Expose long-text fields as input sockets (forceInput)

axes, reference_description, system_prompt, user_prompt now render as INPUT
SOCKETS (forceInput) so they can be wired from other nodes — e.g. describe's
canonical output -> compare's reference_description, or a text node -> chat
prompts. Small config (report_dir, run_tag, model_path, ...) stays as typeable
fields. Unconnected sockets fall back to sensible defaults; the agent/bridge can
still set them by value via the API. Dropped the now-socket fields from the
example workflows; bumped their max_new_tokens to 2048.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-27 10:49:37 +02:00
parent 0e9e99b8b2
commit fee136e98c
4 changed files with 19 additions and 21 deletions
+4 -3
View File
@@ -37,14 +37,15 @@ can act on it.
| `model_select` | dropdown (model name) | 4B local | **which judge** (transformers/safetensors, auto-downloaded): Qwen3-VL 4B/8B/30B-A3B, **Qwen3.5-9B**, **Qwen3.6-27B/35B-A3B** (newer, natively multimodal). Param size shown in the label | | `model_select` | dropdown (model name) | 4B local | **which judge** (transformers/safetensors, auto-downloaded): Qwen3-VL 4B/8B/30B-A3B, **Qwen3.5-9B**, **Qwen3.6-27B/35B-A3B** (newer, natively multimodal). Param size shown in the label |
| `precision` | bf16 / fp8 / nf4 | bf16 | **the quant** — applies to the selected model (VRAM table below) | | `precision` | bf16 / fp8 / nf4 | bf16 | **the quant** — applies to the selected model (VRAM table below) |
| `model_path` | STRING | "" (empty) | **manual override** of the dropdown — local dir, HF repo id, or alias (`8b`/`30b-a3b`/`3.5-9b`/`3.6-27b`/`3.6-35b`). Empty = use `model_select` | | `model_path` | STRING | "" (empty) | **manual override** of the dropdown — local dir, HF repo id, or alias (`8b`/`30b-a3b`/`3.5-9b`/`3.6-27b`/`3.6-35b`). Empty = use `model_select` |
| `axes` | STRING | "" (empty) | **override** the profile's axis set with a custom comma/newline list; empty = use `profile` | | `axes` | STRING **input** | — | (socket) optional override of the profile's axis set; wire a text node or leave unconnected to use `profile` |
| `max_new_tokens` | INT | 2048 | raise it if a reasoning model (Qwen3.5/3.6) gets cut off before finishing | | `max_new_tokens` | INT | 2048 | raise it if a reasoning model (Qwen3.5/3.6) gets cut off before finishing |
| `temperature` | FLOAT | 0.0 | 0 = greedy/repeatable | | `temperature` | FLOAT | 0.0 | 0 = greedy/repeatable |
| `swap_eval` | BOOL | true | run twice with images swapped, average → cuts position bias | | `swap_eval` | BOOL | true | run twice with images swapped, average → cuts position bias |
| `keep_loaded` | BOOL | true | cache weights across loop iterations | | `keep_loaded` | BOOL | true | cache weights across loop iterations |
| `auto_download` | BOOL | true | if `model_path` is a repo id/alias and not local, fetch it from HF into `models/prompt_generator/` | | `auto_download` | BOOL | true | if `model_path` is a repo id/alias and not local, fetch it from HF into `models/prompt_generator/` |
| `system_prompt` | STRING | "" | **chat mode**: your system prompt | | `system_prompt` | STRING **input** | — | (socket) chat mode: wire your system prompt from a text node |
| `user_prompt` | STRING | "Describe this image." | **chat mode**: your instruction over the image(s) | | `user_prompt` | STRING **input** | — | (socket) chat mode: wire your instruction from a text node |
| `reference_description` | STRING **input** | — | (socket) compare: wire describe's canonical output here to anchor the reference |
**Auto-download:** set `model_path` to `30b-a3b` (alias) or any `org/name` repo id and leave **Auto-download:** set `model_path` to `30b-a3b` (alias) or any `org/name` repo id and leave
`auto_download` on — the node snapshot-downloads it on first run (into ComfyUI's `auto_download` on — the node snapshot-downloads it on first run (into ComfyUI's
+12 -12
View File
@@ -795,34 +795,34 @@ class QwenVLImageJudge:
{"default": list(MODEL_PRESETS.keys())[0]}), {"default": list(MODEL_PRESETS.keys())[0]}),
"model_path": ("STRING", {"default": ""}), # manual override (local dir / HF repo / alias) "model_path": ("STRING", {"default": ""}), # manual override (local dir / HF repo / alias)
"precision": (["bf16", "fp8", "nf4"], {"default": "bf16"}), "precision": (["bf16", "fp8", "nf4"], {"default": "bf16"}),
"axes": ("STRING", {"default": "", "multiline": True}),
"max_new_tokens": ("INT", {"default": 2048, "min": 64, "max": 8192}), "max_new_tokens": ("INT", {"default": 2048, "min": 64, "max": 8192}),
"temperature": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.5, "step": 0.05}), "temperature": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.5, "step": 0.05}),
"swap_eval": ("BOOLEAN", {"default": True}), "swap_eval": ("BOOLEAN", {"default": True}),
"keep_loaded": ("BOOLEAN", {"default": True}), "keep_loaded": ("BOOLEAN", {"default": True}),
"auto_download": ("BOOLEAN", {"default": True}), "auto_download": ("BOOLEAN", {"default": True}),
# The agent reads the analysis from these files after each queue. # Small config values stay as typeable fields.
"report_dir": ("STRING", {"default": ""}), "report_dir": ("STRING", {"default": ""}),
"run_tag": ("STRING", {"default": ""}), "run_tag": ("STRING", {"default": ""}),
# compare: canonical reference text (from describe). When set, compare
# anchors on it instead of re-reading the reference image each time.
"reference_description": ("STRING", {"default": "", "multiline": True}),
# chat mode: use the node as a general VLM with your own prompts.
"system_prompt": ("STRING", {"default": "", "multiline": True}),
"user_prompt": ("STRING", {"default": "Describe this image.", "multiline": True}),
}, },
# Only genuine node-to-node wires stay optional (widgets in `optional` render # Long text content is exposed as INPUT SOCKETS (forceInput) so it can be wired
# as input sockets instead of editable fields in some ComfyUI frontends). # from other nodes — e.g. describe's canonical output -> reference_description, a
# text node -> system_prompt/user_prompt. Left unconnected, sensible defaults apply
# (empty axes -> profile; empty reference_description -> two-image compare). The
# agent/bridge can still set them by value via the API.
"optional": { "optional": {
"generated_image": ("IMAGE",), # required for compare, ignored for describe/chat "generated_image": ("IMAGE",), # required for compare, ignored for describe/chat
"axes": ("STRING", {"forceInput": True}),
"reference_description": ("STRING", {"forceInput": True}),
"system_prompt": ("STRING", {"forceInput": True}),
"user_prompt": ("STRING", {"forceInput": True}),
}, },
} }
def judge(self, reference_image, mode, model_path, precision, axes, def judge(self, reference_image, mode, model_path, precision,
max_new_tokens, temperature, swap_eval, profile="general", max_new_tokens, temperature, swap_eval, profile="general",
model_select=MANUAL_CHOICE, generated_image=None, model_select=MANUAL_CHOICE, generated_image=None,
keep_loaded=True, auto_download=True, keep_loaded=True, auto_download=True,
report_dir="", run_tag="", reference_description="", report_dir="", run_tag="", axes="", reference_description="",
system_prompt="", user_prompt="Describe this image."): system_prompt="", user_prompt="Describe this image."):
# `axes` overrides the profile when provided; otherwise use the profile's axis set. # `axes` overrides the profile when provided; otherwise use the profile's axis set.
axis_list = [a.strip() for a in re.split(r"[,\n]", axes) if a.strip()] axis_list = [a.strip() for a in re.split(r"[,\n]", axes) if a.strip()]
+2 -4
View File
@@ -68,15 +68,13 @@
"model_path": "/media/p5/qwen3vl_4b_abliterated_comfy_convert/hf_bf16", "model_path": "/media/p5/qwen3vl_4b_abliterated_comfy_convert/hf_bf16",
"precision": "bf16", "precision": "bf16",
"profile": "general", "profile": "general",
"axes": "", "max_new_tokens": 2048,
"max_new_tokens": 512,
"temperature": 0.0, "temperature": 0.0,
"swap_eval": true, "swap_eval": true,
"keep_loaded": true, "keep_loaded": true,
"auto_download": true, "auto_download": true,
"report_dir": "/media/p5/Comfyui/output/calibrator", "report_dir": "/media/p5/Comfyui/output/calibrator",
"run_tag": "", "run_tag": ""
"reference_description": ""
}, },
"_meta": { "title": "Qwen3-VL Image Judge (Calibrator)" } "_meta": { "title": "Qwen3-VL Image Judge (Calibrator)" }
} }
+1 -2
View File
@@ -12,8 +12,7 @@
"profile": "general", "profile": "general",
"model_path": "/media/p5/qwen3vl_4b_abliterated_comfy_convert/hf_bf16", "model_path": "/media/p5/qwen3vl_4b_abliterated_comfy_convert/hf_bf16",
"precision": "bf16", "precision": "bf16",
"axes": "", "max_new_tokens": 2048,
"max_new_tokens": 1024,
"temperature": 0.0, "temperature": 0.0,
"swap_eval": false, "swap_eval": false,
"keep_loaded": true, "keep_loaded": true,