comfyui-mcp 0.52.33 → 0.52.34
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.
|
@@ -60,6 +60,35 @@ import { NO_ORIGIN_REMEDY } from "./fence-refusal.js";
|
|
|
60
60
|
* labeled "foreign" and boundary sweeps could never close the ticket (codex
|
|
61
61
|
* round 3, P1). Resolves the scope to the active tab; a real-tab ctx is
|
|
62
62
|
* returned unchanged. */
|
|
63
|
+
/**
|
|
64
|
+
* #1917 — the CANONICAL tab id a SCOPE-addressed session's commands are dispatched
|
|
65
|
+
* to right now: the in-flight turn's routing pin, resolved onward through any
|
|
66
|
+
* same-socket migration alias, else the active-tab fallback when no turn is
|
|
67
|
+
* pinned. Undefined when nothing resolves — and, deliberately, for a REAL-TAB ctx,
|
|
68
|
+
* which routes by its own id and has no second selector to disagree with.
|
|
69
|
+
*
|
|
70
|
+
* Canonical on purpose: `resolveSharedTabId` answers with `conn.tabId`, the same
|
|
71
|
+
* value `resolveActiveScopeTab` answers with, so the two can be compared for
|
|
72
|
+
* "different TAB" rather than "different id string". A pin naming a retired
|
|
73
|
+
* `wf:<route>:<path>` id that still reaches the same live socket resolves to that
|
|
74
|
+
* socket's current canonical id and is therefore NOT a disagreement.
|
|
75
|
+
*
|
|
76
|
+
* Never throws: an unresolvable pin is the bridge's own loud failure at dispatch
|
|
77
|
+
* time, and a reporting helper must not turn it into a different one here.
|
|
78
|
+
*/
|
|
79
|
+
function scopeRoutedTabId(ctx) {
|
|
80
|
+
if (!isScopeAddress(ctx.tabId))
|
|
81
|
+
return undefined;
|
|
82
|
+
const b = ctx.bridge;
|
|
83
|
+
if (typeof b.resolveSharedTabId !== "function")
|
|
84
|
+
return undefined;
|
|
85
|
+
try {
|
|
86
|
+
return b.resolveSharedTabId(ctx.tabId);
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
63
92
|
function journalTabFor(ctx) {
|
|
64
93
|
if (!isScopeAddress(ctx.tabId))
|
|
65
94
|
return ctx.tabId;
|
|
@@ -12423,6 +12452,53 @@ export function buildPanelToolDefs() {
|
|
|
12423
12452
|
// made only on the evidence that supports it; without that evidence the reply
|
|
12424
12453
|
// says what IS true (the pin is set and acts as a GUARD) and hands back the
|
|
12425
12454
|
// cheap read that settles it.
|
|
12455
|
+
//
|
|
12456
|
+
// #1917 — the SAME rule for the `mode:"current"` arm, which panel#1529's fix
|
|
12457
|
+
// deliberately did not take. "Following the user's current workflow tab." is
|
|
12458
|
+
// also a claim about ROUTING, and it was likewise unconditional. It is FALSE
|
|
12459
|
+
// whenever this conversation's in-flight turn pin is holding routing on a
|
|
12460
|
+
// different tab: `rebindToActiveTab` short-circuits for a scope ctx whose pin
|
|
12461
|
+
// still reaches a live tab (#884 — a live pin is never displaced) and returns
|
|
12462
|
+
// `{rebound:false}` with no `repinRefusal` at all, so nothing in the reply
|
|
12463
|
+
// mentioned the pin. Measured on clean main over a real bridge: with the pin
|
|
12464
|
+
// on the tab showing Basic_V37 and the active-scope resolution naming the tab
|
|
12465
|
+
// showing PHOTO, this call answered «Following the user's current workflow
|
|
12466
|
+
// tab.» with `graph_binding:"bound"`, and the next `panel_graph_outline` AND
|
|
12467
|
+
// the next `panel_remove_node` were both dispatched to Basic_V37.
|
|
12468
|
+
//
|
|
12469
|
+
// The pin is NOT moved to make the sentence true — that is #884's P0, and
|
|
12470
|
+
// widening "displace" from dead-or-ambiguous to dead-or-ambiguous-or-different
|
|
12471
|
+
// would re-aim an in-flight conversation's mutations at a tab it never
|
|
12472
|
+
// addressed. What changes is the CLAIM: when two selectors name different
|
|
12473
|
+
// tabs, say so and name both, rather than silently reporting one of them.
|
|
12474
|
+
const routedTab = scopeRoutedTabId(ctx);
|
|
12475
|
+
const activeScopeTab = typeof ctx.bridge.resolveActiveScopeTab === "function"
|
|
12476
|
+
? ctx.bridge.resolveActiveScopeTab()
|
|
12477
|
+
: undefined;
|
|
12478
|
+
// Compared as CANONICAL connection ids on both sides (resolveSharedTabId and
|
|
12479
|
+
// resolveActiveScopeTab both answer with `conn.tabId`), so a pin that merely
|
|
12480
|
+
// names a RETIRED per-workflow route id but still resolves onto the same live
|
|
12481
|
+
// socket does not read as a split — only a genuinely different tab does.
|
|
12482
|
+
const turnPinRoutesElsewhere = mode === "current" &&
|
|
12483
|
+
!currentModeTurnRepinned &&
|
|
12484
|
+
isScopeAddress(ctx.tabId) &&
|
|
12485
|
+
typeof routedTab === "string" &&
|
|
12486
|
+
typeof activeScopeTab === "string" &&
|
|
12487
|
+
routedTab !== activeScopeTab
|
|
12488
|
+
? { routedTab, activeScopeTab }
|
|
12489
|
+
: undefined;
|
|
12490
|
+
// panel#1529's `pin_verified_active` rule, applied to the routing half: the
|
|
12491
|
+
// same verdict the note carries, MACHINE-READABLE, so an agent never has to
|
|
12492
|
+
// read "the two selectors disagree" out of prose. `turn_routing:"repinned"`
|
|
12493
|
+
// and `"pinned_elsewhere"` are mutually exclusive by construction — the
|
|
12494
|
+
// predicate above requires `!currentModeTurnRepinned`.
|
|
12495
|
+
const turnRoutingSplitFields = turnPinRoutesElsewhere
|
|
12496
|
+
? {
|
|
12497
|
+
turn_routing: "pinned_elsewhere",
|
|
12498
|
+
turn_routing_tab: turnPinRoutesElsewhere.routedTab,
|
|
12499
|
+
current_would_route_to: turnPinRoutesElsewhere.activeScopeTab,
|
|
12500
|
+
}
|
|
12501
|
+
: {};
|
|
12426
12502
|
const hint = target.mode === "pinned"
|
|
12427
12503
|
? pinVerifiedActive
|
|
12428
12504
|
? `Pinned to "${target.filename ?? target.path}". Graph tools will target that workflow without switching the user's view.`
|
|
@@ -12433,7 +12509,24 @@ export function buildPanelToolDefs() {
|
|
|
12433
12509
|
// be a confident wrong diagnosis; what is true in all three is that the
|
|
12434
12510
|
// check did not happen.
|
|
12435
12511
|
: `Pinned to "${target.filename ?? target.path}" — but NOT CONFIRMED: the live canvas could not be read back to check this pin against it, so this call does NOT establish that graph tools will reach that workflow. The pin travels on graph commands as a GUARD: if the active canvas is a different workflow, the next graph call FAILS with a workflow mismatch rather than editing it. Settle it with one cheap read — panel_graph_outline — before relying on this.`
|
|
12436
|
-
:
|
|
12512
|
+
: turnPinRoutesElsewhere
|
|
12513
|
+
? `The workflow target is now mode:"current" — but graph tools will NOT ` +
|
|
12514
|
+
`follow the tab this session would otherwise resolve to. This ` +
|
|
12515
|
+
`conversation's IN-FLIGHT TURN is pinned to tab ` +
|
|
12516
|
+
`${shortTabId(turnPinRoutesElsewhere.routedTab)}, and that pin was NOT ` +
|
|
12517
|
+
`displaced: a pin that still reaches a live tab of this conversation is ` +
|
|
12518
|
+
`never displaced, however explicit the request (#884). So every graph ` +
|
|
12519
|
+
`command — READS AND MUTATIONS ALIKE — is dispatched to ` +
|
|
12520
|
+
`${shortTabId(turnPinRoutesElsewhere.routedTab)}, not to ` +
|
|
12521
|
+
`${shortTabId(turnPinRoutesElsewhere.activeScopeTab)}, which is where ` +
|
|
12522
|
+
`"current" would resolve. TWO SELECTORS NAME DIFFERENT TABS and this ` +
|
|
12523
|
+
`call moved neither, so do not read it as "graph tools now follow the ` +
|
|
12524
|
+
`user's current tab". WHAT TO DO: read the pinned tab first ` +
|
|
12525
|
+
`(panel_graph_outline) and work there if that is the workflow you mean; ` +
|
|
12526
|
+
`otherwise ask the user to send a message from the tab they want — the ` +
|
|
12527
|
+
`turn pin is released at the end of this turn and the next message's ` +
|
|
12528
|
+
`origin establishes routing. Retrying this tool will not move it.`
|
|
12529
|
+
: "Following the user's current workflow tab.";
|
|
12437
12530
|
// #803 — this used to END here for every mode:"current" call, with the
|
|
12438
12531
|
// unconditional "Following the user's current workflow tab." Reporters followed
|
|
12439
12532
|
// that as the documented recovery, read it as success, and stayed wedged. The
|
|
@@ -12646,6 +12739,7 @@ CHECKED FOR YOU: the graph read this message prescribes was just run, and it ` +
|
|
|
12646
12739
|
graph_binding: "bound",
|
|
12647
12740
|
...(fenceRebind ? { graph_binding_status: fenceRebind.status } : {}),
|
|
12648
12741
|
...(currentModeTurnRepinned ? { turn_routing: "repinned" } : {}),
|
|
12742
|
+
...turnRoutingSplitFields,
|
|
12649
12743
|
note: hint +
|
|
12650
12744
|
rebindNote +
|
|
12651
12745
|
` The graph binding was NOT re-derived (the panel's active reply could ` +
|
|
@@ -12691,6 +12785,7 @@ CHECKED FOR YOU: the graph read this message prescribes was just run, and it ` +
|
|
|
12691
12785
|
...(typeof scopeRepin === "string" || currentModeTurnRepinned
|
|
12692
12786
|
? { turn_routing: "repinned" }
|
|
12693
12787
|
: {}),
|
|
12788
|
+
...turnRoutingSplitFields,
|
|
12694
12789
|
note: hint + rebindNote + (fence?.note ?? "") + scopeRepinNote,
|
|
12695
12790
|
});
|
|
12696
12791
|
}),
|