comfyui-mcp 0.50.6 → 0.50.7
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/comfyui/fetch.js +74 -3
- package/dist/comfyui/fetch.js.map +1 -1
- package/dist/orchestrator/index.js +25 -3
- package/dist/orchestrator/index.js.map +1 -1
- package/dist/orchestrator/pair-durability.js +83 -0
- package/dist/orchestrator/pair-durability.js.map +1 -0
- package/dist/orchestrator/panel-tools.js +61 -2
- package/dist/orchestrator/panel-tools.js.map +1 -1
- package/dist/services/model-resolver.js +39 -5
- package/dist/services/model-resolver.js.map +1 -1
- package/dist/services/self-restart.js +12 -0
- package/dist/services/self-restart.js.map +1 -1
- package/dist/services/ui-bridge.js +46 -2
- package/dist/services/ui-bridge.js.map +1 -1
- package/package.json +1 -1
package/dist/comfyui/fetch.js
CHANGED
|
@@ -13,6 +13,75 @@ function targetOf(input) {
|
|
|
13
13
|
return String(input);
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* What the CONNECTED panels front, for the drift comparison below (#952).
|
|
18
|
+
*
|
|
19
|
+
* Injected by the orchestrator at startup rather than imported: this module is
|
|
20
|
+
* the bottom of the stack and must not depend on the bridge. Unset (the plain
|
|
21
|
+
* MCP server, tests, any process with no bridge) simply means the comparison is
|
|
22
|
+
* skipped — never that there is no drift.
|
|
23
|
+
*
|
|
24
|
+
* Origins here must be the SERVER-OBSERVED handshake Origin (UiBridge's
|
|
25
|
+
* `tabServerOrigin`), not the client-supplied `hello.comfyui_url`: the browser
|
|
26
|
+
* sets the former and blocks page JS from forging it, so it is the trustworthy
|
|
27
|
+
* answer to "which ComfyUI is this tab actually on".
|
|
28
|
+
*/
|
|
29
|
+
let connectedPanelOrigins = null;
|
|
30
|
+
/** Install the panel-origin source. Pass null to clear (tests, shutdown). */
|
|
31
|
+
export function setConnectedPanelOrigins(fn) {
|
|
32
|
+
connectedPanelOrigins = fn;
|
|
33
|
+
}
|
|
34
|
+
/** Origin (scheme://host:port) of a request target, or undefined if unparsable. */
|
|
35
|
+
function originOf(target) {
|
|
36
|
+
try {
|
|
37
|
+
return new URL(target).origin;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Name the drift instead of asking the reader to go and check for it (#952).
|
|
45
|
+
*
|
|
46
|
+
* The shipped message told the user a connected panel "does not imply this
|
|
47
|
+
* address is reachable" and pointed them at install_comfyui(action:"environment")
|
|
48
|
+
* to compare the two by hand. We can usually just do the comparison — the bridge
|
|
49
|
+
* knows what each connected tab fronts — and saying which of the three cases
|
|
50
|
+
* holds is worth far more than the instruction to go and find out:
|
|
51
|
+
*
|
|
52
|
+
* - DIFFERENT → that is very likely the whole answer.
|
|
53
|
+
* - THE SAME → drift is RULED OUT. Worth stating plainly, because it stops
|
|
54
|
+
* the reader chasing the explanation the old text volunteered.
|
|
55
|
+
* The panel reaches it from the browser; this process does not
|
|
56
|
+
* (a firewall, a container boundary, a bound interface).
|
|
57
|
+
* - UNKNOWN → no panel connected, no origin source installed, or the
|
|
58
|
+
* handshake carried no usable Origin. Say nothing about drift;
|
|
59
|
+
* an absent comparison is not a negative result.
|
|
60
|
+
*/
|
|
61
|
+
function describeTargetDrift(target) {
|
|
62
|
+
const origins = (() => {
|
|
63
|
+
try {
|
|
64
|
+
return connectedPanelOrigins?.() ?? [];
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return []; // a broken source must never replace the real network error
|
|
68
|
+
}
|
|
69
|
+
})();
|
|
70
|
+
if (origins.length === 0)
|
|
71
|
+
return "";
|
|
72
|
+
const want = originOf(target);
|
|
73
|
+
if (!want)
|
|
74
|
+
return "";
|
|
75
|
+
const distinct = [...new Set(origins)];
|
|
76
|
+
if (distinct.includes(want)) {
|
|
77
|
+
return (` A connected panel is on this same origin, so this is NOT a wrong-address problem: ` +
|
|
78
|
+
`the browser can reach ${want} and this process cannot (a firewall, a container ` +
|
|
79
|
+
`boundary, or a server bound to one interface).`);
|
|
80
|
+
}
|
|
81
|
+
return (` A connected panel is on ${distinct.join(", ")} — a DIFFERENT address, which is why ` +
|
|
82
|
+
`the panel works while this call does not. Point COMFYUI_URL at that origin if it is the ` +
|
|
83
|
+
`server you meant.`);
|
|
84
|
+
}
|
|
16
85
|
/**
|
|
17
86
|
* Turn a network-layer throw into a diagnostic that says WHAT was attempted.
|
|
18
87
|
*
|
|
@@ -25,14 +94,16 @@ function targetOf(input) {
|
|
|
25
94
|
*
|
|
26
95
|
* The two ARE separate targets by design: the panel talks to whichever ComfyUI
|
|
27
96
|
* the browser is on, while these calls go to the configured COMFYUI_URL. That is
|
|
28
|
-
* not a bug, but it is invisible unless the failure names the address
|
|
97
|
+
* not a bug, but it is invisible unless the failure names the address — and,
|
|
98
|
+
* where the bridge can tell us, says whether the two actually differ.
|
|
29
99
|
*/
|
|
30
100
|
function describeComfyFetchFailure(err, target) {
|
|
31
101
|
const { message, code } = describeFetchFailure(err);
|
|
32
102
|
const wrapped = new Error(`${message} — while requesting ${target}. ` +
|
|
33
103
|
`That is the headless ComfyUI target (COMFYUI_URL); a CONNECTED sidebar panel does not imply this address is reachable, ` +
|
|
34
|
-
`because the panel talks to whichever ComfyUI its browser tab is on
|
|
35
|
-
|
|
104
|
+
`because the panel talks to whichever ComfyUI its browser tab is on.` +
|
|
105
|
+
describeTargetDrift(target) +
|
|
106
|
+
` Check the target with install_comfyui (action:"environment"), and confirm the server is up with get_system_stats (action:"health").`, { cause: err });
|
|
36
107
|
if (code)
|
|
37
108
|
wrapped.code = code;
|
|
38
109
|
return wrapped;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/comfyui/fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE9E,4EAA4E;AAC5E,SAAS,QAAQ,CAAC,KAA6B;IAC7C,IAAI,CAAC;QACH,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QAC5C,IAAI,KAAK,YAAY,GAAG;YAAE,OAAO,KAAK,CAAC,IAAI,CAAC;QAC5C,OAAQ,KAAiB,CAAC,GAAG,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;AACH,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/comfyui/fetch.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,12 +24,14 @@ import { performPanelSync, reassessPanelAfterSyncFailure } from "../services/pan
|
|
|
24
24
|
import { clearPanelDiskObservation } from "../services/panel-workspace.js";
|
|
25
25
|
import { panelRecoveryContext } from "../services/panel-recovery.js";
|
|
26
26
|
import { isPanelAutoInstallDisabled } from "../services/panel-installer.js";
|
|
27
|
-
import { SelfRestarter } from "../services/self-restart.js";
|
|
27
|
+
import { SelfRestarter, canSelfRestart } from "../services/self-restart.js";
|
|
28
|
+
import { pairUrlDurability } from "./pair-durability.js";
|
|
28
29
|
import { SessionStore, workflowIdentityParts } from "./session-store.js";
|
|
29
30
|
import { SHARED_SESSION_SCOPE, isScopeAddress, conversationTabs, shouldRetireSharedAgent, messageOrigin, normalizeHelloBackend, workflowOriginNote, } from "../services/session-scope.js";
|
|
30
31
|
import { TurnOriginTracker, makeScopeRepinHandler, makeScopeTargetResolver, } from "./turn-origins.js";
|
|
31
32
|
import { listSessions, loadTranscript } from "./history.js";
|
|
32
33
|
import { uploadImageHttp, resetClient } from "../comfyui/client.js";
|
|
34
|
+
import { setConnectedPanelOrigins } from "../comfyui/fetch.js";
|
|
33
35
|
import { logger } from "../utils/logger.js";
|
|
34
36
|
import { PanelAgentManager, fetchSupportedModels, fetchSupportedCommands, isEffort, } from "./panel-agent.js";
|
|
35
37
|
import { promptText } from "./error-text.js";
|
|
@@ -2466,6 +2468,12 @@ export async function runPanelOrchestrator() {
|
|
|
2466
2468
|
// `null` (ambiguous origin) makes the bridge refuse loudly; no entry lets
|
|
2467
2469
|
// the bridge fall back to active-tab resolution (idle-time probes).
|
|
2468
2470
|
bridge.setScopeTargetResolver(makeScopeTargetResolver({ tracker: turnOrigins, scopeAgentKeyOf }));
|
|
2471
|
+
// #952 — let a headless `fetch failed` say whether the connected panel is on a
|
|
2472
|
+
// DIFFERENT ComfyUI than COMFYUI_URL. The reporter's readonly tools failed
|
|
2473
|
+
// while every panel tool worked, and nothing in the error connected the two.
|
|
2474
|
+
// SERVER-OBSERVED origins only (tabServerOrigin): the browser sets the
|
|
2475
|
+
// handshake Origin and page JS cannot forge it, unlike hello.comfyui_url.
|
|
2476
|
+
setConnectedPanelOrigins(() => bridge.connectedServerOrigins());
|
|
2469
2477
|
// #884 P1 (confirming gate 2) — EXPLICIT recovery from a DEAD or AMBIGUOUS
|
|
2470
2478
|
// pin, and from those only. The bridge's refusal names
|
|
2471
2479
|
// panel_set_workflow_target as the way out; this is the ONLY path that
|
|
@@ -3911,8 +3919,22 @@ export async function runPanelOrchestrator() {
|
|
|
3911
3919
|
}
|
|
3912
3920
|
url = `ws://${ip}:${pairPort}/?token=${token}`;
|
|
3913
3921
|
}
|
|
3914
|
-
|
|
3915
|
-
|
|
3922
|
+
// #875 — say at pair time whether this URL survives a restart. The
|
|
3923
|
+
// self-restarter is on by default and rotates the token (always, unless
|
|
3924
|
+
// pinned) and the tunnel hostname (always, quick tunnels cannot be
|
|
3925
|
+
// pinned). A user hit exactly this and reported it as "updating the npm
|
|
3926
|
+
// version bricks my communication with the agent" — the restart was the
|
|
3927
|
+
// cause, and nothing here had told them.
|
|
3928
|
+
const durability = pairUrlDurability({
|
|
3929
|
+
mode,
|
|
3930
|
+
pinnedToken: envPairToken !== null,
|
|
3931
|
+
autoRestart: canSelfRestart(),
|
|
3932
|
+
});
|
|
3933
|
+
logger.info(`[panel-orchestrator] pairing URL minted (${mode}) — ` +
|
|
3934
|
+
(durability.survivesRestart
|
|
3935
|
+
? "survives restart"
|
|
3936
|
+
: `rotates on restart: ${durability.rotates.join(", ")}`));
|
|
3937
|
+
bridge.push({ type: "pair_url", mode, url, durability }, tabId);
|
|
3916
3938
|
})().catch((err) => {
|
|
3917
3939
|
bridge.push({ type: "pair_error", mode, error: err instanceof Error ? err.message : String(err) }, tabId);
|
|
3918
3940
|
});
|