comfyui-mcp 0.51.11 → 0.51.12
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 { createSdkMcpServer, tool } from "@anthropic-ai/claude-agent-sdk";
|
|
|
38
38
|
import { parse as parseYaml } from "yaml";
|
|
39
39
|
import { conversationOfScopeAddress, isScopeAddress, shortTabId } from "../services/session-scope.js";
|
|
40
40
|
import { NODE_ID_MESSAGE, NODE_ID_PATTERN, normalizeNodeId } from "./node-id.js";
|
|
41
|
+
import { clearSwitchHold, describeSwitchHold, recordSwitchHold, successProvesSwitchCleared, } from "./switch-hold.js";
|
|
41
42
|
import { NO_ORIGIN_REMEDY } from "./fence-refusal.js";
|
|
42
43
|
/** #884 — journal TICKETS (run completions #468, ask answers #486) must be
|
|
43
44
|
* keyed by the REAL tab a run/card was routed to: the panel reports back under
|
|
@@ -5234,7 +5235,14 @@ export function makePanelToolCtx(bridge, tabId, workflowTargets) {
|
|
|
5234
5235
|
await awaitReachable();
|
|
5235
5236
|
}
|
|
5236
5237
|
ensureReachable();
|
|
5237
|
-
|
|
5238
|
+
const firstTry = ok(await sendRouted(cmd, timeoutMs, observeRid));
|
|
5239
|
+
// panel#1097 — a guard-domain command that SUCCEEDS is the evidence that the
|
|
5240
|
+
// switch is over, whichever attempt lands it. Without this an ordinary
|
|
5241
|
+
// first-attempt success left the old run in place, and a later unrelated
|
|
5242
|
+
// switch inherited its age and was announced as stuck at once (codex r4).
|
|
5243
|
+
if (successProvesSwitchCleared(cmd.cmd))
|
|
5244
|
+
clearSwitchHold(ctx.tabId);
|
|
5245
|
+
return firstTry;
|
|
5238
5246
|
}
|
|
5239
5247
|
catch (err) {
|
|
5240
5248
|
// Post-reconnect retry-once: a reboot/free_vram/reconnect can drop the tab's
|
|
@@ -5248,10 +5256,30 @@ export function makePanelToolCtx(bridge, tabId, workflowTargets) {
|
|
|
5248
5256
|
// is what retrySettleMs already waits. Still gated on RETRY-SAFE commands,
|
|
5249
5257
|
// so a mutation is never re-issued on our own initiative.
|
|
5250
5258
|
if (isRetrySafeCmd(cmd) && (isTransientReconnectError(err) || isWorkflowSwitchGuardRefusal(err))) {
|
|
5259
|
+
// panel#1097 — declared out here so the refusal branch below can see it,
|
|
5260
|
+
// and REASSIGNED after ensureReachable so it names the tab the command is
|
|
5261
|
+
// actually dispatched on. Reading it before the rebind attributed a refusal
|
|
5262
|
+
// from B to A; reading it after the await let a later rebind move it again
|
|
5263
|
+
// (codex rounds 1 and 2).
|
|
5264
|
+
let holdTab = ctx.tabId;
|
|
5251
5265
|
try {
|
|
5252
5266
|
await sleep(retrySettleMs());
|
|
5253
5267
|
ensureReachable(); // rebinds a current-mode session onto the reconnected tab
|
|
5254
|
-
|
|
5268
|
+
holdTab = ctx.tabId;
|
|
5269
|
+
const retried = ok(await sendRouted(cmd, timeoutMs, observeRid));
|
|
5270
|
+
// Cleared HERE and nowhere else, and only when the failure this retried
|
|
5271
|
+
// was a SWITCH refusal. Clearing on every routed success let an unguarded
|
|
5272
|
+
// status read wipe the evidence while graph commands stayed refused
|
|
5273
|
+
// (codex round 2); clearing after a transient-reconnect retry does the
|
|
5274
|
+
// same thing one step removed, because reconnecting proves nothing about
|
|
5275
|
+
// whether the switch cleared (codex round 3).
|
|
5276
|
+
// Same rule on the retry path. A transient-RECONNECT retry that succeeds
|
|
5277
|
+
// proves nothing about the switch (codex r3), so the command still has to
|
|
5278
|
+
// be one the guard would have refused.
|
|
5279
|
+
if (isWorkflowSwitchGuardRefusal(err) && successProvesSwitchCleared(cmd.cmd)) {
|
|
5280
|
+
clearSwitchHold(holdTab);
|
|
5281
|
+
}
|
|
5282
|
+
return retried;
|
|
5255
5283
|
}
|
|
5256
5284
|
catch (err2) {
|
|
5257
5285
|
// #1027 — a switch STILL in progress is not a reconnect, and saying so
|
|
@@ -5259,13 +5287,18 @@ export function makePanelToolCtx(bridge, tabId, workflowTargets) {
|
|
|
5259
5287
|
// it is simply mid-switch. Name the actual state and the actual wait.
|
|
5260
5288
|
if (isWorkflowSwitchGuardRefusal(err2)) {
|
|
5261
5289
|
const name = typeof cmd.cmd === "string" ? cmd.cmd : "panel command";
|
|
5290
|
+
// panel#1097 — time the RUN of these refusals. "Simply retry" is right
|
|
5291
|
+
// for the fraction of a second this normally lasts and wrong for a
|
|
5292
|
+
// switch held open by a dialog, and the two were indistinguishable.
|
|
5293
|
+
const held = describeSwitchHold(recordSwitchHold(holdTab));
|
|
5262
5294
|
return fail(`${name} was NOT applied — nothing changed. The panel is still switching or ` +
|
|
5263
5295
|
`reloading the workflow on the canvas, which it refuses commands during so a ` +
|
|
5264
5296
|
`command cannot land on the wrong graph. The tab is connected and this is not a ` +
|
|
5265
5297
|
`reconnect: it normally clears in well under a second, so simply retry. If a ` +
|
|
5266
5298
|
`switch appears stuck, check the canvas — a load dialog or an unsaved-changes ` +
|
|
5267
5299
|
`prompt can hold it open awaiting the user. ` +
|
|
5268
|
-
`(${err2 instanceof Error ? err2.message : String(err2)})`
|
|
5300
|
+
`(${err2 instanceof Error ? err2.message : String(err2)})` +
|
|
5301
|
+
held);
|
|
5269
5302
|
}
|
|
5270
5303
|
// The retry also failed — surface an actionable reconnecting status rather
|
|
5271
5304
|
// than a bare transport error (#332), while still failing honestly.
|