comfyui-mcp 0.52.143 → 0.52.144

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.
@@ -38,6 +38,7 @@ import { getModelInventoryDisclosure, } from "../services/model-inventory-disclo
38
38
  import { sanitizePanelUpdateNodeResult } from "../services/manager-update-error.js";
39
39
  import { formatQueueStatusPartialNote, getManifestPartialLeftover, } from "../services/manifest-partial.js";
40
40
  import { searchPanelNodes } from "../services/manager-node-search.js";
41
+ import { listPanelNodes } from "../services/manager-node-list.js";
41
42
  import { isPanelAnsweredError } from "../services/panel-answered.js";
42
43
  import { readWorkflowListReadiness, workflowListReadinessOf, } from "../services/panel-workflow-readiness.js";
43
44
  import { isPreExecutorRefusal } from "../services/panel-refusal.js";
@@ -7185,6 +7186,38 @@ function acceptedPromptId(parsed) {
7185
7186
  function isPanelQueueUncertainty(parsed) {
7186
7187
  return parsed?.queued_unknown === true;
7187
7188
  }
7189
+ /**
7190
+ * #2438 — the live-canvas surface has no render-queue inspector. Panel
7191
+ * `retry_guidance` historically named `queue (action:"list")`, which is a
7192
+ * headless stdio tool and may be unreachable (ECONNREFUSED) even while the
7193
+ * panel is connected. The only safe next step on this surface is to wait for
7194
+ * an eventual UNDETERMINED completion and not re-dispatch.
7195
+ */
7196
+ const PANEL_QUEUED_UNKNOWN_RETRY_GUIDANCE = `Do NOT re-run panel_run: the /prompt request already left the panel, and a second ` +
7197
+ `dispatch may queue a duplicate render. This live-canvas surface has no render-queue ` +
7198
+ `inspection tool. End your turn and wait for an eventual UNDETERMINED completion ` +
7199
+ `event for this tab; if one arrives, treat it as this run's possible outcome rather ` +
7200
+ `than queuing another.`;
7201
+ function applyQueuedUnknownRetryGuidance(res) {
7202
+ const parsed = parseToolResultJson(res);
7203
+ if (!parsed || !isPanelQueueUncertainty(parsed))
7204
+ return res;
7205
+ if (parsed.retry_guidance === PANEL_QUEUED_UNKNOWN_RETRY_GUIDANCE)
7206
+ return res;
7207
+ return {
7208
+ ...res,
7209
+ content: [
7210
+ {
7211
+ type: "text",
7212
+ text: JSON.stringify({
7213
+ ...parsed,
7214
+ retry_guidance: PANEL_QUEUED_UNKNOWN_RETRY_GUIDANCE,
7215
+ }),
7216
+ },
7217
+ ...res.content.slice(1),
7218
+ ],
7219
+ };
7220
+ }
7188
7221
  function detectRunRejection(res) {
7189
7222
  // Bridge/transport/executor error: never a queue. Preserve it verbatim (#248),
7190
7223
  // no success note (#331). fail() already carries err.message (incl. any stack).
@@ -7194,9 +7227,9 @@ function detectRunRejection(res) {
7194
7227
  if (!parsed)
7195
7228
  return null; // unparseable non-error reply — don't regress a success
7196
7229
  // #2143 — `queued_unknown` is an explicit Panel receipt, not the ComfyUI
7197
- // rejection channel. Its `error` field explains the timeout and its
7198
- // `retry_guidance` tells the caller how to settle it; keep the receipt intact
7199
- // and never redispatch from here.
7230
+ // rejection channel. Its `error` field explains the timeout. Keep the
7231
+ // receipt intact and never redispatch from here; the handler rewrites
7232
+ // `retry_guidance` onto this surface (#2438) after this gate.
7200
7233
  if (isPanelQueueUncertainty(parsed))
7201
7234
  return null;
7202
7235
  const topError = parsed.error;
@@ -7336,6 +7369,8 @@ export const __panelRunTestHooks = {
7336
7369
  isRetryableRunToNodeStampRace,
7337
7370
  isSeedRunToNodeStampRace,
7338
7371
  describeDroppedOutputs,
7372
+ applyQueuedUnknownRetryGuidance,
7373
+ PANEL_QUEUED_UNKNOWN_RETRY_GUIDANCE,
7339
7374
  };
7340
7375
  /** Drop a trailing .json (case-insensitive) so filename/path forms compare equal. */
7341
7376
  function stripJsonExt(s) {
@@ -13403,20 +13438,20 @@ function panelLateReceiptNote(promptId) {
13403
13438
  `panel_run or you may queue a duplicate render.`);
13404
13439
  }
13405
13440
  /**
13406
- * #2143 — a normal Panel timeout receipt is neither a confirmed queue nor a
13407
- * refusal. Keep its retry guidance in the original JSON and add only the
13408
- * local fact that this handler did not dispatch a second run.
13441
+ * #2143 / #2438 — a normal Panel timeout receipt is neither a confirmed queue
13442
+ * nor a refusal. Name the next step that exists on THIS surface rather than
13443
+ * forwarding Panel retry_guidance that points at a headless queue inspector.
13409
13444
  */
13410
13445
  function panelQueueUncertaintyNote(queuedPromptIds) {
13411
13446
  if (queuedPromptIds.length > 0) {
13412
13447
  return (`\n\n[UNCERTAIN] The Panel confirmed these prompt id(s) left its queue path: ` +
13413
13448
  `${queuedPromptIds.join(", ")}. Completion tickets were opened for them. ` +
13414
- `Any remaining request(s) are still uncertain; follow the Panel's retry_guidance above ` +
13415
- `before retrying. No second panel_run was dispatched.`);
13449
+ `Any remaining request(s) are still uncertain. ${PANEL_QUEUED_UNKNOWN_RETRY_GUIDANCE} ` +
13450
+ `No second panel_run was dispatched.`);
13416
13451
  }
13417
13452
  return (`\n\n[UNCERTAIN] The Panel could not determine whether this run entered ComfyUI's queue. ` +
13418
13453
  `This is not a confirmed refusal, and no completion ticket can be opened without a prompt id. ` +
13419
- `Follow the Panel's retry_guidance above before retrying. No second panel_run was dispatched.`);
13454
+ `${PANEL_QUEUED_UNKNOWN_RETRY_GUIDANCE} No second panel_run was dispatched.`);
13420
13455
  }
13421
13456
  async function pollLateAskReply(bridge, askId, timing, hardDeadline) {
13422
13457
  const probe = bridge;
@@ -16456,6 +16491,11 @@ export function buildPanelToolDefs() {
16456
16491
  `If the running job is genuinely stuck, queue (action:"cancel") with clear_pending:true interrupts it AND drops pending, then escalate to restart_comfyui if it reports the job wedged.`;
16457
16492
  }
16458
16493
  }
16494
+ // #2438 — rewrite Panel retry_guidance BEFORE the notes are spliced so
16495
+ // a headless `queue (action:"list")` inspector is not left in the JSON
16496
+ // for a surface that cannot call it.
16497
+ if (panelQueueUncertain)
16498
+ res = applyQueuedUnknownRetryGuidance(res);
16459
16499
  if (res.content?.[0]?.type === "text") {
16460
16500
  return {
16461
16501
  ...res,
@@ -18558,7 +18598,20 @@ CHECKED FOR YOU: the graph read this message prescribes was just run, and it ` +
18558
18598
  });
18559
18599
  return out.via === "panel" ? out.value : ok(out.value);
18560
18600
  }),
18561
- def("panel_list_nodes", "List the custom-node PACKS currently installed in the user's ComfyUI (via the built-in Manager). Takes no arguments — it returns the whole installed set. Read-only. This lists packs, NOT node classes: to find out whether a specific node type is available (e.g. LTXVContextWindowsGuideAware), use comfy_cli action:\"search_nodes\", which fuzzy-searches real node classes and falls back to the connected server's live /object_info. panel_search_nodes is a third thing again — it searches INSTALLABLE packs in the registry, not what is already here.", {}, async (_args, ctx) => ctx.call({ cmd: "nodes_list" }, 20000)),
18601
+ def("panel_list_nodes", "List the custom-node PACKS currently installed in the user's ComfyUI (via the built-in Manager). Takes no arguments — it returns the whole installed set. Read-only. This lists packs, NOT node classes: to find out whether a specific node type is available (e.g. LTXVContextWindowsGuideAware), use comfy_cli action:\"search_nodes\", which fuzzy-searches real node classes and falls back to the connected server's live /object_info. panel_search_nodes is a third thing again — it searches INSTALLABLE packs in the registry, not what is already here. If the panel tab is gone, the listing is served from the ComfyUI host's Manager HTTP instead of failing as a dispatch error.", {}, async (_args, ctx) => {
18602
+ // #2459 — pack listing is a Manager / object_info server-state read.
18603
+ // Try the live tab first (Manager dialect + /object_info + #1496
18604
+ // filter). When dispatch never reaches the tab, serve the same
18605
+ // inventory from host Manager HTTP instead of dying as tab-loss.
18606
+ const out = await listPanelNodes({
18607
+ panelList: () => ctx.call({ cmd: "nodes_list" }, 20000),
18608
+ });
18609
+ if (out.via === "panel")
18610
+ return out.value;
18611
+ if (out.via === "fallback")
18612
+ return ok(out.value);
18613
+ return fail(out.message);
18614
+ }),
18562
18615
  def("panel_install_node", "Install a custom-node pack into the user's ComfyUI through the BUILT-IN Manager. Registry ids are supported: pass an id from panel_search_nodes (or another known registry id), then poll panel_node_queue_status and verify with panel_list_nodes before restarting. The panel runtime refuses Git URLs before Manager v4 queueing because v4 ignores the supplied repository and resolves by bare name, so a URL is not a successful v4 from-source install. Use an id from panel_search_nodes; use install_custom_node(source:'git') only when its local target is the same ComfyUI as this panel. If the panel drives another machine, install the repository on the ComfyUI host instead. The repository input remains normalized for legacy Manager 3.x direct-URL routing, but that compatibility path is not a v4 guarantee. The channel input can select a Manager channel for a supported registry-id install; it does not bypass the v4 Git-URL refusal. Install packs one at a time and confirm each is present before restarting.", {
18563
18616
  id: z.string().optional().describe("Registry id returned by panel_search_nodes."),
18564
18617
  repository: z