From 360f185abf0c7f2758598c5d6ca156ebc978a4a6 Mon Sep 17 00:00:00 2001 From: Jedrzej Kosinski Date: Tue, 2 Dec 2025 16:23:58 -0800 Subject: [PATCH] Initial exploration of combo issues --- comfy_api/latest/_io.py | 14 ++++++++++++++ comfy_execution/validation.py | 4 ++++ comfy_extras/nodes_logic.py | 16 ++++++++++++++++ nodes.py | 2 +- 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/comfy_api/latest/_io.py b/comfy_api/latest/_io.py index 3e52fdc2d..41ab974ff 100644 --- a/comfy_api/latest/_io.py +++ b/comfy_api/latest/_io.py @@ -238,6 +238,11 @@ class ComfyTypeI(_ComfyType): class Input(Input): ... +class ComfyTypeO(_ComfyType): + '''ComfyType subclass that only has a default Output class - intended for types that only have Outputs.''' + class Output(Output): + ... + class ComfyTypeIO(ComfyTypeI): '''ComfyType subclass that has default Input and Output classes; useful for types with both Inputs and Outputs.''' class Output(Output): @@ -338,6 +343,14 @@ class String(ComfyTypeIO): "dynamicPrompts": self.dynamic_prompts, }) +@comfytype(io_type="COMBO_OPTION") +class ComboOption(ComfyTypeO): + Type = str + class Output(Output): + @property + def io_type(self): + return [self.Parent.io_type, self.Parent.io_type] + @comfytype(io_type="COMBO") class Combo(ComfyTypeIO): Type = str @@ -1846,6 +1859,7 @@ __all__ = [ "Int", "Float", "String", + "ComboOption", "Combo", "MultiCombo", "Image", diff --git a/comfy_execution/validation.py b/comfy_execution/validation.py index 24c0b4ed7..c426614e8 100644 --- a/comfy_execution/validation.py +++ b/comfy_execution/validation.py @@ -29,6 +29,10 @@ def validate_node_input( if received_type == IO.MatchType.io_type or input_type == IO.MatchType.io_type: return True + if isinstance(received_type, list) and IO.ComboOption.io_type in received_type: + if input_type == IO.Combo.io_type or isinstance(input_type, list): + return True + # Not equal, and not strings if not isinstance(received_type, str) or not isinstance(input_type, str): return False diff --git a/comfy_extras/nodes_logic.py b/comfy_extras/nodes_logic.py index 95a6ba788..eaf2156cc 100644 --- a/comfy_extras/nodes_logic.py +++ b/comfy_extras/nodes_logic.py @@ -141,6 +141,21 @@ class AutogrowPrefixTestNode(io.ComfyNode): combined = ",".join([str(x) for x in vals]) return io.NodeOutput(combined) +class ComboOptionTestNode(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"])], + outputs=[_io.ComboOption.Output()], + ) + + @classmethod + def execute(cls, combo: io.Combo.Type) -> io.NodeOutput: + return io.NodeOutput(combo) + class LogicExtension(ComfyExtension): @override async def get_node_list(self) -> list[type[io.ComfyNode]]: @@ -149,6 +164,7 @@ class LogicExtension(ComfyExtension): # DCTestNode, # AutogrowNamesTestNode, # AutogrowPrefixTestNode, + ComboOptionTestNode, ] async def comfy_entrypoint() -> LogicExtension: diff --git a/nodes.py b/nodes.py index 498401a43..e9e62f708 100644 --- a/nodes.py +++ b/nodes.py @@ -1820,7 +1820,7 @@ class ImageScaleBy: @classmethod def INPUT_TYPES(s): - return {"required": { "image": ("IMAGE",), "upscale_method": (s.upscale_methods,), + return {"required": { "image": ("IMAGE",), "upscale_method": ("COMBO", {"options": s.upscale_methods,}), "scale_by": ("FLOAT", {"default": 1.0, "min": 0.01, "max": 8.0, "step": 0.01}),}} RETURN_TYPES = ("IMAGE",) FUNCTION = "upscale"