Skip to main content

comfyui-node-inputs

ComfyUI node input types - INT, FLOAT, STRING, BOOLEAN, COMBO widgets, hidden inputs, optional inputs, lazy inputs, force_input. Use when configuring node inputs, adding widgets, or customizing input behavior.

소스 정보

저장소
jtydhr88/comfyui-custom-node-skills
최근 소스 활동
2026년 10월 17일 01:09
감지된 SKILL.md 언어
영어
스타
298
포크
28

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
comfyui-node-inputs
description
ComfyUI node input types - INT, FLOAT, STRING, BOOLEAN, COMBO widgets, hidden inputs, optional inputs, lazy inputs, force_input. Use when configuring node inputs, adding widgets, or customizing input behavior.
# ComfyUI Node Inputs Inputs define what data a node accepts. Widget inputs create UI controls; connection inputs create socket slots. ## Widget Input Types ### INT ```python io.Int.Input("seed", default=0, min=0, max=0xffffffffffffffff, step=1, control_after_generate=True, # adds increment/decrement/randomize control display_mode=io.NumberDisplay.number, # "number", "slider", or "gradient_slider" tooltip="Random seed for generation", ) ``` **NumberDisplay options**: `io.NumberDisplay.number`, `io.NumberDisplay.slider`, `io.NumberDisplay.gradient_slider` **ControlAfterGenerate options**: `True` (default randomize), or `io.ControlAfterGenerate.fixed`, `.increment`, `.decrement`, `.randomize`. A mode value is treated as the control's *starting mode* only from frontend v1.57.0 (#19867); older frontends used the string as the control widget's name. ### FLOAT ```python io.Float.Input("strength", default=1.0, min=0.0, max=10.0, step=0.01, round=0.001, # rounding precision display_mode=io.NumberDisplay.slider, gradient_stops=[{"offset": 0.0, "color": [0, 0, 0]}, {"offset": 1.0, "color": [255, 255, 255]}], # for gradient_slider mode tooltip="Effect strength", ) ``` ### STRING ```python # Single-line string io.String.Input("name", default="", placeholder="Enter name...", ) # Multi-line text area io.String.Input("prompt", multiline=True, default="", placeholder="Enter prompt...", dynamic_prompts=True, # enable dynamic prompt syntax ) ``` ### BOOLEAN ```python io.Boolean.Input("enabled", default=True, label_on="Enabled", label_off="Disabled", tooltip="Toggle this feature", ) ``` ### COMBO (Dropdown) ```python io.Combo.Input("mode", options=["option_a", "option_b", "option_c"], default="option_a", tooltip="Select processing mode", control_after_generate=True, # adds increment/decrement/randomize control ) ``` **Combo with Enum**: ```python from enum import Enum class BlendMode(Enum): NORMAL = "normal" MULTIPLY = "multiply" SCREEN = "screen" io.Combo.Input("blend", options=BlendMode, default=BlendMode.NORMAL) # Enum values auto-converted to string list ``` **Combo with file upload**: ```python io.Combo.Input("image_file", options=[], upload=io.UploadType.image, # .image, .audio, .video, .model (for generic file upload) image_folder=io.FolderType.input, # .input, .output, .temp ) ``` **Dynamic combo with remote options**: ```python io.Combo.Input("model_name", options=[], remote=io.RemoteOptions( route="/internal/models/checkpoints", refresh_button=True, control_after_refresh="first", # "first" or "last" timeout=5000, # ms max_retries=3, refresh=60000, # TTL refresh interval in ms ), ) ``` **Security**: treat combo / `DynamicCombo` values as untrusted when they reach the filesystem. Re-validate any value used as a file/folder name, path, format or extension at the load/save boundary (`folder_paths.get_full_path_or_raise(...)`, `folder_paths.is_within_directory(base, path)`, or a fixed allowlist) — prompts can be submitted via the API with values outside `options`. ### MULTICOMBO (Multi-select Dropdown) ```python io.MultiCombo.Input("tags", options=["tag1", "tag2", "tag3", "tag4"], default=["tag1"], placeholder="Select tags...", chip=True, # display as chips ) # Value type: list[str] ``` ### COLOR (Color Picker) ```python io.Color.Input("color", default="#ffffff", socketless=True, # widget only by default ) # Value type: str (hex color) ``` ### COLORS (Color Palette) ```python io.Colors.Input("palette", default=["#ff0000", "#00ff00"], socketless=True, ) # Value type: list[str] (hex colors) ``` ### BOUNDING_BOX (Rectangle Selector) ```python io.BoundingBox.Input("region", default={"x": 0, "y": 0, "width": 512, "height": 512}, socketless=True, component="my_component", # optional custom UI component name force_input=False, ) # Value type: {"x": int, "y": int, "width": int, "height": int} ``` ### BOUNDING_BOXES (Multiple Regions) ```python io.BoundingBoxes.Input("regions", default=[], socketless=True, ) # Value type: list of {"x": int, "y": int, "width": int, "height": int, "metadata": dict} ``` ### CURVE (Spline Editor) ```python io.Curve.Input("curve", default=[(0.0, 0.0), (1.0, 1.0)], # linear ramp socketless=True, ) # Value type: raw curve data; normalize with CurveInput.from_raw(value) # (from comfy_api.input import CurveInput) ``` ### RANGE (Levels/Range Editor) ```python io.Range.Input("levels", default={"min": 0.0, "max": 1.0}, gradient_stops=None, # gradient background for the slider show_midpoint=True, # gamma midpoint handle value_min=0.0, value_max=1.0, ) # Value type: raw dict; normalize with RangeInput.from_raw(value) # (from comfy_api.input import RangeInput) -> .min_val, .max_val, .midpoint, .to_lut() ``` ### WEBCAM (Camera Capture) ```python io.Webcam.Input("capture") # Value type: str ``` ### IMAGECOMPARE (Comparison Widget) ```python io.ImageCompare.Input("comparison", socketless=True) # Value type: dict ``` ### Newer editor widgets (v0.31–v0.40, need a matching frontend) ```python io.VideoEdit.Input("trim", features=["trim"]) # "trim" and/or "crop" (default both) # Value: {"trim": {"start_time": float, "duration": float}, "crop": {"x","y","width","height"}} # apply with video.as_trimmed(...) / video.as_cropped(...); zero width/height = full frame io.ResolutionPreview.Input("preview", # live preview of a computed size; optional by default ratio_widget="aspect_ratio", megapixels_widget="megapixels", multiple_widget="multiple") io.Compositor.Input("compositor") # layer-editor state dict (pairs with io.Layers) io.CameraInfoState.Input("camera_info_state", optional=True) # camera editor state dict ``` ## Input Options (Common to All) ```python io.Image.Input("image", optional=True, # not required; creates optional input socket tooltip="Description shown on hover", lazy=True, # lazy evaluation - only computed when needed advanced=True, # hidden by default in compact mode raw_link=True, # receive raw link reference instead of value ) ``` ### force_input Forces a widget input to appear as a connection socket instead of a widget: ```python io.Float.Input("value", default=1.0, force_input=True, # shows as socket, not slider ) ``` ### socketless Makes a widget input appear only as a widget with no input socket: ```python io.String.Input("note", default="", socketless=True, # widget only, no connection socket ) ``` ## Optional Inputs ```python class MyNode(io.ComfyNode): @classmethod def define_schema(cls): return io.Schema( node_id="MyNode", display_name="My Node", category="example", inputs=[ io.Image.Input("image"), # required io.Mask.Input("mask", optional=True), # optional io.Float.Input("blend", default=0.5), # has default widget ], outputs=[io.Image.Output("IMAGE")], ) @classmethod def execute(cls, image, mask=None, blend=0.5): # Optional inputs default to None when not connected if mask is not None: image = image * (1 - blend) + image * mask.unsqueeze(-1) * blend return io.NodeOutput(image) ``` ## Hidden Inputs Hidden inputs receive server-provided values, not user input: ```python class MyNode(io.ComfyNode): @classmethod def define_schema(cls): return io.Schema( node_id="MyNode", display_name="My Node", category="example", inputs=[io.String.Input("text")], outputs=[io.String.Output()], hidden=[ io.Hidden.unique_id, # node's unique ID io.Hidden.prompt, # full prompt data io.Hidden.extra_pnginfo, # PNG metadata dict io.Hidden.dynprompt, # dynamic prompt object io.Hidden.auth_token_comfy_org, # auth token io.Hidden.api_key_comfy_org, # API key io.Hidden.comfy_usage_source, # prompt source, e.g. "comfyui-frontend" # io.Hidden.execution_list exists (v0.36+) but is core-internal and # slated for removal - DO NOT USE ], ) @classmethod def execute(cls, text): # Access hidden values via cls.hidden node_id = cls.hidden.unique_id prompt = cls.hidden.prompt extra = cls.hidden.extra_pnginfo return io.NodeOutput(f"{text} (node: {node_id})") ``` ## Lazy Evaluation Lazy inputs are only evaluated when actually needed, saving computation: ```python class ConditionalNode(io.ComfyNode): @classmethod def define_schema(cls): return io.Schema( node_id="ConditionalNode", display_name="Conditional", category="logic", inputs=[ io.Boolean.Input("condition"), io.Image.Input("if_true", lazy=True), io.Image.Input("if_false", lazy=True), ], outputs=[io.Image.Output("IMAGE")], ) @classmethod def check_lazy_status(cls, condition, if_true=None, if_false=None): """Return list of input names that need evaluation.""" if condition and if_true is None: return ["if_true"] if not condition and if_false is None: return ["if_false"] return [] @classmethod def execute(cls, condition, if_true, if_false): return io.NodeOutput(if_true if condition else if_false) ``` **Rules for lazy evaluation**: - Mark inputs with `lazy=True` - Implement `check_lazy_status()` classmethod - Unevaluated inputs are `None`; a disconnected *optional* lazy input is absent from kwargs — use a sentinel default (`MISSING = object()`) to distinguish (see the Switch pattern in `comfyui-node-advanced`) - Return list of input names that need computing, or empty list - Method may be called multiple times - Lazy sub-inputs of Autogrow/DynamicCombo arrive as `(value, key)` tuples here (see `comfyui-node-advanced`) **Input tolerance** (core policy): don't reject values just because they exceed recommended/UI limits or may give poor results; adapt (clamp/pad/resize) only when the operation would otherwise fail. Security checks (path containment) still apply. ## V1 Input Format (Legacy Reference) ```python @classmethod def INPUT_TYPES(s): return { "required": { "image": ("IMAGE",), "strength": ("FLOAT", {
GitHub에서 보기
이 SKILL.md는 매우 커서 SkillsMP가 여기에는 첫 섹션만 미리 보여줍니다. GitHub에서 보기