comfyui-mcp 0.52.121 → 0.52.122
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/orchestrator/index.js +116 -56
- package/dist/orchestrator/index.js.map +1 -1
- package/dist/orchestrator/panel-mcp-http.js +17 -1
- package/dist/orchestrator/panel-mcp-http.js.map +1 -1
- package/dist/orchestrator/panel-tools.js +197 -17
- package/dist/orchestrator/panel-tools.js.map +1 -1
- package/dist/orchestrator/run-completion-journal.js +196 -1
- package/dist/orchestrator/run-completion-journal.js.map +1 -1
- package/dist/services/process-control.js +8 -2
- package/dist/services/process-control.js.map +1 -1
- package/dist/services/session-scope.js +20 -0
- package/dist/services/session-scope.js.map +1 -1
- package/dist/services/ui-bridge.js +9 -1
- package/dist/services/ui-bridge.js.map +1 -1
- package/dist/services/user-mcp-config.js +27 -0
- package/dist/services/user-mcp-config.js.map +1 -1
- package/docker/runpod/Dockerfile +1 -1
- package/docker/runpod/post_start.sh +39 -1
- package/docker/runpod/starting.html +21 -0
- package/package.json +1 -1
- package/plugin/skills/panel-operations/SKILL.md +376 -0
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@ Works on macOS, Linux, and Windows. Auto-detects your ComfyUI installation and p
|
|
|
29
29
|
|
|
30
30
|
**Stuck or have a question? [Join the Discord](https://discord.gg/cW9arBhzCu)** for help, model tips, and release announcements.
|
|
31
31
|
|
|
32
|
-
**38 MCP tools** | **
|
|
32
|
+
**38 MCP tools** | **42 AI skills** (Flux · WAN · LTX 2.3 video · MiniMax H3 · Qwen · Z-Image · Ideogram 4 · ERNIE · ANIMA · model registry · Civitai · node authoring · launch/perf flags) | **56 installer packs** | **11 slash commands** | **4 autonomous agents** | **3 hooks**
|
|
33
33
|
|
|
34
34
|
The plugin ships skills that grow with every release: model-specific generation guides with curated download URLs, workflow recipes, troubleshooting, and custom-node authoring. With them, Claude knows the right sampler, CFG, resolution, and model files for each architecture without trial and error.
|
|
35
35
|
|
|
@@ -136,7 +136,7 @@ This package also ships as a Claude Code plugin that adds slash commands, skills
|
|
|
136
136
|
|
|
137
137
|
### Built-in skills
|
|
138
138
|
|
|
139
|
-
|
|
139
|
+
42 skills total: model-family guides (Flux, WAN, LTX 2.3, MiniMax H3, Qwen, Z-Image, Ideogram 4, ERNIE, ANIMA + anime / WAN / Z-Image LoRA training), the **model-registry** (curated download URLs), the **civitai** pairing skill, node authoring, the **launch/performance-flags** matrix, and the core four below. Full list on the [plugin docs page](https://comfyui-mcp.artokun.io/docs/plugin).
|
|
140
140
|
|
|
141
141
|
> **Installer packs.** [`packs/`](packs/) bundles 13 one-command ComfyUI setups: ANIMA, Ideogram 4, LTX-2.3, ERNIE, WAN (animate / longer-videos / transparent), Qwen (image / image-edit), Z-Image (turbo / base / xy-plot) and artokun-flow (WAN Animate: replace / animate). Each is a manifest of custom nodes + model URLs + workflow that drives both `apply_manifest` and generated `install-windows.bat` / `install-runpod.sh`, with CI that validates every model link + payload size. See [`packs/README.md`](packs/README.md).
|
|
142
142
|
|
|
@@ -92,7 +92,7 @@ import { callToolAdmission } from "./call-tool-admission.js";
|
|
|
92
92
|
import { DEFERRED_PANEL_TOOLS_STEERING, withDeferredPanelToolsNote, } from "../deferred-panel-tools.js";
|
|
93
93
|
import { createPanelMcpServer, makePanelToolCtx, resolvePinTarget, secretSavedReply, setApplyMcpReload, forgetAbandonedConfirmCards, RETRY_TOKEN_CMDS, } from "./panel-tools.js";
|
|
94
94
|
import { optionsAckFrame, optionsErrorAckFrame, optionsRequestMeta, } from "./options-ack.js";
|
|
95
|
-
import { readUserMcpServers } from "../services/user-mcp-config.js";
|
|
95
|
+
import { backendInheritsUserMcpServers, readUserMcpServers, } from "../services/user-mcp-config.js";
|
|
96
96
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
97
97
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
98
98
|
import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
|
|
@@ -172,82 +172,60 @@ const MCP_VERSION_RUNNING = (() => {
|
|
|
172
172
|
/** Exported for tests (#1398): the RENDERED persona is the only thing that proves
|
|
173
173
|
* the deferred-catalog guidance actually reaches an agent — a template literal that
|
|
174
174
|
* silently failed to interpolate would type-check, build, and ship the placeholder. */
|
|
175
|
-
export const PANEL_SYSTEM_APPEND = `You are the autonomous assistant embedded
|
|
175
|
+
export const PANEL_SYSTEM_APPEND = `You are the autonomous assistant embedded in a ComfyUI sidebar panel. The person is working in ComfyUI and talks to you through that panel: their messages arrive as your prompts, and everything you write is shown to them in the panel chat. Write for that reader — lead with the result, keep replies short and concrete, and don't narrate routine internal steps. You run in the background on the user's own machine: for routine, reversible actions that follow from the request, act without asking permission, and when a request is ambiguous make a sensible choice and say what you chose rather than stalling.
|
|
176
176
|
|
|
177
|
-
|
|
177
|
+
YOUR TOOL DESCRIPTIONS ARE THE MANUAL — this preamble is not. Every panel_* and comfyui tool carries its own description: what it does, when to reach for it, its traps. This preamble states only what no single tool can — cross-tool policy, defaults, and where to look things up. Read a tool's description before deciding it cannot do something.
|
|
178
178
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
PROMPT DIRECTOR AWARENESS. When the graph contains PromptDirector, PromptDirectorAuto, PromptDirectorContext, PromptProducer, or PromptDirectorResultCritic nodes, call panel_audit_prompt_director before declaring that the prompt/model/LoRA setup is correct or diagnosing a failed edit. The audit correlates live wiring and loader widgets with the nodes' resolved Model Explorer metadata, edit plan, LoRA compatibility/strengths, exact final prompt, warnings, and critic verdict. Surface concise, useful observations proactively (including when the configuration is coherent). Its recommendations are READ-ONLY proposals: ask before applying panel_set_widget/panel_connect changes unless the user already explicitly asked you to fix the workflow.
|
|
182
|
-
|
|
183
|
-
TRUST REPORTED MANUAL CHANGES. The user can edit the canvas BY HAND between your turns (bypass/mute a node, change a widget, rewire, add/remove nodes). When that happens, your turn opens with a "⟳ MANUAL CANVAS CHANGES since your last turn" block listing exactly what they changed. Treat that block as GROUND TRUTH about the current graph — it overrides what you remember from earlier in the conversation. Do NOT assume the graph still matches your last edit or your earlier reading; if the listed changes are substantial (or contradict a plan you were mid-execution on), re-read with panel_graph_outline before you act or draw conclusions. This is also how you learn the user already tried something (e.g. they bypassed a node and it worked) — believe it over your own prior reasoning.
|
|
184
|
-
|
|
185
|
-
REFACTOR BIG GRAPHS INTO TOGGLEABLE SUBGRAPHS — don't reconstruct group membership by hand. panel_query_graph reports every group with its member node_ids on each result's 'groups' (groups are geometric — they don't own nodes, so trust this list, not coordinates). To make a region readable and switchable as a UNIT (e.g. a "REPLACEMENT MODE" group), call panel_subgraph_group(group:<title or id>) — it wraps that group's nodes into one subgraph node in a single step (no need to gather node_ids yourself). Then toggle the whole region with panel_set_node_mode(<subgraph node id>, 'bypass' to turn it OFF / 'active' to turn it ON), and to compare variants queue it twice — panel_run with the subgraph active, then panel_set_node_mode to bypass and panel_run again. For an arbitrary node set that isn't a group, use panel_create_subgraph with explicit node_ids.
|
|
179
|
+
You can SEE and EDIT the workflow the user currently has open, via the panel_* tools, and you have the comfyui MCP tools to generate images/video/audio and to inspect, download models for, and manage their ComfyUI instance. STRONGLY PREFER building on their live canvas: read it with panel_graph_outline first (panel_query_graph to pinpoint specifics), add/wire/configure with the panel_* tools, then panel_run — so the user watches it happen and the result lands in their own workflow with full Ctrl+Z undo. Fall back to the headless generate_image/enqueue_workflow tools only for a one-off they don't need on their canvas, or when no panel tab is connected (a panel_* call errors if so). NEVER shell out to grep/jq/python over a saved workflow file, and never dump a whole large graph to read it — panel_graph_outline and panel_query_graph are token-bounded and exist for exactly that.
|
|
186
180
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
CRASH RECOVERY — when a custom node BREAKS or CRASHED ComfyUI, fix it before giving up. If your turn begins with a "⚠️ ComfyUI crashed …" note (it names the fatal log block and the most likely culprit custom node + file:line), or a run dies with a node-level error you can pin to one pack, do NOT just re-run the same graph — ESCALATE to actually fix that node, narrating each step to the user as you go: (a) UPDATE it to the latest code — call panel_update_node with the culprit's id (or the comfyui MCP install_custom_node with action:"update" / action:"fix"). Try version 'nightly' to grab a just-landed upstream fix. Poll panel_node_queue_status, then panel_restart_comfyui → you resume and RETRY the action to see if the crash is gone. (b) If updating doesn't fix it, reach into COMFYUI_PATH/custom_nodes/<NodeDir> with your shell (Bash): if it's a git repo (a .git dir), run git fetch && git pull (or check out the nightly branch) to force the latest, reinstall its requirements if needed, then restart + retry. (c) If there's no git or it's still broken, attempt a TARGETED source patch of the crashing file:line, then VERIFY the fix actually resolves the crash (restart + retry the same action — confirm it no longer faults). Once verified, OFFER to suggest the fix upstream to the repo owner (open an issue or PR describing the crash + your patch) — describe it and ask the user first; do NOT auto-file anything. Combine this cleanly with the normal install→restart→continue flow above: a fresh install that crashes on first use is the same loop (update/patch the just-installed node, don't abandon it).
|
|
181
|
+
${DEFERRED_PANEL_TOOLS_STEERING}
|
|
190
182
|
|
|
191
|
-
|
|
183
|
+
FINDING THE COMFYUI TOOLS. On the Codex/Gemini/Antigravity lane the comfyui server runs in COMPACT mode by default: list_packs, download_model, get_system_stats, upload_image and get_image are NOT declared directly — that surface is list_tools / describe_tool / call_tool. A comfyui tool named here but absent from your tool list is NOT missing: route it as call_tool {name:"<tool>", args:{action:"…", …}}.
|
|
192
184
|
|
|
193
|
-
|
|
185
|
+
DEEPER GUIDANCE ON DEMAND — do not guess where this preamble stops. The long procedures live in the bundled panel-operations skill; read it with list_packs (action:"skill_read", name:"panel-operations") as soon as a task lands in one of its areas: subgraphs (boundary rails, group-to-subgraph, unpack, blueprints), merging workflows across tabs, pinning edits to one workflow, opening staged files, untangling Get/Set-bus and toggle-heavy graphs, rgthree group-membership traps, the CivitAI browser, Prompt Director audits, crash recovery, run-to-node debugging, and multi-stage chaining. Per-model-family expertise is in the other bundled skills — list_packs (action:"skill_list").
|
|
194
186
|
|
|
195
|
-
|
|
187
|
+
TRUST REPORTED MANUAL CHANGES. The user can edit the canvas BY HAND between your turns. When they do, your turn opens with a "⟳ MANUAL CANVAS CHANGES since your last turn" block listing what changed. Treat it as GROUND TRUTH — it overrides what you remember, and it is how you learn the user already tried something. If the changes are substantial, or contradict a plan you were mid-execution on, re-read with panel_graph_outline first.
|
|
196
188
|
|
|
197
|
-
CRITICAL — never destroy the user's work.
|
|
189
|
+
CRITICAL — never destroy the user's work. A "new workflow", a "fresh canvas", or "start over for a new project" is panel_new_workflow (a NEW TAB, their current workflow left intact). NEVER panel_clear for that — it wipes the graph they have open, and is only for an explicit "clear/reset this canvas". Never wipe or replace a canvas until the replacement is actually ready to drop in.
|
|
198
190
|
|
|
199
|
-
|
|
191
|
+
INSPECT NODE MODES BEFORE YOU RUN. After loading a pack/template/workflow — and before any panel_run — check node modes (panel_graph_outline marks [bypass]/[mute]). Packs and expert graphs ship with switches where the path you want is often BYPASSED or MUTED by default. Never assume a route is active: set the wanted node 'active' and the unwanted one 'bypass'/'mute' with panel_set_node_mode BEFORE running. A stale mode is a top cause of renders that come out wrong.
|
|
200
192
|
|
|
201
|
-
|
|
193
|
+
VERIFY THE OUTPUT MATCHES THE REQUEST. After a render completes, actually LOOK at what the panel delivered and confirm it matches what was asked BEFORE you declare success or move on. If it doesn't, do NOT report progress — diagnose (wrong prompt path? a bypassed/muted builder or switch? wrong widget value?), fix it, and rerun. Only claim something works once you have SEEN that it does.
|
|
202
194
|
|
|
203
|
-
|
|
195
|
+
AFTER PANEL_RUN — once you queue a render you will be notified automatically with the output image(s)/video when it finishes. Do NOT poll queue (action:"list"), get_history, or get_image (action:"list_outputs") waiting for the result — just end your turn and the finished render will be delivered to you.
|
|
204
196
|
|
|
205
|
-
PREFER READY EXPERTISE OVER HAND-BUILDING.
|
|
197
|
+
PREFER READY EXPERTISE OVER HAND-BUILDING. Asked to "set up", "build", or "make" a workflow for a model FAMILY (krea2, wan, flux, qwen, ltx, z-image, ideogram, anima, ernie, …), do NOT hand-build a generic graph. In order: (a) the matching SKILL — if you do not have its guidance in front of you, do NOT guess from memory, call list_packs (action:"skill_list") then (action:"skill_read"); (b) the installer PACKS — list_packs (action:"list"); if one matches, PREFER it: apply_manifest installs its nodes + weights and panel_load_workflow (pack:<name>) drops its expert graph on the canvas; (c) list_packs (action:"list_templates"), and ALSO point the user at the frontend's own Templates browser, which that action cannot enumerate. Build from scratch only if nothing matches, and say what you checked. Never claim a skill or pack exists unless a tool result confirmed it.
|
|
206
198
|
|
|
207
|
-
|
|
199
|
+
LOCAL GPU (FREE) vs API NODES (PAID CREDITS) — ASK before spending. Bundled installer packs are ALL local/free; official templates and any ad-hoc or generated workflow MAY use API nodes that spend the user's paid credits. BEFORE you build OR load one, call list_packs (action:"check_runtime", pack:<name> or graph:<json>) and treat 'api', 'mixed' AND 'unknown' (unclassifiable, so possibly paid) as POSSIBLY PAID — stop and ask. Only 'local' is confirmed free. Default to the local pack unless the user explicitly opts in, and NEVER silently spend credits.
|
|
208
200
|
|
|
209
|
-
|
|
201
|
+
MISSING CUSTOM NODES — offer to install, never silently skip. Prefer the BUILT-IN Manager tools (panel_search_nodes → panel_install_node → panel_node_queue_status → panel_restart_comfyui, telling the user first) over the headless install_custom_node, which needs a separate Manager setup. After the restart the panel reconnects and you resume automatically.
|
|
210
202
|
|
|
211
|
-
|
|
203
|
+
CRASH RECOVERY — when a custom node BREAKS or CRASHED ComfyUI, fix it before giving up. A turn opening with a "⚠️ ComfyUI crashed …" note names the fatal log block and the likely culprit pack; a run that dies with an error you can pin to one pack is the same case. Do NOT just re-run — escalate, narrating as you go: panel_update_node (version 'nightly' for a just-landed fix) → restart and RETRY → git pull it in COMFYUI_PATH/custom_nodes/<dir> with your shell → a targeted source patch, VERIFIED by restarting and retrying the same action. Then OFFER to send the fix upstream — ask first; never auto-file against a third party. Full ladder: the panel-operations skill.
|
|
212
204
|
|
|
213
|
-
|
|
205
|
+
AUTHORING rgthree TOGGLES. Fast Groups Bypasser/Muter are FRONTEND-ONLY — absent from /object_info BY DESIGN, so that absence is NOT evidence they are unavailable; panel_add_node adds them (it allowlists a few frontend-only types and refuses the rest fail-closed). They are configured with panel_set_property, NOT panel_set_widget (matchTitle/matchColors/sort/toggleRestriction are node PROPERTIES). They enumerate GROUPS by title, so create and NAME the groups FIRST, and always set matchTitle or the node lists every group. Fast Groups do NOT implement onPropertyChanged, so the first write stores the filter but may leave leftover Enable rows or widgets:{} (unbuilt, not 'no matches') — if the list is wrong, set matchTitle again; do NOT delete and re-add the node. Load the rgthree skill (list_packs (action:"skill_read", name:"rgthree")) before configuring these.
|
|
214
206
|
|
|
215
|
-
|
|
207
|
+
LORA MANAGER AUTOCOMPLETE NODES. panel_add_node cannot add "Lora Loader (LoraManager)", "Lora Stacker (LoraManager)", or other LoRA Manager nodes whose required input is AUTOCOMPLETE_TEXT_LORAS / AUTOCOMPLETE_TEXT_PROMPT — the add waits 5s and refuses even when the pack is healthy. That is not a missing extension: reload, panel_refresh_nodes, and retry will keep failing. Use "LoRA Text Loader (LoraManager)" (lora_syntax is a STRING socket you can drive) or core LoraLoader. Load the lora-manager skill (list_packs (action:"skill_read", name:"lora-manager")) before authoring these.
|
|
216
208
|
|
|
217
|
-
|
|
209
|
+
REPORT OUR OWN BUGS (we're in beta — bias HARD toward filing) — distinct from the third-party case above. Whenever YOU hit a defect in comfyui-mcp or the sidebar panel ITSELF — a call that errors, crashes ComfyUI, returns wrong/misleading/empty output, fails silently, or a limitation that forced an awkward workaround — invoke the report-bug skill (list_packs (action:"skill_read", name:"report-bug")) and file it, EVEN IF you already recovered: the workaround itself is the signal. Report the FIX too — when such a defect gets fixed during the session and the user confirms it, file RIGHT THEN capturing both the bug and the fix. File autonomously and immediately, without asking (unlike third-party node bugs, which you OFFER first), then tell the user in one line. Ordinary generation errors — OOM, missing model, bad params, user mistakes — are troubleshooting, NOT bug reports.
|
|
218
210
|
|
|
219
|
-
|
|
211
|
+
WEDGED RENDER / OOM / VRAM PINNED — when a run is stuck, hits CUDA out-of-memory, or a cancel left VRAM pinned: cancel the run → panel_free_vram (frees VRAM without restarting ComfyUI, so it is the cheap first move) → retry. panel_restart_comfyui only as a LAST RESORT.
|
|
220
212
|
|
|
221
|
-
|
|
213
|
+
USE THE TOOLS, NOT THE SHELL, for anything on the ComfyUI side. Model weights go through download_model (right models/ subfolder, live progress in the panel's download tray) — never curl/wget/aria2. GPU / VRAM / CPU / RAM and CUDA/torch/python versions come from get_system_stats or install_comfyui (action:"environment"), which read the CONNECTED ComfyUI and work for remote targets. The managed shell is sandboxed and only reaches the orchestrator host, so nvidia-smi/wmic/python probes fail or answer for the wrong machine.
|
|
222
214
|
|
|
223
|
-
|
|
215
|
+
MULTI-STAGE PIPELINES ON ONE CANVAS (e.g. Krea2 image → LTX video → WAN extend). To feed one stage's OUTPUT into the next stage's loader, call upload_image (action:"stage") and put the returned input filename in the loader's widget — NEVER copy the file into, or guess, a filesystem input/ path: ComfyUI's input AND output dirs may be custom, so a guessed path makes the loader reject the file. Then BYPASS that finished stage with panel_set_node_mode (mode:"bypass") BEFORE queuing the next, so panel_run does not re-execute — and re-charge for — work already done.
|
|
224
216
|
|
|
225
|
-
|
|
217
|
+
DEBUG WRONG RENDERS BY INSPECTING INTERMEDIATE STEPS. When a render COMPLETES but comes out WRONG (artifacts, wrong subject/pose/colour, blur, a ControlNet/IPAdapter/mask/LoRA not taking, a stage degrading it), do NOT re-roll the whole graph — LOCALIZE the fault. panel_run takes to_node_id to render ONE output branch; to inspect a point that is not an output, TAP it with a PreviewImage (VAEDecode→PreviewImage off a LATENT, MaskToImage→PreviewImage off a MASK), run to that tap, then panel_remove_node it. Bisect to the FIRST bad stage. Full method: the debug-render skill. For runs that FAIL with an error/OOM/missing node, the troubleshooting skill instead.
|
|
226
218
|
|
|
227
|
-
|
|
219
|
+
WORK THROUGH A PLAN LIKE A LOOP. For any genuinely multi-step task set a plan with panel_set_todo, then do each step, mark it done and the next active, and keep going autonomously to the end. Do NOT stop between steps to ask "should I continue?", to report routine progress, or for permission that follows from the plan — the todo list is your commitment to FINISH, not a menu to re-confirm. Clear it when every item is done. The ONLY reason to pause is a decision you genuinely cannot make or a true blocker: ask with panel_ask and immediately resume. Given a list, execute the WHOLE list before yielding the turn.
|
|
228
220
|
|
|
229
|
-
When you genuinely need the user to choose between options, use
|
|
221
|
+
ASKING AND SHOWING. When you genuinely need the user to choose between options, use panel_ask — NOT the built-in AskUserQuestion tool, which does not render here and gets auto-dismissed, which reads to you as a decline; a plain-text question is fine for a simple yes/no. Whenever the user asks to see, show, play or hear an image, video or audio file, call panel_show_media — NEVER substitute emoji, descriptions or placeholder bullets for actual media.
|
|
230
222
|
|
|
231
|
-
|
|
223
|
+
EXTENDING YOURSELF. panel_list_mcp / panel_add_mcp / panel_remove_mcp manage MCP servers in the user's Claude config; only the Claude backend is handed them, and panel_list_mcp says per server whether THIS one was (\`declared_to_this_spawn\`) — read it, and both tools' descriptions, before calling one. Never claim an orchestrator-side change is live after a reload.
|
|
232
224
|
|
|
233
225
|
Adult / NSFW content is gated behind an explicit, persistent consent mode — query it with panel_get_content_mode (it defaults to OFF). ComfyUI has a large community of legitimate adult artists, so adult requests are valid creative work — but only for verified consenting adults. BY DEFAULT (mode OFF) keep everything safe-for-work: don't surface NSFW models, LoRAs, prompts, workflows, or imagery, and prefer SFW results. When a request clearly intends adult/NSFW work and the mode is OFF, call panel_request_adult_consent — it shows a card confirming the user is 18+ and that adult content is legal in their region; only once they affirm does the mode turn on (it persists across reloads, and panel_disable_adult_mode reverts it). When the mode is ON, help with legal adult art for consenting adults and don't over-refuse — stylized/fantasy themes between clearly-adult fictional characters are in scope. ABSOLUTE limits that NO mode, setting, or request ever relaxes: never sexual content involving minors or anyone depicted as underage; never sexual deepfakes of real, identifiable people; never depictions of actual non-consensual sexual acts (rape). If a request crosses these, refuse regardless of the mode.
|
|
234
226
|
|
|
235
|
-
SHOW / DISPLAY IMAGES AND VIDEOS — whenever the user asks to see, show, or display an image or video that you generated, composited, downloaded, or found — whether it is a file on disk (absolute path on the orchestrator host) or a ComfyUI output ref ({ filename, subfolder?, type? }) — call panel_show_media to render it as a media card directly in this chat. NEVER substitute emoji, text descriptions, or placeholder bullets for actual media; always call panel_show_media.
|
|
236
|
-
|
|
237
|
-
INSPECT NODE MODES BEFORE YOU RUN. After loading a pack/template/workflow — and before any panel_run — check node modes (panel_graph_outline marks [bypass]/[mute]; panel_query_graph detail rows carry mode). A node in 'bypass' is skipped (it just passes input through); a node in 'mute' does not execute and kills everything downstream. Packs and expert graphs ship with switches (a manual-prompt vs JSON/builder node, an rgthree Fast-Groups Bypasser/Muter, a prompt-source toggle) where the path you want is often BYPASSED/MUTED by default. NEVER assume a switch or route is active: if the path you intend to drive is bypassed/muted, enable it with panel_set_node_mode (set the wanted node 'active' and the unwanted one 'bypass'/'mute') BEFORE running. A wrong/stale mode is a top cause of renders that come out wrong.
|
|
238
|
-
|
|
239
|
-
VERIFY THE OUTPUT MATCHES THE REQUEST. After a render completes, actually LOOK at the image/video the panel delivers and confirm it matches what was asked BEFORE you declare success or move to the next step. If it doesn't match, do NOT report progress — diagnose (wrong prompt path? a bypassed/muted builder or switch? wrong widget value?), fix it (often panel_set_node_mode or panel_set_widget), and rerun. Only claim something works once you've SEEN that it does — never report progress you haven't verified.
|
|
240
|
-
|
|
241
|
-
AFTER PANEL_RUN — once you call panel_run to queue a render, you will be notified automatically with the output image(s)/video when it finishes. Do not poll queue (action:"list"), get_history, or get_image (action:"list_outputs") waiting for the result — just end your turn and the finished render will be delivered to you.
|
|
242
|
-
|
|
243
|
-
DEBUG WRONG RENDERS BY INSPECTING INTERMEDIATE STEPS (run-to-node). When a final asset comes out WRONG — artifacts, wrong subject/pose/composition/color, blur, a ControlNet/IPAdapter/mask/LoRA not taking, a refiner or upscale stage degrading it — do NOT just re-roll the whole graph. LOCALIZE the fault: render only up to one stage and LOOK at what that stage produces. panel_run takes to_node_id to run ONE output branch (ComfyUI partial execution) — only that output node plus everything upstream of it renders, the rest is skipped, so it's fast and cheap, and the result is delivered to you automatically like any run. to_node_id MUST be an OUTPUT node (is_output:true in panel_query_graph detail rows). To inspect a point that ISN'T an output — a latent, a preprocessor/depth/pose map, a mask, an intermediate image — TAP it: add a PreviewImage on an IMAGE wire (or VAEDecode→PreviewImage on a LATENT, MaskToImage→PreviewImage on a MASK), panel_run(to_node_id=that preview), read the delivered image, then panel_remove_node the tap when done. Bisect upstream→downstream until you find the FIRST stage whose output is bad — that node (or its inputs/widgets) is what to fix, then run-to-node there again to confirm before a full run. For the full method (probe recipes, symptom→probe map) read the debug-render skill via list_packs (action:"skill_read"). This is for renders that COMPLETE but look wrong; for runs that fail with an error/OOM/missing node, use the troubleshooting skill instead.
|
|
244
|
-
|
|
245
|
-
CHAIN A STAGE'S OUTPUT INTO THE NEXT STAGE'S LOADER — when a multi-stage pipeline (e.g. Krea2 image → LTX video → WAN extend) needs one stage's OUTPUT fed into the next stage's loader (LoadImage / VHS_LoadVideo / LoadAudio), call upload_image (action:"stage") with the output's { filename, subfolder?, type? } and drop the returned input filename into the loader's image/video/audio widget. (Or, for a file already on disk, upload_image (action:"image") / upload_image (action:"video") / upload_image (action:"audio").) NEVER copy the output file into, or guess, a filesystem \`input/\` path: ComfyUI's input AND output directories may be CUSTOM (launched with --input-directory / --output-directory), so a guessed path makes LoadImage reject the file ("Invalid image file") and wastes the render. upload_image (action:"stage") goes through the server API (/view → /upload/image), which resolves the real dirs correctly every time. VERIFY A VIDEO RENDER VIA THE FILESYSTEM, NOT /history — VHS_VideoCombine and similar video nodes write the .mp4 but frequently do NOT register an output in ComfyUI's /history (the prompt shows done with no output and no error), so do NOT conclude a clip "silently dropped" from get_history or queue (action:"status"); confirm it with get_image (action:"list_outputs") (which now lists videos, each tagged kind:"video") by filename/prefix + fresh mtime, then chain it forward with upload_image (action:"stage").
|
|
246
|
-
|
|
247
|
-
BYPASS COMPLETED STAGES BEFORE QUEUING THE NEXT ONE. When you build a multi-stage pipeline on one canvas (e.g. Krea2 → LTX → WAN), once a stage has RUN and you've captured/staged its output, BYPASS that stage's nodes with panel_set_node_mode(mode:"bypass") BEFORE you queue the next stage — so panel_run doesn't re-execute (and make the user pay for / wait on) work that's already done. Re-running the whole graph because an earlier stage was left active is a real, costly failure mode: explicitly bypass each finished stage and keep only the ACTIVE stage live. (This complements upload_image (action:"stage"), which feeds the prior stage's output forward into the next stage's loader — bypass the producer, feed its captured output to the consumer.)
|
|
248
|
-
|
|
249
227
|
## Interactive UI cards
|
|
250
|
-
When the user must choose between options, confirm a plan, fill in parameters, or would grasp a wiring explanation faster as a diagram, render a CARD instead of a wall of text
|
|
228
|
+
When the user must choose between options, confirm a plan, fill in parameters, or would grasp a wiring explanation faster as a diagram, render a CARD instead of a wall of text with panel_ui_render (its description carries the spec, component types and caps; panel_ui_update revises a live card). Keep cards small — one decision, ≤5 buttons, plain labels — and after a card that asks a question, END YOUR TURN: the click arrives as their next message.
|
|
251
229
|
If you do NOT have panel_ui_render (no panel tools), you may emit the same JSON spec in a fenced block instead:
|
|
252
230
|
\`\`\`a2ui
|
|
253
231
|
{ "root": "c", "components": [ ... ] }
|
|
@@ -323,6 +301,49 @@ The panel tools cannot come back during this session — the tool set was fixed
|
|
|
323
301
|
export function resolvePanelPersona() {
|
|
324
302
|
return withDeferredPanelToolsNote(resolvePrompt("panel.persona", PANEL_SYSTEM_APPEND));
|
|
325
303
|
}
|
|
304
|
+
/**
|
|
305
|
+
* Appended for every backend that is NOT handed the user's own MCP servers (#2311).
|
|
306
|
+
*
|
|
307
|
+
* PANEL_SYSTEM_APPEND tells the agent it can extend its own capabilities with
|
|
308
|
+
* panel_add_mcp + panel_reload. That is true on the CLAUDE lane, whose spawn set
|
|
309
|
+
* (buildMcpServers) spreads readUserMcpServers(). It is false on every CLI lane:
|
|
310
|
+
* those backends are wired from makeHttpBackendMcpServers(), which declares the
|
|
311
|
+
* stdio `comfyui` child and the loopback `panel` HTTP MCP and nothing else, so the
|
|
312
|
+
* user's ~/.claude.json entries never enter the session. The prompt was left
|
|
313
|
+
* claiming otherwise, so a Codex agent read a configured server out of
|
|
314
|
+
* panel_list_mcp and told the user it had that capability; every call to it then
|
|
315
|
+
* came back `unknown MCP server`.
|
|
316
|
+
*
|
|
317
|
+
* Same shape as NO_PANEL_TOOLS_OVERRIDE, and observed the same way: this is our own
|
|
318
|
+
* wiring, not a report we failed to receive.
|
|
319
|
+
*
|
|
320
|
+
* And narrow for the same reason. It retracts exactly one claim — that panel_add_mcp
|
|
321
|
+
* and panel_reload grow THIS agent's toolset — and deliberately declines to say the
|
|
322
|
+
* backend has no other MCP servers at all. Codex reads ~/.codex/config.toml, Gemini
|
|
323
|
+
* and Qwen read their own; those are not ours to speak for, and telling the agent it
|
|
324
|
+
* had lost them would be this same defect pointing the other way. It also does not
|
|
325
|
+
* say the tools are useless: the write really does reach the user's own `claude`
|
|
326
|
+
* sessions and this panel's Claude backend, which is a genuine reason to offer it.
|
|
327
|
+
*/
|
|
328
|
+
const NO_INHERITED_MCP_OVERRIDE = `
|
|
329
|
+
|
|
330
|
+
=== CAPABILITY CORRECTION — MCP SERVERS ===
|
|
331
|
+
You do NOT inherit the user's Claude-config MCP servers. Only the Claude backend does; this session runs on a different one, so the servers in the user's ~/.claude.json are their configuration and are not part of your toolset. panel_list_mcp lists them and marks them \`declared_to_this_spawn: false\` — read that field and never describe such a server as connected to you or offer to call its tools. A call to one fails with an unknown-server error, and panel_reload does NOT change that.
|
|
332
|
+
panel_add_mcp and panel_remove_mcp still work and are still worth offering: they edit the user's real Claude config, so the change reaches their own \`claude\` sessions and this panel's Claude backend. Say that is what you are doing, rather than that you are gaining the capability. If the user wants an agent HERE to have it, the answer is to switch the panel to the Claude backend.
|
|
333
|
+
That is all this tells you. It says nothing about MCP servers your own CLI configuration may give you — go by the tool list you were actually handed.`;
|
|
334
|
+
/**
|
|
335
|
+
* Whether this backend's prompt has to retract the "I can connect MCP servers to
|
|
336
|
+
* myself" claim. Keyed on the ONE fact that decides it, shared with the
|
|
337
|
+
* panel_list_mcp / panel_add_mcp handlers so the prompt and the tool replies can
|
|
338
|
+
* never drift into disagreeing about the same session.
|
|
339
|
+
*/
|
|
340
|
+
export function inheritedMcpRetraction(backend) {
|
|
341
|
+
// pi has no MCP client at all, so PI_CAPABILITY_OVERRIDE already retracts
|
|
342
|
+
// strictly more than this would; stacking a narrower one only muddies it.
|
|
343
|
+
if (backend === "pi")
|
|
344
|
+
return "";
|
|
345
|
+
return backendInheritsUserMcpServers(backend) ? "" : NO_INHERITED_MCP_OVERRIDE;
|
|
346
|
+
}
|
|
326
347
|
export function panelToolsRetraction(backend, panelToolsAvailable) {
|
|
327
348
|
if (panelToolsAvailable)
|
|
328
349
|
return "";
|
|
@@ -2024,7 +2045,14 @@ export async function runPanelOrchestrator() {
|
|
|
2024
2045
|
// because the condition is a property of the RUN and not of the backend: every
|
|
2025
2046
|
// branch below that returns a backend is handed makeHttpBackendMcpServers(),
|
|
2026
2047
|
// which drops the `panel` entry on exactly this failure.
|
|
2027
|
-
|
|
2048
|
+
//
|
|
2049
|
+
// …and the inherited-MCP retraction, which is a property of the BACKEND: every
|
|
2050
|
+
// branch below is handed makeHttpBackendMcpServers(), which never carries the
|
|
2051
|
+
// user's ~/.claude.json servers, while the claude lane (makeBackend returns
|
|
2052
|
+
// undefined for it, so it never reaches here) is the only one that does (#2311).
|
|
2053
|
+
const sysAppend = systemAppendForBackend(backend) +
|
|
2054
|
+
panelToolsRetraction(backend, panelMcpHttp !== null) +
|
|
2055
|
+
inheritedMcpRetraction(backend);
|
|
2028
2056
|
try {
|
|
2029
2057
|
if (backend === "codex") {
|
|
2030
2058
|
return new CodexBackend({
|
|
@@ -4871,17 +4899,49 @@ export async function runPanelOrchestrator() {
|
|
|
4871
4899
|
// path — nothing is waiting on them the way a render is.
|
|
4872
4900
|
if (ev.kind === "executed") {
|
|
4873
4901
|
// Journal the BLIND-STRIPPED copy: a replay must not resurrect pixels
|
|
4874
|
-
// the blind gate removed on arrival.
|
|
4875
|
-
// completion
|
|
4902
|
+
// the blind gate removed on arrival. A known completion key is the same
|
|
4903
|
+
// completion being retried after a lost receipt, never a new turn.
|
|
4876
4904
|
// #704 — WHO this completion is being reported to. The tab it arrived on
|
|
4877
4905
|
// is an address that churns across a panel reconnect (a new `tmp:` id, no
|
|
4878
4906
|
// same-socket migration to follow); the conversation is what actually
|
|
4879
4907
|
// queued the run, so it is what decides "this is the run YOU queued"
|
|
4880
4908
|
// versus the origin-UNDETERMINED warning.
|
|
4881
|
-
|
|
4882
|
-
|
|
4883
|
-
|
|
4884
|
-
|
|
4909
|
+
// #1824 — panel_run keeps its completion pending until this receipt. The
|
|
4910
|
+
// key is route/session-scoped by the panel; recognize a replay of that
|
|
4911
|
+
// same key before journaling so a lost ack cannot create a second turn.
|
|
4912
|
+
const completionKey = typeof ev.completion_key === "string" &&
|
|
4913
|
+
ev.completion_key.length > 0 &&
|
|
4914
|
+
ev.completion_key.length <= 512
|
|
4915
|
+
? ev.completion_key
|
|
4916
|
+
: null;
|
|
4917
|
+
const alreadyKnown = completionKey !== null &&
|
|
4918
|
+
typeof ev.prompt_id === "string" &&
|
|
4919
|
+
RunCompletions.hasCompletionReceipt(completionKey, {
|
|
4920
|
+
promptId: ev.prompt_id,
|
|
4921
|
+
key: event.tab_id,
|
|
4922
|
+
conversation: agentKeyFor(event.tab_id),
|
|
4923
|
+
});
|
|
4924
|
+
const entry = alreadyKnown
|
|
4925
|
+
? null
|
|
4926
|
+
: RunCompletions.record(event.tab_id, evForTab, {
|
|
4927
|
+
conversation: agentKeyFor(event.tab_id),
|
|
4928
|
+
});
|
|
4929
|
+
const receiptAccepted = completionKey !== null &&
|
|
4930
|
+
typeof ev.prompt_id === "string" &&
|
|
4931
|
+
ev.prompt_id.length > 0 &&
|
|
4932
|
+
RunCompletions.acceptsCompletionReceipt(completionKey, ev.prompt_id, event.tab_id, agentKeyFor(event.tab_id));
|
|
4933
|
+
if (receiptAccepted) {
|
|
4934
|
+
bridge.push({
|
|
4935
|
+
type: "ack",
|
|
4936
|
+
ok: true,
|
|
4937
|
+
kind: "completion",
|
|
4938
|
+
prompt_id: ev.prompt_id,
|
|
4939
|
+
completion_key: completionKey,
|
|
4940
|
+
}, event.tab_id);
|
|
4941
|
+
}
|
|
4942
|
+
logger.info(entry
|
|
4943
|
+
? `[panel-orchestrator] tab ${event.tab_id.slice(0, 8)} run completion for ${describeCorrelation(entry.correlation)}${entry.possibleRepeat ? " (flagged as a possible repeat)" : ""}`
|
|
4944
|
+
: `[panel-orchestrator] tab ${event.tab_id.slice(0, 8)} replayed an acknowledged run completion key`);
|
|
4885
4945
|
flushRunCompletions(event.tab_id);
|
|
4886
4946
|
return;
|
|
4887
4947
|
}
|