mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-05 13:10:24 +00:00
docs: document subgraph limitations with autogrow and matchtype (#8709)
## Summary Document why autogrow and matchtype don't work inside subgraphs, covering root cause, symptoms, workarounds, and historical context. ## Changes - **What**: Add `src/core/graph/subgraph-dynamic-input-limitations.md` explaining the static-vs-dynamic impedance mismatch between subgraph slots (fixed type at creation) and matchtype/autogrow (runtime mutations). Includes Mermaid diagrams, workarounds, and PR history. Link added to `src/lib/litegraph/AGENTS.md` for discoverability. ## Review Focus - Accuracy of the technical explanation — @AustinMroz authored matchtype/autogrow, @webfiltered authored the subgraph system - Whether the workarounds section is practical and complete - File placement: colocated at `src/core/graph/` next to both `subgraph/` and `widgets/dynamicWidgets.ts` ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-8709-docs-document-subgraph-limitations-with-autogrow-and-matchtype-3006d73d36508134a64ce8c2c49e05f1) by [Unito](https://www.unito.io) --------- Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
52
src/core/graph/subgraph-dynamic-input-limitations.md
Normal file
52
src/core/graph/subgraph-dynamic-input-limitations.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# Subgraph Limitations: Dynamic Inputs (MatchType / Autogrow)
|
||||
|
||||
MatchType and autogrow do not work inside subgraphs. Subgraph boundary slots freeze their type at connection time — whatever type exists at that moment is permanently captured as a fixed string. There is no runtime type resolution or reactivity across the boundary: matchtype mutations and autogrow slot additions on internal nodes are never propagated to the `SubgraphNode`.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph Parent Graph
|
||||
SN[SubgraphNode]
|
||||
end
|
||||
subgraph Inside Subgraph
|
||||
SIN[SubgraphInputNode]
|
||||
N[Node with matchtype/autogrow]
|
||||
end
|
||||
|
||||
SN -- "mirrors slots on\nconfigure & input-added" --> SIN
|
||||
SIN -- "type frozen as string\non addInput()" --> N
|
||||
N -. "runtime type changes\nNOT propagated" .-> SIN
|
||||
SIN -. "no type update path" .-> SN
|
||||
|
||||
classDef static fill:#1a1a2e,stroke:#e94560,color:#eee
|
||||
classDef dynamic fill:#1a1a2e,stroke:#0f3460,color:#eee
|
||||
class SN,SIN static
|
||||
class N dynamic
|
||||
```
|
||||
|
||||
## MatchType
|
||||
|
||||
`SubgraphInputNode.connectByType` captures the type as a fixed string via `subgraph.addInput(name, String(type))`. `SubgraphNode` mirrors each new input via the `input-added` event, copying the type at that moment.
|
||||
|
||||
The subgraph boundary slot type is frozen at connection time with no subsequent reactivity. If the first connection carries a specific type (e.g., `IMAGE`), the slot is correctly typed and incompatible connections are properly blocked on the `SubgraphNode`. However, if the first connection carries `*` (any type) — for example from a switch node — the slot is permanently set to `*`, accepting any connection regardless of the internal node's actual type requirements.
|
||||
|
||||
## Autogrow
|
||||
|
||||
Autogrow hooks `onConnectionsChange` and splices new inputs into the node's `inputs` array when the last slot is connected. These inputs are added to the **internal node**, not to the subgraph's input/output definitions. `SubgraphNode` only listens for events on the subgraph definition — there is no bridge.
|
||||
|
||||
Open UX questions (from the autogrow author):
|
||||
|
||||
- Should promoting an autogrow connection cause the `SubgraphNode` to autogrow from that slot?
|
||||
- How to distinguish "promote this specific input" vs "promote the autogrow behavior"?
|
||||
|
||||
## Workarounds
|
||||
|
||||
- Use explicitly typed subgraph inputs instead of relying on matchtype at the boundary.
|
||||
- Move matchtype/autogrow nodes outside the subgraph; pass stable typed values in.
|
||||
|
||||
## References
|
||||
|
||||
- `src/core/graph/widgets/dynamicWidgets.ts` — `applyMatchType`, `applyAutogrow`
|
||||
- `src/lib/litegraph/src/subgraph/SubgraphInputNode.ts` — `connectByType`
|
||||
- `src/lib/litegraph/src/subgraph/SubgraphNode.ts` — `input-added` event listener
|
||||
- [#8352](https://github.com/Comfy-Org/ComfyUI_frontend/pull/8352) (closed) — attempted fix, unresolved edge cases
|
||||
- [#7837](https://github.com/Comfy-Org/ComfyUI_frontend/pull/7837) (merged) — partial fix only
|
||||
@@ -28,6 +28,10 @@ import { LGraph } from '@/lib/litegraph/src/LGraph'
|
||||
|
||||
**Root cause**: `LGraph` ↔ `Subgraph` circular dependency (Subgraph extends LGraph, LGraph creates Subgraph instances).
|
||||
|
||||
## Known Limitations
|
||||
|
||||
- Subgraph dynamic input limitations (autogrow/matchtype): see [`src/core/graph/subgraph-dynamic-input-limitations.md`](../../core/graph/subgraph-dynamic-input-limitations.md)
|
||||
|
||||
## Test Helpers
|
||||
|
||||
```typescript
|
||||
|
||||
Reference in New Issue
Block a user