mirror of
https://github.com/Comfy-Org/ComfyUI.git
synced 2026-08-25 18:32:35 +08:00
DynamicSlot: typed option dispatch driven by TypeResolver
Replaces the old connected/unconnected fixed-child DynamicSlot with a type-keyed option list. Each Option declares a 'when' condition (None, io.AnyType, a single ComfyType, a list, or a MultiType.Input) and the child inputs revealed when that condition matches the slot's resolved upstream type. Selection happens at schema-finalization time using live_input_types computed by TypeResolver, so API-only workflows (no frontend) get the same expansion the UI would. - _io.py: redesign DynamicSlot.Input / Option; auto-derive slotType as the union of all non-None when sets; expose it via as_dict so the frontend knows what types are accepted; the class io_type stays COMFY_DYNAMICSLOT_V3 as the parse-time dispatch tag. - type_resolver.py: return the auto-derived _slot_io_type for DynamicSlot.Input; document the AnyType (*) limitation. - execution.py: validate links into a DynamicSlot against slotType, not the dispatch tag COMFY_DYNAMICSLOT_V3. - tests: new test_dynamic_slot.py + regression coverage in test_type_resolver.py. Amp-Thread-ID: https://ampcode.com/threads/T-019e8568-f382-743d-a97f-0de3ff29d501 Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
@@ -358,6 +358,35 @@ def test_effective_slot_type_on_v3_plain_input(fake_nodes_module, TypeResolver):
|
||||
assert r.compute_live_input_types("n") == {"flag": "BOOLEAN"}
|
||||
|
||||
|
||||
def test_effective_slot_type_peels_dynamic_slot(fake_nodes_module, TypeResolver):
|
||||
"""A DynamicSlot input reports its auto-derived slotType (union of `when` types)."""
|
||||
from comfy_api.latest import _io as io
|
||||
|
||||
class DSNode(io.ComfyNode):
|
||||
@classmethod
|
||||
def define_schema(cls):
|
||||
return io.Schema(
|
||||
node_id="DSNode",
|
||||
inputs=[
|
||||
io.DynamicSlot.Input("slot", options=[
|
||||
io.DynamicSlot.Option(when=io.Image, inputs=[]),
|
||||
io.DynamicSlot.Option(when=io.Latent, inputs=[]),
|
||||
]),
|
||||
],
|
||||
outputs=[io.String.Output()],
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def execute(cls, **kwargs):
|
||||
return io.NodeOutput("")
|
||||
|
||||
DSNode.GET_SCHEMA()
|
||||
fake_nodes_module["DSNode"] = DSNode
|
||||
prompt = {"n": {"class_type": "DSNode", "inputs": {}}}
|
||||
r = TypeResolver(prompt)
|
||||
assert r.get_declared_slot_io_type("n", "slot") == "IMAGE,LATENT"
|
||||
|
||||
|
||||
def test_compute_live_input_types_mixes_links_and_literals(fake_nodes_module, TypeResolver):
|
||||
fake_nodes_module["Src"] = _v1_node(("MODEL",))
|
||||
fake_nodes_module["Sink"] = _v1_node(
|
||||
|
||||
Reference in New Issue
Block a user