comfyui-mcp 0.50.8 → 0.50.9
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.
|
@@ -621,6 +621,33 @@ function isTransientReconnectError(err) {
|
|
|
621
621
|
const msg = err instanceof Error ? err.message : String(err ?? "");
|
|
622
622
|
return /no connected tab|genuinely gone|is not open|Failed to fetch|Panel not reachable|ECONNRESET|socket hang up|premature close|other side closed|ECONNABORTED|EPIPE/i.test(msg);
|
|
623
623
|
}
|
|
624
|
+
/**
|
|
625
|
+
* #1027 — the panel's WORKFLOW-SWITCH critical section, which is retryable by
|
|
626
|
+
* construction and was not being retried.
|
|
627
|
+
*
|
|
628
|
+
* While a workflow switch/reload is in flight the panel refuses every graph and
|
|
629
|
+
* workflow executor rather than queueing it, because refusing cannot reorder or
|
|
630
|
+
* double-apply. Its own words:
|
|
631
|
+
*
|
|
632
|
+
* the panel is switching/refreshing "<key>" right now, so "<cmd>" was NOT
|
|
633
|
+
* applied — nothing changed. Retry in a moment.
|
|
634
|
+
*
|
|
635
|
+
* Two facts make this the safest retry in the file: the panel STATES nothing was
|
|
636
|
+
* applied, and the section lasts a fraction of a second. Yet none of that text
|
|
637
|
+
* matched the transient classifier, so a read issued right after
|
|
638
|
+
* panel_open_workflow surfaced the refusal to the agent instead of waiting the
|
|
639
|
+
* ~400ms the panel asked for. A reporter driving several tabs read-only hit it
|
|
640
|
+
* repeatedly, and read the resulting instance-mismatch errors as a wedge.
|
|
641
|
+
*
|
|
642
|
+
* TEXT-matched, deliberately, unlike #1001's typed marker: this error is minted
|
|
643
|
+
* in the browser and arrives over the wire, so there is no object identity to
|
|
644
|
+
* carry a symbol across. The phrasing is distinctive enough to key on, and the
|
|
645
|
+
* retry it enables is bounded to RETRY-SAFE commands either way.
|
|
646
|
+
*/
|
|
647
|
+
function isWorkflowSwitchGuardRefusal(err) {
|
|
648
|
+
const msg = err instanceof Error ? err.message : String(err ?? "");
|
|
649
|
+
return /panel is switching\/refreshing|panel is switching or reloading/i.test(msg);
|
|
650
|
+
}
|
|
624
651
|
let retrySettleMsOverride = null;
|
|
625
652
|
/** Short pause before the single post-drop retry, letting the replacement tab
|
|
626
653
|
* finish its reconnect hello so ensureReachable can resolve it. Test-overridable. */
|
|
@@ -3956,13 +3983,31 @@ export function makePanelToolCtx(bridge, tabId, workflowTargets) {
|
|
|
3956
3983
|
// For idempotent commands, settle briefly, rebind onto the now-live tab, and
|
|
3957
3984
|
// retry ONE time before surfacing an error (#278/#310/#332/#481). Mutating
|
|
3958
3985
|
// edits are excluded from RETRY_SAFE_CMDS, so they never double-apply.
|
|
3959
|
-
|
|
3986
|
+
// #1027 — the workflow-switch critical section is retried on the same path.
|
|
3987
|
+
// The panel refuses during it, states that nothing was applied, and asks
|
|
3988
|
+
// for a retry in a moment; the section lasts a fraction of a second, which
|
|
3989
|
+
// is what retrySettleMs already waits. Still gated on RETRY-SAFE commands,
|
|
3990
|
+
// so a mutation is never re-issued on our own initiative.
|
|
3991
|
+
if (isRetrySafeCmd(cmd) && (isTransientReconnectError(err) || isWorkflowSwitchGuardRefusal(err))) {
|
|
3960
3992
|
try {
|
|
3961
3993
|
await sleep(retrySettleMs());
|
|
3962
3994
|
ensureReachable(); // rebinds a current-mode session onto the reconnected tab
|
|
3963
3995
|
return ok(await sendRouted(cmd, timeoutMs, observeRid));
|
|
3964
3996
|
}
|
|
3965
3997
|
catch (err2) {
|
|
3998
|
+
// #1027 — a switch STILL in progress is not a reconnect, and saying so
|
|
3999
|
+
// would be the #1001 mistake again: the tab is connected and healthy,
|
|
4000
|
+
// it is simply mid-switch. Name the actual state and the actual wait.
|
|
4001
|
+
if (isWorkflowSwitchGuardRefusal(err2)) {
|
|
4002
|
+
const name = typeof cmd.cmd === "string" ? cmd.cmd : "panel command";
|
|
4003
|
+
return fail(`${name} was NOT applied — nothing changed. The panel is still switching or ` +
|
|
4004
|
+
`reloading the workflow on the canvas, which it refuses commands during so a ` +
|
|
4005
|
+
`command cannot land on the wrong graph. The tab is connected and this is not a ` +
|
|
4006
|
+
`reconnect: it normally clears in well under a second, so simply retry. If a ` +
|
|
4007
|
+
`switch appears stuck, check the canvas — a load dialog or an unsaved-changes ` +
|
|
4008
|
+
`prompt can hold it open awaiting the user. ` +
|
|
4009
|
+
`(${err2 instanceof Error ? err2.message : String(err2)})`);
|
|
4010
|
+
}
|
|
3966
4011
|
// The retry also failed — surface an actionable reconnecting status rather
|
|
3967
4012
|
// than a bare transport error (#332), while still failing honestly.
|
|
3968
4013
|
if (isTransientReconnectError(err2)) {
|