comfyui-mcp 0.51.26 → 0.51.28
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.
|
@@ -3218,6 +3218,49 @@ WHY THIS READ WAS NEEDED AT ALL: this session's panel is ${v.version}, and a ` +
|
|
|
3218
3218
|
* happening here.
|
|
3219
3219
|
*/
|
|
3220
3220
|
const FENCE_CORROBORATION_RECHECK_STEPS_MS = [400, 900, 1600];
|
|
3221
|
+
/**
|
|
3222
|
+
* #1478 — NAME THE CAUSE OF A MISMATCH THE LOAD MAY HAVE CREATED.
|
|
3223
|
+
*
|
|
3224
|
+
* An API-format `graph_load` can re-mint the canvas workflow instance, which leaves this
|
|
3225
|
+
* session's fence naming the old one — so the very next `panel_graph_outline` is refused
|
|
3226
|
+
* with `workflow instance mismatch`. The reporter hit that twice, deterministically. The
|
|
3227
|
+
* refusal then says "NO PANEL COMMAND CLAIMED IT", pointing at "the user switched tabs"
|
|
3228
|
+
* when a panel command one call earlier is the actual cause.
|
|
3229
|
+
*
|
|
3230
|
+
* WHAT THIS DELIBERATELY DOES NOT DO — and four review rounds are the reason:
|
|
3231
|
+
*
|
|
3232
|
+
* 1. It does NOT auto-repair the fence. The obvious fix runs the same re-derivation the
|
|
3233
|
+
* documented recovery runs, and that adopts WHATEVER IS ACTIVE NOW with no tie to the
|
|
3234
|
+
* load: a user switching canvases in the window would stamp the session to a different
|
|
3235
|
+
* workflow and the next edit would land on the wrong graph. `panel_set_workflow_target`
|
|
3236
|
+
* is sound doing this only because the user explicitly asked to follow what is live.
|
|
3237
|
+
* 2. It does NOT claim the fence IS stale. Every categorical version of that sentence was
|
|
3238
|
+
* falsified: a UI-format load with an active workflow passes `__cmcpKeepInstance: true`
|
|
3239
|
+
* and preserves the instance outright; and a second API load into the same
|
|
3240
|
+
* already-active `graph_load.json` workflow reuses that object, so its uuid — which is
|
|
3241
|
+
* object-keyed — does not change either. The reply carries nothing that separates
|
|
3242
|
+
* "re-minted" from "reused", so asserting staleness is a guess dressed as a fact.
|
|
3243
|
+
*
|
|
3244
|
+
* So it states the CONDITIONAL, which is true on every path: this kind of load can move
|
|
3245
|
+
* the instance, here is the symptom, here is the cause, here is the one call that clears
|
|
3246
|
+
* it. A reader who is not refused ignores it; a reader who is refused stops hunting a tab
|
|
3247
|
+
* switch that never happened.
|
|
3248
|
+
*
|
|
3249
|
+
* The categorical version needs the panel's help: give `graph_load`'s reply a
|
|
3250
|
+
* `workflow_uuid`, as #762/#800 did for `workflow_new` / `workflow_save`, and the load can
|
|
3251
|
+
* then compare it against the fence and say exactly what happened — or claim the identity
|
|
3252
|
+
* it created outright, which is race-proof and refusal-proof and is why those two work
|
|
3253
|
+
* that way.
|
|
3254
|
+
*/
|
|
3255
|
+
function noteStaleFenceAfterLoad() {
|
|
3256
|
+
return (`
|
|
3257
|
+
|
|
3258
|
+
NOTE: an API-format load CAN re-mint the canvas workflow instance. If your next ` +
|
|
3259
|
+
`graph command is refused with "workflow instance mismatch", that is why — the cause is ` +
|
|
3260
|
+
`this load, NOT the user switching tabs (the refusal's own text suggests otherwise). ` +
|
|
3261
|
+
`Clear it with panel_set_workflow_target({mode:"current"}), which re-derives the fence ` +
|
|
3262
|
+
`from the live canvas, then retry. If the next command is not refused, nothing needs doing.`);
|
|
3263
|
+
}
|
|
3221
3264
|
async function rebindWorkflowFence(ctx) {
|
|
3222
3265
|
const tabAtStart = ctx.tabId;
|
|
3223
3266
|
let before = currentWorkflowFence(ctx);
|
|
@@ -7509,7 +7552,25 @@ export function buildPanelToolDefs() {
|
|
|
7509
7552
|
throw new Error("Provide one of `pack` (a bundled pack name), `path` (a workflow .json on disk), or `graph` (a UI workflow).");
|
|
7510
7553
|
}
|
|
7511
7554
|
// Generous timeout — loading a large graph onto the live canvas can take a moment.
|
|
7512
|
-
|
|
7555
|
+
const loaded = await ctx.call({ cmd: "graph_load", graph: data }, 30000);
|
|
7556
|
+
if (loaded.isError)
|
|
7557
|
+
return loaded;
|
|
7558
|
+
// Keyed on the reply SAYING the graph was replaced, not merely on the call not
|
|
7559
|
+
// erroring (codex r2). A non-error envelope that reports `loaded:false` did not
|
|
7560
|
+
// replace anything, and telling that caller their fence is stale would be a
|
|
7561
|
+
// fabricated consequence of a load that never happened — the same
|
|
7562
|
+
// unmeasured-claim defect this note exists to remove.
|
|
7563
|
+
// ONLY THE API-FORMAT LOAD MINTS A NEW INSTANCE (codex r3, checked in the panel).
|
|
7564
|
+
// The UI-format path passes `__cmcpKeepInstance: true` whenever a workflow is
|
|
7565
|
+
// active, deliberately PRESERVING the instance so the agent's own follow-up
|
|
7566
|
+
// commands are not rejected — so a note claiming the fence went stale would be
|
|
7567
|
+
// false for the commonest load. The API path (`app.loadApiJson`) passes no such
|
|
7568
|
+
// option and does re-mint, and it is the path the reporter hit: their reply reads
|
|
7569
|
+
// `format:"api"`. That field is present only on this branch, which makes it the
|
|
7570
|
+
// signal rather than an inference.
|
|
7571
|
+
const reply = parseToolResultJson(loaded);
|
|
7572
|
+
const remintedInstance = reply?.loaded === true && reply?.format === "api";
|
|
7573
|
+
return remintedInstance ? appendNote(loaded, noteStaleFenceAfterLoad()) : loaded;
|
|
7513
7574
|
}
|
|
7514
7575
|
catch (err) {
|
|
7515
7576
|
return fail(err);
|