comfyui-mcp 0.50.94 → 0.50.95
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.
|
@@ -149,6 +149,55 @@ function fail(err) {
|
|
|
149
149
|
const msg = err instanceof Error ? err.message : String(err);
|
|
150
150
|
return { content: [{ type: "text", text: `Error: ${msg}` }], isError: true };
|
|
151
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* #971 — the AMBIGUOUS-rebind refusal, worded so it can be acted on.
|
|
154
|
+
*
|
|
155
|
+
* Refusing here is right (#474: with 2+ live tabs the rebind is ambiguous, so the
|
|
156
|
+
* user picks rather than us guessing). What was wrong is what it refused WITH:
|
|
157
|
+
* rebindToActiveTab propagates the bridge's raw resolve error, which ends
|
|
158
|
+
* "— pass tab_id". This tool has no tab_id parameter (schema: mode/path/filename)
|
|
159
|
+
* and #754 made these schemas strict, so an unknown key is a hard validation error
|
|
160
|
+
* rather than a no-op. Since panel_open_workflow's own refusal names THIS tool as
|
|
161
|
+
* the way out, an instruction that cannot be followed closes the loop and the
|
|
162
|
+
* session stays wedged with no exit — the reporter's wedge.
|
|
163
|
+
*
|
|
164
|
+
* The action named here is the one that actually works, which is NOT the obvious one.
|
|
165
|
+
* UiBridge.setLastActiveTab is documented as the ONLY writer of lastActiveTabId and
|
|
166
|
+
* fires on `msg.type === "user_message"` (ui-bridge.ts) — a tab becomes last-active
|
|
167
|
+
* when a MESSAGE IS SENT from its Agent panel, not when the browser tab is focused or
|
|
168
|
+
* clicked. "Switch to the tab you want" (which panel_reload's sibling message says)
|
|
169
|
+
* would leave the state unchanged and send the user round the loop again.
|
|
170
|
+
* Name the connected tabs too, so the user knows what they are choosing among.
|
|
171
|
+
*/
|
|
172
|
+
function ambiguousRebindGuidance(ctx, err) {
|
|
173
|
+
const raw = err instanceof Error ? err.message : String(err ?? "");
|
|
174
|
+
// Only reword the ambiguity refusal — every other failure keeps its own words.
|
|
175
|
+
if (!/multiple|last active|pass tab_id/i.test(raw))
|
|
176
|
+
return raw;
|
|
177
|
+
let listed = "";
|
|
178
|
+
try {
|
|
179
|
+
const live = typeof ctx.bridge.tabs === "function" ? ctx.bridge.tabs() : undefined;
|
|
180
|
+
if (Array.isArray(live)) {
|
|
181
|
+
// isHeadless THROUGH the bridge — a detached reference loses `this` and throws
|
|
182
|
+
// on `this.conns` (#478). A headless viewer is not a pickable canvas tab.
|
|
183
|
+
const isHeadlessTab = (id) => typeof ctx.bridge.isHeadless === "function" && ctx.bridge.isHeadless(id);
|
|
184
|
+
const names = live
|
|
185
|
+
.filter((t) => !isHeadlessTab(t.tab_id))
|
|
186
|
+
.map((t) => (t.title ? `${shortTabId(t.tab_id)} ("${t.title}")` : shortTabId(t.tab_id)));
|
|
187
|
+
if (names.length)
|
|
188
|
+
listed = ` Connected ComfyUI tabs: ${names.join(", ")}.`;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
catch {
|
|
192
|
+
// Enumeration is best-effort; the instruction below stands without the list.
|
|
193
|
+
}
|
|
194
|
+
return ("Several ComfyUI tabs are connected and none is marked active, so this session cannot " +
|
|
195
|
+
"tell which one to follow — and this tool takes no tab_id to disambiguate with." +
|
|
196
|
+
`${listed} A tab becomes the active one when a message is SENT from its Agent panel ` +
|
|
197
|
+
"(focusing or clicking the browser tab does not do it), so ask the user to send any " +
|
|
198
|
+
"message from the Agent panel in the ComfyUI tab they want you working in, then call " +
|
|
199
|
+
'panel_set_workflow_target({mode:"current"}) again. Nothing was rebound.');
|
|
200
|
+
}
|
|
152
201
|
// ── Honest secret-save reporting (#826) ─────────────────────────────────────
|
|
153
202
|
// `panel_request_secret` used to answer "the comfyui tools respawn with it as
|
|
154
203
|
// soon as this turn ends" unconditionally — a claim about a FUTURE event nothing
|
|
@@ -5524,8 +5573,9 @@ function desktopCanvasRedirect(ctx, label) {
|
|
|
5524
5573
|
return {
|
|
5525
5574
|
error: `${label} needs an open ComfyUI desktop panel canvas, but this session is bound to ` +
|
|
5526
5575
|
`a canvas-less (mobile/remote) client and multiple desktop tabs are open — it can't ` +
|
|
5527
|
-
`pick one automatically.
|
|
5528
|
-
`
|
|
5576
|
+
`pick one automatically. Ask the user to send a message from the Agent panel in the ` +
|
|
5577
|
+
`ComfyUI tab they want (that — not focusing the tab — is what marks it active), ` +
|
|
5578
|
+
`rebind with panel_set_workflow_target({mode:"current"}), then retry.`,
|
|
5529
5579
|
};
|
|
5530
5580
|
}
|
|
5531
5581
|
/** Dispatch a command to a SPECIFIC tab id (the #624 desktop-canvas redirect target)
|
|
@@ -7209,9 +7259,10 @@ export function buildPanelToolDefs() {
|
|
|
7209
7259
|
if (!reachable) {
|
|
7210
7260
|
return fail("This conversation's current turn is pinned to a tab that is no longer " +
|
|
7211
7261
|
"reachable (it disconnected or its origin is ambiguous), so the reload " +
|
|
7212
|
-
"frame has nowhere safe to go.
|
|
7213
|
-
|
|
7214
|
-
|
|
7262
|
+
"frame has nowhere safe to go. Ask the user to send a message from the Agent " +
|
|
7263
|
+
"panel in the ComfyUI tab they want (that — not focusing the tab — is what " +
|
|
7264
|
+
'marks it active), call panel_set_workflow_target({mode:"current"}) to ' +
|
|
7265
|
+
"re-bind this session onto it, then retry panel_reload.");
|
|
7215
7266
|
}
|
|
7216
7267
|
}
|
|
7217
7268
|
else if (ctx.rebindToActiveTab) {
|
|
@@ -7235,8 +7286,10 @@ export function buildPanelToolDefs() {
|
|
|
7235
7286
|
: live;
|
|
7236
7287
|
if (orphaned && Array.isArray(interactive) && interactive.length > 1) {
|
|
7237
7288
|
return fail("This session's ComfyUI tab was replaced and multiple tabs are now open — " +
|
|
7238
|
-
"can't safely pick one.
|
|
7239
|
-
|
|
7289
|
+
"can't safely pick one. Ask the user to send a message from the Agent panel " +
|
|
7290
|
+
"in the tab they want (that — not focusing the tab — is what marks it " +
|
|
7291
|
+
'active), then call panel_set_workflow_target({mode:"current"}) before ' +
|
|
7292
|
+
"panel_reload.");
|
|
7240
7293
|
}
|
|
7241
7294
|
try {
|
|
7242
7295
|
ctx.rebindToActiveTab();
|
|
@@ -7991,7 +8044,7 @@ export function buildPanelToolDefs() {
|
|
|
7991
8044
|
!/multiple|last active|pass tab_id/i.test(msg);
|
|
7992
8045
|
}
|
|
7993
8046
|
if (!noTabsConnected)
|
|
7994
|
-
return fail(err);
|
|
8047
|
+
return fail(ambiguousRebindGuidance(ctx, err));
|
|
7995
8048
|
deferredBind = true;
|
|
7996
8049
|
rebindNote =
|
|
7997
8050
|
" No panel tab is connected yet — cleared the stale binding; this session will " +
|