comfyui-mcp 0.52.55 → 0.52.57
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.
- package/dist/orchestrator/panel-tools.js +40 -1
- package/dist/orchestrator/panel-tools.js.map +1 -1
- package/dist/services/comfy-view-ref.js +18 -5
- package/dist/services/comfy-view-ref.js.map +1 -1
- package/dist/services/ui-bridge.js +109 -16
- package/dist/services/ui-bridge.js.map +1 -1
- package/package.json +1 -1
|
@@ -58,6 +58,26 @@ import { clearSwitchHold, describeSwitchHold, recordSwitchHold, successProvesSwi
|
|
|
58
58
|
import { NO_ORIGIN_REMEDY } from "./fence-refusal.js";
|
|
59
59
|
import { completeGetErrorsAudit } from "./get-errors-audit.js";
|
|
60
60
|
import { applyKitchenRecommendation, assessKitchen, assessKitchenGraph, extractLoaders, gatherKitchenStatus, kitchenProactiveHint, } from "../services/kitchen.js";
|
|
61
|
+
export function resolveClientKind(ctx) {
|
|
62
|
+
const b = ctx.bridge;
|
|
63
|
+
const routed = typeof b?.liveTabIdFor === "function" ? b.liveTabIdFor(ctx.tabId) : undefined;
|
|
64
|
+
// A live resolution wins. When nothing resolves: a CONCRETE id still names
|
|
65
|
+
// the mailbox recipient; a SCOPE address names nobody.
|
|
66
|
+
// `isScopeAddress` is typed `id is string`; its false branch would otherwise
|
|
67
|
+
// narrow a `string` tabId to `never` before `.length` is read (tsc TS2339).
|
|
68
|
+
const address = ctx.tabId;
|
|
69
|
+
const destination = typeof routed === "string" && routed.length > 0
|
|
70
|
+
? routed
|
|
71
|
+
: typeof address === "string" && address.length > 0 && !isScopeAddress(address)
|
|
72
|
+
? address
|
|
73
|
+
: undefined;
|
|
74
|
+
if (destination == null)
|
|
75
|
+
return { kind: "unroutable" };
|
|
76
|
+
if (typeof b?.isHeadless === "function" && b.isHeadless(destination)) {
|
|
77
|
+
return { kind: "headless", tabId: destination };
|
|
78
|
+
}
|
|
79
|
+
return { kind: "interactive", tabId: destination };
|
|
80
|
+
}
|
|
61
81
|
/** #884 — journal TICKETS (run completions #468, ask answers #486) must be
|
|
62
82
|
* keyed by the REAL tab a run/card was routed to: the panel reports back under
|
|
63
83
|
* that tab id, and a ticket keyed by the shared scope address a tool ctx is
|
|
@@ -738,6 +758,10 @@ export const __panelToolsTestHooks = {
|
|
|
738
758
|
* it fails even where the handler suite does not reach. The handler CALL SITE
|
|
739
759
|
* is covered separately (deleting the wiring must also fail a named test). */
|
|
740
760
|
annotateShowMediaAck,
|
|
761
|
+
/** #2012 — the destination-kind helper. Handler call sites are covered
|
|
762
|
+
* separately (reverting `panel_show_media` to `isHeadless` on the address
|
|
763
|
+
* must also fail a named test). */
|
|
764
|
+
resolveClientKind,
|
|
741
765
|
/** Direct access to the #742 decline recheck loop so its hard-deadline
|
|
742
766
|
* guarantee (codex gate r2) can be unit-tested with a custom deadline. */
|
|
743
767
|
probeDeclineRecovery,
|
|
@@ -3050,6 +3074,15 @@ function annotateShowMediaAck(res, dispatched) {
|
|
|
3050
3074
|
* "partial_accounting" or "mailboxed". Structured so a caller can
|
|
3051
3075
|
* branch on it without reading the prose. */
|
|
3052
3076
|
unaccounted_because: verdict.reason,
|
|
3077
|
+
/** #2013 — only on a mailbox receipt. A concrete tab id is a known
|
|
3078
|
+
* recipient; `null` means the box is scope-keyed (whoever hellos
|
|
3079
|
+
* next). Structured so a caller does not have to parse the prose. */
|
|
3080
|
+
...(verdict.reason === "mailboxed"
|
|
3081
|
+
? {
|
|
3082
|
+
queued_for: verdict.queuedFor ?? null,
|
|
3083
|
+
recipient_known: verdict.queuedFor != null,
|
|
3084
|
+
}
|
|
3085
|
+
: {}),
|
|
3053
3086
|
/** EVERY dispatched item, even under partial accounting: a reply
|
|
3054
3087
|
* that covers 1 of 2 does not say WHICH, so none can be settled. */
|
|
3055
3088
|
unaccounted: dispatched.map((d) => ({ filename: d.filename, kind: d.kind })),
|
|
@@ -16420,8 +16453,14 @@ CHECKED FOR YOU: the graph read this message prescribes was just run, and it ` +
|
|
|
16420
16453
|
// bytes HERE and inline them as a data URL. Best-effort: any failure
|
|
16421
16454
|
// (fetch error, non-media, too big) falls back to forwarding the ref,
|
|
16422
16455
|
// which the client renders as a caption card.
|
|
16456
|
+
//
|
|
16457
|
+
// #2012 — judge the DESTINATION, not the address. `ctx.tabId` may be
|
|
16458
|
+
// a scope / prefix / alias; `isHeadless` on the address is a lookup
|
|
16459
|
+
// miss that answers false and a phone gets a /view URL it cannot
|
|
16460
|
+
// fetch. Positive requirement: inline only a proven headless
|
|
16461
|
+
// destination.
|
|
16423
16462
|
let inlined = false;
|
|
16424
|
-
if (
|
|
16463
|
+
if (resolveClientKind(ctx).kind === "headless") {
|
|
16425
16464
|
try {
|
|
16426
16465
|
const base = (process.env.COMFYUI_URL ?? "http://127.0.0.1:8188").replace(/\/+$/, "");
|
|
16427
16466
|
const qs = new URLSearchParams({ filename: src.filename, type: src.type ?? "output" });
|