Support Combo outputs in a more sane way

This commit is contained in:
Jedrzej Kosinski 2025-12-02 23:51:26 -08:00
parent 861817d22d
commit 5ede17309a
4 changed files with 33 additions and 4 deletions

View File

@ -387,10 +387,6 @@ class Combo(ComfyTypeIO):
super().__init__(id, display_name, tooltip, is_output_list)
self.options = options if options is not None else []
@property
def io_type(self):
return self.options
@comfytype(io_type="COMBO")
class MultiCombo(ComfyTypeI):
'''Multiselect Combo input (dropdown for selecting potentially more than one value).'''

View File

@ -6,6 +6,7 @@ import asyncio
import inspect
from comfy_execution.graph_utils import is_link, ExecutionBlocker
from comfy.comfy_types.node_typing import ComfyNodeABC, InputTypeDict, InputTypeOptions
from comfy_api.latest import IO
# NOTE: ExecutionBlocker code got moved to graph_utils.py to prevent torch being imported too soon during unit tests
ExecutionBlocker = ExecutionBlocker
@ -97,6 +98,10 @@ def get_input_info(
extra_info = input_info[1]
else:
extra_info = {}
# if input_type is a list, it is a Combo defined in outdated format; convert it
if isinstance(input_type, list):
extra_info["options"] = input_type
input_type = IO.Combo.io_type
return input_type, input_category, extra_info
class TopologicalSort:

View File

@ -29,6 +29,11 @@ def validate_node_input(
if received_type == IO.MatchType.io_type or input_type == IO.MatchType.io_type:
return True
# This accounts for some custom nodes that output lists of options as the type;
# if we ever want to break them on purpose, this can be removed
if isinstance(received_type, list) and input_type == IO.Combo.io_type:
return True
# Not equal, and not strings
if not isinstance(received_type, str) or not isinstance(input_type, str):
return False

View File

@ -141,6 +141,28 @@ class AutogrowPrefixTestNode(io.ComfyNode):
combined = ",".join([str(x) for x in vals])
return io.NodeOutput(combined)
class ComboOutputTestNode(io.ComfyNode):
@classmethod
def define_schema(cls):
return io.Schema(
node_id="ComboOptionTestNode",
display_name="ComboOptionTest",
category="logic",
inputs=[io.Combo.Input("combo", options=["option1", "option2", "option3"]),
io.Combo.Input("combo2", options=["option4", "option5", "option6"])],
outputs=[io.Combo.Output(), io.Combo.Output()],
)
@classmethod
def validate_inputs(cls, combo: io.Combo.Type) -> bool:
if combo not in ["option1", "option2", "option3"]:
return "Invalid combo: {}".format(combo)
return True
@classmethod
def execute(cls, combo: io.Combo.Type, combo2: io.Combo.Type) -> io.NodeOutput:
return io.NodeOutput(combo, combo2)
class LogicExtension(ComfyExtension):
@override
async def get_node_list(self) -> list[type[io.ComfyNode]]:
@ -149,6 +171,7 @@ class LogicExtension(ComfyExtension):
# DCTestNode,
# AutogrowNamesTestNode,
# AutogrowPrefixTestNode,
ComboOutputTestNode,
]
async def comfy_entrypoint() -> LogicExtension: