Movie Editor: emit widget defaults, wireable STRING/forceInput sockets
- builder now emits a value for EVERY widget input (type-appropriate empty when no default is declared), matching ComfyUI's frontend. Fixes generation refusing to start on required widgets with no default (e.g. ImageTransform's 'bboxes', refinement key fields) — they were dropped from the graph and ComfyUI rejected the prompt for a missing required input. Empty required widgets are now a warning, not a blocking error, in the Models modal. - connection_inputs + ports_from_input_types now include forceInput STRING sockets, so refinement_key_input on Studio and the Chain Sampler is visible and can be wired manually (was invisible because STRING is a widget type). Lets a custom STRING source override the default keyloader wire. - Refinement key stays optional: the keyloader defaults to the keyless 'none' key. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
d4c1f7f72e
commit
c0dff7893d
@@ -92,6 +92,8 @@ CORE_PRODUCERS: list[tuple[str, int, str]] = [ # (core_id, output_index, type)
|
||||
]
|
||||
|
||||
CONTROL_VALUES = {"fixed", "randomize", "increment", "decrement"}
|
||||
# Type-appropriate empty values for widgets that declare no default.
|
||||
_WIDGET_EMPTY = {"STRING": "", "INT": 0, "FLOAT": 0.0, "BOOLEAN": False}
|
||||
_VHS_NON_INPUT = {"videopreview"}
|
||||
|
||||
|
||||
@@ -156,9 +158,15 @@ def _widget_defaults(node_def: Optional[dict]) -> dict:
|
||||
continue
|
||||
if isinstance(t, list):
|
||||
out[name] = opts.get("default", t[0] if t else None)
|
||||
elif t == "COMBO":
|
||||
choices = opts.get("options") or []
|
||||
out[name] = opts.get("default", choices[0] if choices else "")
|
||||
elif t in WIDGET_PRIMITIVES:
|
||||
if "default" in opts:
|
||||
out[name] = opts["default"]
|
||||
# Always emit a value for every widget — ComfyUI's frontend does, and a
|
||||
# required widget with no declared default (e.g. ImageTransform's bboxes)
|
||||
# otherwise goes missing and ComfyUI rejects the prompt. Fall back to a
|
||||
# type-appropriate empty so generation isn't blocked.
|
||||
out[name] = opts.get("default", _WIDGET_EMPTY.get(t, ""))
|
||||
return out
|
||||
|
||||
|
||||
|
||||
@@ -113,9 +113,14 @@ def connection_inputs(node_def: dict) -> list[dict]:
|
||||
if not isinstance(spec, list) or not spec:
|
||||
continue
|
||||
t = spec[0]
|
||||
if not isinstance(t, str) or t in _WIDGET_TYPES:
|
||||
if not isinstance(t, str):
|
||||
continue
|
||||
opts = spec[1] if len(spec) > 1 and isinstance(spec[1], dict) else {}
|
||||
# A widget-typed input is a SOCKET (wireable) only when forceInput is set —
|
||||
# e.g. refinement_key_input is ("STRING", {"forceInput": True}). Plain widgets
|
||||
# are handled by widget_inputs, not here.
|
||||
if t in _WIDGET_TYPES and not opts.get("forceInput"):
|
||||
continue
|
||||
# V3 nodes can mark a required-group input as optional via the flag.
|
||||
is_required = group == "required" and not opts.get("optional", False)
|
||||
out.append({"name": name, "type": _normalize_type(t), "required": is_required})
|
||||
@@ -254,9 +259,15 @@ def ports_from_input_types(label: str, node_key: str, input_types: dict) -> list
|
||||
if not isinstance(spec, (list, tuple)) or not spec:
|
||||
continue
|
||||
t = spec[0]
|
||||
if isinstance(t, str) and t not in WIDGET_PRIMITIVES:
|
||||
ports.append({"id": f"{node_key}.{name}", "node": label, "input": name,
|
||||
"type": t, "label": f"{label} · {name}"})
|
||||
if not isinstance(t, str):
|
||||
continue
|
||||
opts = spec[1] if len(spec) > 1 and isinstance(spec[1], dict) else {}
|
||||
# Expose typed sockets, plus forceInput widget sockets (e.g. the STRING
|
||||
# refinement_key_input on Studio/Sampler) so they can be wired manually.
|
||||
if t in WIDGET_PRIMITIVES and not opts.get("forceInput"):
|
||||
continue
|
||||
ports.append({"id": f"{node_key}.{name}", "node": label, "input": name,
|
||||
"type": t, "label": f"{label} · {name}"})
|
||||
return ports
|
||||
|
||||
|
||||
|
||||
@@ -124,7 +124,9 @@
|
||||
if (w.kind === "combo" && (!w.choices || !w.choices.length)) {
|
||||
issues.push({ level: "error", msg: `"${w.name}" has no installed options to pick from.` });
|
||||
} else if (v == null || v === "") {
|
||||
issues.push({ level: "error", msg: `Required field "${w.name}" is empty.` });
|
||||
// Not blocking: the builder emits a type-appropriate empty for any widget left
|
||||
// blank (matching ComfyUI's frontend), so an empty field won't stall generation.
|
||||
issues.push({ level: "warn", msg: `"${w.name}" is empty — using its default.` });
|
||||
}
|
||||
});
|
||||
const outs = spec.outputs || [];
|
||||
|
||||
Reference in New Issue
Block a user