comfyui-mcp 0.52.86 → 0.52.87
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.
|
@@ -5533,10 +5533,6 @@ function formatRunRejection(payload) {
|
|
|
5533
5533
|
* overrides the flag-based rule and #213 does not regress: that reply had no
|
|
5534
5534
|
* prompt id. The same asymmetry the retry guard already relies on.
|
|
5535
5535
|
*/
|
|
5536
|
-
function acceptedPromptId(parsed) {
|
|
5537
|
-
const pid = parsed?.prompt_id;
|
|
5538
|
-
return typeof pid === "string" && pid.trim() !== "" ? pid.trim() : null;
|
|
5539
|
-
}
|
|
5540
5536
|
/**
|
|
5541
5537
|
* EVERY prompt id a graph_run reply minted, first one first (#949).
|
|
5542
5538
|
*
|
|
@@ -5548,6 +5544,8 @@ function acceptedPromptId(parsed) {
|
|
|
5548
5544
|
*
|
|
5549
5545
|
* Deduped and order-preserving: `prompt_id` normally repeats the first entry of
|
|
5550
5546
|
* `prompt_ids`, and a duplicate would open two tickets for one render.
|
|
5547
|
+
* The Panel's scoped-run uncertainty receipt uses `queued_prompt_ids` for the
|
|
5548
|
+
* subset it did confirm (#2143); those are receipts too and must be ticketed.
|
|
5551
5549
|
*/
|
|
5552
5550
|
export function acceptedPromptIds(parsed) {
|
|
5553
5551
|
const out = [];
|
|
@@ -5563,8 +5561,24 @@ export function acceptedPromptIds(parsed) {
|
|
|
5563
5561
|
if (Array.isArray(many))
|
|
5564
5562
|
for (const v of many)
|
|
5565
5563
|
add(v);
|
|
5564
|
+
const queued = parsed?.queued_prompt_ids;
|
|
5565
|
+
if (Array.isArray(queued))
|
|
5566
|
+
for (const v of queued)
|
|
5567
|
+
add(v);
|
|
5566
5568
|
return out;
|
|
5567
5569
|
}
|
|
5570
|
+
function acceptedPromptId(parsed) {
|
|
5571
|
+
return acceptedPromptIds(parsed)[0] ?? null;
|
|
5572
|
+
}
|
|
5573
|
+
/**
|
|
5574
|
+
* The Panel's explicit scoped-run uncertainty contract (#2143). This is a
|
|
5575
|
+
* normal, parseable receipt rather than a transport failure: the Panel knows
|
|
5576
|
+
* that one or more requests left the tab but cannot prove whether ComfyUI
|
|
5577
|
+
* accepted them. Do not reinterpret its `error` field as a refusal.
|
|
5578
|
+
*/
|
|
5579
|
+
function isPanelQueueUncertainty(parsed) {
|
|
5580
|
+
return parsed?.queued_unknown === true;
|
|
5581
|
+
}
|
|
5568
5582
|
function detectRunRejection(res) {
|
|
5569
5583
|
// Bridge/transport/executor error: never a queue. Preserve it verbatim (#248),
|
|
5570
5584
|
// no success note (#331). fail() already carries err.message (incl. any stack).
|
|
@@ -5573,6 +5587,12 @@ function detectRunRejection(res) {
|
|
|
5573
5587
|
const parsed = parseToolResultJson(res);
|
|
5574
5588
|
if (!parsed)
|
|
5575
5589
|
return null; // unparseable non-error reply — don't regress a success
|
|
5590
|
+
// #2143 — `queued_unknown` is an explicit Panel receipt, not the ComfyUI
|
|
5591
|
+
// rejection channel. Its `error` field explains the timeout and its
|
|
5592
|
+
// `retry_guidance` tells the caller how to settle it; keep the receipt intact
|
|
5593
|
+
// and never redispatch from here.
|
|
5594
|
+
if (isPanelQueueUncertainty(parsed))
|
|
5595
|
+
return null;
|
|
5576
5596
|
const topError = parsed.error;
|
|
5577
5597
|
const nodeErrors = parsed.node_errors;
|
|
5578
5598
|
const rejected = hasTopLevelError(topError) || hasNodeErrors(nodeErrors) || parsed.queued === false;
|
|
@@ -5687,8 +5707,8 @@ function isRetryableRunToNodeStampRace(res, rejection) {
|
|
|
5687
5707
|
return false; // unreadable reply — an unknown, not a clean queue
|
|
5688
5708
|
if (parsed.queued === true)
|
|
5689
5709
|
return false; // observed queue evidence vetoes prose
|
|
5690
|
-
if (
|
|
5691
|
-
return false;
|
|
5710
|
+
if (acceptedPromptIds(parsed).length > 0)
|
|
5711
|
+
return false; // any receipt vetoes retry
|
|
5692
5712
|
const text = toolResultText(rejection);
|
|
5693
5713
|
return (/workflow graph CHANGED after the run was queued/i.test(text) &&
|
|
5694
5714
|
/Nothing was queued/i.test(text));
|
|
@@ -11160,6 +11180,22 @@ function queueRunReceiptNote(promptId) {
|
|
|
11160
11180
|
`Nothing was dispatched a second time. Do NOT re-run: a second panel_run would bill/queue ` +
|
|
11161
11181
|
`another render behind the one already running.`);
|
|
11162
11182
|
}
|
|
11183
|
+
/**
|
|
11184
|
+
* #2143 — a normal Panel timeout receipt is neither a confirmed queue nor a
|
|
11185
|
+
* refusal. Keep its retry guidance in the original JSON and add only the
|
|
11186
|
+
* local fact that this handler did not dispatch a second run.
|
|
11187
|
+
*/
|
|
11188
|
+
function panelQueueUncertaintyNote(queuedPromptIds) {
|
|
11189
|
+
if (queuedPromptIds.length > 0) {
|
|
11190
|
+
return (`\n\n[UNCERTAIN] The Panel confirmed these prompt id(s) left its queue path: ` +
|
|
11191
|
+
`${queuedPromptIds.join(", ")}. Completion tickets were opened for them. ` +
|
|
11192
|
+
`Any remaining request(s) are still uncertain; follow the Panel's retry_guidance above ` +
|
|
11193
|
+
`before retrying. No second panel_run was dispatched.`);
|
|
11194
|
+
}
|
|
11195
|
+
return (`\n\n[UNCERTAIN] The Panel could not determine whether this run entered ComfyUI's queue. ` +
|
|
11196
|
+
`This is not a confirmed refusal, and no completion ticket can be opened without a prompt id. ` +
|
|
11197
|
+
`Follow the Panel's retry_guidance above before retrying. No second panel_run was dispatched.`);
|
|
11198
|
+
}
|
|
11163
11199
|
async function pollLateAskReply(bridge, askId, timing, hardDeadline) {
|
|
11164
11200
|
const take = bridge
|
|
11165
11201
|
.takeLateAskReply;
|
|
@@ -13414,7 +13450,7 @@ export function buildPanelToolDefs() {
|
|
|
13414
13450
|
// "does NOT match any run you queued … its origin is UNDETERMINED" — for
|
|
13415
13451
|
// runs the agent had just queued itself. Ticket all of them.
|
|
13416
13452
|
const queuedIds = acceptedPromptIds(runReply);
|
|
13417
|
-
const
|
|
13453
|
+
const panelQueueUncertain = isPanelQueueUncertainty(runReply);
|
|
13418
13454
|
// #944: a run ComfyUI accepted while dropping some outputs reaches here
|
|
13419
13455
|
// (a minted prompt id outranks the rejection signals). Say which outputs
|
|
13420
13456
|
// were dropped, or the caller waits for files that will never be written.
|
|
@@ -13435,8 +13471,11 @@ export function buildPanelToolDefs() {
|
|
|
13435
13471
|
`and this dispatch stacked a duplicate.`
|
|
13436
13472
|
: "";
|
|
13437
13473
|
// markSelfQueued with NO id still stamps the recent-self-queue timestamp,
|
|
13438
|
-
// so the id-less
|
|
13439
|
-
|
|
13474
|
+
// so both the id-less genuine queue and the Panel's explicit uncertainty
|
|
13475
|
+
// receipt must call it exactly once (#559/#2143). The latter must not be
|
|
13476
|
+
// mistaken for a definite queue, but it is still unsafe to immediately
|
|
13477
|
+
// redispatch a request that the Panel says left its tab.
|
|
13478
|
+
if (queuedIds.length === 0 || panelQueueUncertain)
|
|
13440
13479
|
QueueMonitor.markSelfQueued(null);
|
|
13441
13480
|
for (const id of queuedIds)
|
|
13442
13481
|
QueueMonitor.markSelfQueued(id);
|
|
@@ -13460,14 +13499,16 @@ export function buildPanelToolDefs() {
|
|
|
13460
13499
|
// anti-poll note is allowed to make — true only if at least one run can
|
|
13461
13500
|
// actually be correlated back.
|
|
13462
13501
|
const ticketedPromptIds = [];
|
|
13463
|
-
const correlatable = queuedIds.length === 0
|
|
13464
|
-
?
|
|
13465
|
-
: queuedIds.
|
|
13466
|
-
|
|
13467
|
-
|
|
13468
|
-
|
|
13469
|
-
|
|
13470
|
-
|
|
13502
|
+
const correlatable = panelQueueUncertain && queuedIds.length === 0
|
|
13503
|
+
? false
|
|
13504
|
+
: queuedIds.length === 0
|
|
13505
|
+
? RunCompletions.openRun(undefined, ticketOpts)
|
|
13506
|
+
: queuedIds.map((id) => {
|
|
13507
|
+
const opened = RunCompletions.openRun(id, ticketOpts);
|
|
13508
|
+
if (opened)
|
|
13509
|
+
ticketedPromptIds.push(id);
|
|
13510
|
+
return opened;
|
|
13511
|
+
}).some(Boolean);
|
|
13471
13512
|
// A fast QueueMonitor observation can be held before the panel reply
|
|
13472
13513
|
// returns. Promote that in-memory arm immediately after its journal
|
|
13473
13514
|
// ticket opens, so a completion burst cannot evict this owed run.
|
|
@@ -13521,10 +13562,12 @@ export function buildPanelToolDefs() {
|
|
|
13521
13562
|
const fallbackTail = queuedIds.length === 1
|
|
13522
13563
|
? ""
|
|
13523
13564
|
: ` (this run queued ${queuedIds.length} prompts, so the check is the queue as a whole; get_history settles the outcome of any that are no longer in flight)`;
|
|
13524
|
-
const note =
|
|
13525
|
-
?
|
|
13526
|
-
|
|
13527
|
-
|
|
13565
|
+
const note = panelQueueUncertain
|
|
13566
|
+
? panelQueueUncertaintyNote(ticketedPromptIds)
|
|
13567
|
+
: correlatable
|
|
13568
|
+
? "\n\n[IMPORTANT] You will be notified automatically with the output image(s)/video when the render finishes — do NOT poll queue (action:\"list\"), get_history, or get_image (action:\"list_outputs\"). Just end your turn now and wait for the result to be delivered to you." +
|
|
13569
|
+
`\n[FALLBACK] That notification is journaled and replayed if an agent is not there to take it, and the orchestrator will fill one in from ComfyUI itself — its execution event or its history record — if the panel never reports the finish. But it cannot be GUARANTEED, so do not wait forever on it. If nothing has arrived LONG after this render should have finished (roughly twice the time you expect it to take), make ONE check with ${fallbackCheck} instead of idling indefinitely${fallbackTail}. One check, not a loop — and not before then.`
|
|
13570
|
+
: "\n\n[IMPORTANT] The run was queued, but the panel reported NO prompt id for it, so a completion event CANNOT be correlated back to this run — its outcome will be reported to you as UNDETERMINED. Do NOT simply idle and wait indefinitely: end your turn, and if nothing arrives, confirm the outcome with get_history (action:\"list\") before acting on it.";
|
|
13528
13571
|
// Backpressure note. A backlog is only alarming when it's a job we did NOT
|
|
13529
13572
|
// queue (possibly foreign/stuck). Deliberately batching renders — a sweep,
|
|
13530
13573
|
// a multi-variant comparison — is a NORMAL workflow, so a queue made of our
|