comfyui-mcp 0.52.82 → 0.52.83
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.
|
@@ -190,7 +190,7 @@ import { RunCompletions } from "./run-completion-journal.js";
|
|
|
190
190
|
import { AskAnswers, askFingerprint, PANEL_ASK_ID_PREFIX, } from "./ask-answer-journal.js";
|
|
191
191
|
import { getQueueVerified, resetClient, resetObjectInfoCache, } from "../comfyui/client.js";
|
|
192
192
|
import { convertUiToApi, collectNodeTypes } from "../services/workflow-converter.js";
|
|
193
|
-
import { restartComfyUI, preflightLocalRestart, readServingArgv, describeArgvDrift, recordRestartDispatch, clearRestartDispatch, getRestartDispatchRecord, RESTART_DISPATCH_CAUSATION_WINDOW_MS, PROCESS_WIDE_RESTART_DISPATCH_TOKEN, __processControlTestHooks, } from "../services/process-control.js";
|
|
193
|
+
import { restartComfyUI, preflightLocalRestart, readServingArgv, resolveVerifiedProxyRestartTarget, describeArgvDrift, recordRestartDispatch, clearRestartDispatch, getRestartDispatchRecord, RESTART_DISPATCH_CAUSATION_WINDOW_MS, PROCESS_WIDE_RESTART_DISPATCH_TOKEN, __processControlTestHooks, } from "../services/process-control.js";
|
|
194
194
|
import { resetManagerApiCache } from "../services/manager-api-cache.js";
|
|
195
195
|
import { desktopSavedLaunchArgs, describeSavedLaunchArgDrift, } from "../services/desktop-launch-args.js";
|
|
196
196
|
import { config, isRemoteMode, isCloudMode, getBootLocalComfyUIBaseUrl, getComfyUIBaseUrl, getComfyuiTargetGeneration, } from "../config.js";
|
|
@@ -735,6 +735,10 @@ export const __panelToolsTestHooks = {
|
|
|
735
735
|
setLocalRestartPreflight(fn) {
|
|
736
736
|
localRestartPreflightOverride = fn;
|
|
737
737
|
},
|
|
738
|
+
/** Inject the narrow EZi/CEI proxy proof; null restores the live resolver. */
|
|
739
|
+
setVerifiedProxyRestartTarget(fn) {
|
|
740
|
+
verifiedProxyRestartTargetOverride = fn;
|
|
741
|
+
},
|
|
738
742
|
/** Inject a fast #742 decline-probe recheck window so decline-path tests
|
|
739
743
|
* don't wait the real ~6s. null restores the DECLINE_PROBE_* constants. */
|
|
740
744
|
setDeclineProbeTiming(timing) {
|
|
@@ -2221,6 +2225,16 @@ let healthProbeOverride = null;
|
|
|
2221
2225
|
/** Test injection for the #742 refuse-safe restart preflight (the real one is
|
|
2222
2226
|
* preflightLocalRestart in process-control). null → the live preflight. */
|
|
2223
2227
|
let localRestartPreflightOverride = null;
|
|
2228
|
+
let verifiedProxyRestartTargetOverride = null;
|
|
2229
|
+
function panelVerifiedProxyRestartTarget() {
|
|
2230
|
+
return (verifiedProxyRestartTargetOverride ?? resolveVerifiedProxyRestartTarget)();
|
|
2231
|
+
}
|
|
2232
|
+
function proxyTargetBindsPanel(ctx, target) {
|
|
2233
|
+
return (target != null &&
|
|
2234
|
+
sameHttpBase(getComfyUIBaseUrl(), target.proxyBase) &&
|
|
2235
|
+
ctx.bridge?.tabIsLocal?.(ctx.tabId) === true &&
|
|
2236
|
+
sameHttpBase(ctx.bridge?.tabServerOrigin?.(ctx.tabId), target.proxyBase));
|
|
2237
|
+
}
|
|
2224
2238
|
/** Test injection for the #742 decline-probe recheck window, so tests don't
|
|
2225
2239
|
* wait the real ~6s. null → the DECLINE_PROBE_* constants. */
|
|
2226
2240
|
let declineProbeTimingOverride = null;
|
|
@@ -15561,6 +15575,10 @@ CHECKED FOR YOU: the graph read this message prescribes was just run, and it ` +
|
|
|
15561
15575
|
return fail(surfaceErr +
|
|
15562
15576
|
" To restart the server without a panel confirmation card, use restart_comfyui.");
|
|
15563
15577
|
}
|
|
15578
|
+
// #2118: keep the proxy proof alive across the confirmation/preflight
|
|
15579
|
+
// awaits. The proxy is never treated as a ComfyUI process; it only lets
|
|
15580
|
+
// the tab-scoped Manager request be observed against the immutable backend.
|
|
15581
|
+
let proxyRestartTarget;
|
|
15564
15582
|
// #1819: resolve instance identity BEFORE the confirmation card. Asking the
|
|
15565
15583
|
// user to confirm a restart, then refusing because we cannot tell which
|
|
15566
15584
|
// ComfyUI this tab fronts, is two contradictory outcomes (timeout vs refuse)
|
|
@@ -15575,10 +15593,14 @@ CHECKED FOR YOU: the graph read this message prescribes was just run, and it ` +
|
|
|
15575
15593
|
const identityBound = identityHealthBase != null &&
|
|
15576
15594
|
sameHttpBase(getComfyUIBaseUrl(), identityHealthBase);
|
|
15577
15595
|
if (!identityBound) {
|
|
15596
|
+
const candidate = await panelVerifiedProxyRestartTarget();
|
|
15597
|
+
if (proxyTargetBindsPanel(ctx, candidate)) {
|
|
15598
|
+
proxyRestartTarget = candidate;
|
|
15599
|
+
}
|
|
15578
15600
|
const tabStillHere = typeof ctx.bridge?.canReach === "function"
|
|
15579
15601
|
? ctx.bridge.canReach(ctx.tabId) === true
|
|
15580
15602
|
: true;
|
|
15581
|
-
if (tabStillHere) {
|
|
15603
|
+
if (tabStillHere && proxyRestartTarget == null) {
|
|
15582
15604
|
return restartRefusedPreservingBinding(ctx, unboundLocalRestartRefusalNote(ctx, identityHealthBase, identityBinding.blocker));
|
|
15583
15605
|
}
|
|
15584
15606
|
// Tab is gone: confirm will be unreachable and #1671 crash-recovery
|
|
@@ -16151,8 +16173,16 @@ CHECKED FOR YOU: the graph read this message prescribes was just run, and it ` +
|
|
|
16151
16173
|
// "idle" and a restart aborts whatever is running.
|
|
16152
16174
|
const configuredRestartCommand = config.comfyuiRestartCommand;
|
|
16153
16175
|
if (configuredRestartCommand && !isRemoteMode() && !isCloudMode()) {
|
|
16154
|
-
|
|
16155
|
-
|
|
16176
|
+
if (proxyRestartTarget != null) {
|
|
16177
|
+
const refreshedProxy = await panelVerifiedProxyRestartTarget();
|
|
16178
|
+
proxyRestartTarget = proxyTargetBindsPanel(ctx, refreshedProxy)
|
|
16179
|
+
? refreshedProxy
|
|
16180
|
+
: undefined;
|
|
16181
|
+
}
|
|
16182
|
+
const commandHealthBase = proxyRestartTarget?.backendBase ?? captureRebootHealthBase(ctx);
|
|
16183
|
+
const commandBound = proxyRestartTarget != null ||
|
|
16184
|
+
(commandHealthBase != null && sameHttpBase(getComfyUIBaseUrl(), commandHealthBase));
|
|
16185
|
+
if (commandHealthBase != null && commandBound) {
|
|
16156
16186
|
if (force !== true) {
|
|
16157
16187
|
let busyCount = null;
|
|
16158
16188
|
try {
|
|
@@ -16191,7 +16221,13 @@ CHECKED FOR YOU: the graph read this message prescribes was just run, and it ` +
|
|
|
16191
16221
|
// Re-heal and re-verify at the point of action, exactly as the
|
|
16192
16222
|
// dispatch path below does.
|
|
16193
16223
|
ctx.ensureReachable?.();
|
|
16194
|
-
|
|
16224
|
+
if (proxyRestartTarget != null) {
|
|
16225
|
+
const postProxy = await panelVerifiedProxyRestartTarget();
|
|
16226
|
+
proxyRestartTarget = proxyTargetBindsPanel(ctx, postProxy)
|
|
16227
|
+
? postProxy
|
|
16228
|
+
: undefined;
|
|
16229
|
+
}
|
|
16230
|
+
const postCheckHealthBase = proxyRestartTarget?.backendBase ?? captureRebootHealthBase(ctx);
|
|
16195
16231
|
if (postCheckHealthBase == null ||
|
|
16196
16232
|
!sameHttpBase(commandHealthBase, postCheckHealthBase)) {
|
|
16197
16233
|
return ok({
|
|
@@ -16271,10 +16307,20 @@ CHECKED FOR YOU: the graph read this message prescribes was just run, and it ` +
|
|
|
16271
16307
|
// can be proven. They keep restart_comfyui, and the note says so. Weighed
|
|
16272
16308
|
// against #814 — where exactly such a user's server was stopped and never came
|
|
16273
16309
|
// back — declining is the recoverable side.
|
|
16310
|
+
// Re-resolve after the confirmation await. A proxy proof is an endpoint
|
|
16311
|
+
// identity claim, not a durable permission; a retarget or tab rebind makes
|
|
16312
|
+
// it unusable and returns to the existing refusal path.
|
|
16313
|
+
if (proxyRestartTarget != null) {
|
|
16314
|
+
const refreshedProxy = await panelVerifiedProxyRestartTarget();
|
|
16315
|
+
proxyRestartTarget = proxyTargetBindsPanel(ctx, refreshedProxy)
|
|
16316
|
+
? refreshedProxy
|
|
16317
|
+
: undefined;
|
|
16318
|
+
}
|
|
16274
16319
|
const preflightBinding = resolveRebootHealthBinding(ctx);
|
|
16275
|
-
const preflightHealthBase = preflightBinding.base;
|
|
16276
|
-
const preflightBound =
|
|
16277
|
-
|
|
16320
|
+
const preflightHealthBase = proxyRestartTarget?.backendBase ?? preflightBinding.base;
|
|
16321
|
+
const preflightBound = proxyRestartTarget != null ||
|
|
16322
|
+
(preflightHealthBase != null &&
|
|
16323
|
+
sameHttpBase(getComfyUIBaseUrl(), preflightHealthBase));
|
|
16278
16324
|
// #848: what the instance was OBSERVED running with, taken from the preflight
|
|
16279
16325
|
// that already had to resolve it. Nothing new is probed before the dispatch —
|
|
16280
16326
|
// the no-await invariant between the binding capture and the reboot stands.
|
|
@@ -16308,7 +16354,9 @@ CHECKED FOR YOU: the graph read this message prescribes was just run, and it ` +
|
|
|
16308
16354
|
// EVERY retarget — any mutation, including a round trip back to the
|
|
16309
16355
|
// same base, is caught.
|
|
16310
16356
|
const preflightTargetGeneration = getComfyuiTargetGeneration();
|
|
16311
|
-
const preflight =
|
|
16357
|
+
const preflight = proxyRestartTarget
|
|
16358
|
+
? { ok: true, observedArgv: proxyRestartTarget.argv }
|
|
16359
|
+
: await (localRestartPreflightOverride ?? preflightLocalRestart)();
|
|
16312
16360
|
// #848: keep the observed launch arguments. Recorded here and spent ONLY on
|
|
16313
16361
|
// the success path far below, where the reboot has been proven to have
|
|
16314
16362
|
// cycled THIS instance — it never influences any decision above.
|
|
@@ -16327,11 +16375,19 @@ CHECKED FOR YOU: the graph read this message prescribes was just run, and it ` +
|
|
|
16327
16375
|
// re-capture BEFORE trusting the result either way. The guarantee
|
|
16328
16376
|
// that must hold: a stop/reboot is only ever sent when the preflight
|
|
16329
16377
|
// validated THE instance the dispatch will cycle.
|
|
16378
|
+
if (proxyRestartTarget) {
|
|
16379
|
+
// The proxy branch performs no local stop/preflight. Its direct
|
|
16380
|
+
// backend proof is rechecked immediately before dispatch below.
|
|
16381
|
+
preflightArgvGeneration = proxyRestartTarget.generation;
|
|
16382
|
+
}
|
|
16330
16383
|
ctx.ensureReachable?.();
|
|
16331
16384
|
const postPreflightHealthBase = captureRebootHealthBase(ctx);
|
|
16332
|
-
const tabFrontsSameInstance =
|
|
16333
|
-
|
|
16334
|
-
|
|
16385
|
+
const tabFrontsSameInstance = proxyRestartTarget != null ||
|
|
16386
|
+
(postPreflightHealthBase != null &&
|
|
16387
|
+
sameHttpBase(preflightHealthBase, postPreflightHealthBase));
|
|
16388
|
+
const configStable = proxyRestartTarget != null
|
|
16389
|
+
? getComfyuiTargetGeneration() === proxyRestartTarget.generation
|
|
16390
|
+
: getComfyuiTargetGeneration() === preflightTargetGeneration;
|
|
16335
16391
|
if (!configStable && tabFrontsSameInstance) {
|
|
16336
16392
|
// r10: the target config moved MID-CHECK, so the preflight result
|
|
16337
16393
|
// — pass OR fail — cannot vouch for the tab-fronted instance (a
|
|
@@ -16409,7 +16465,17 @@ CHECKED FOR YOU: the graph read this message prescribes was just run, and it ` +
|
|
|
16409
16465
|
// this SAME browser tab; a different tab can reuse the same saved-workflow
|
|
16410
16466
|
// routing id while the original is still reconnecting.
|
|
16411
16467
|
const preRestartPanelIdentity = ctx.panelConnectionIdentity?.();
|
|
16412
|
-
|
|
16468
|
+
if (proxyRestartTarget != null) {
|
|
16469
|
+
const dispatchProxy = await panelVerifiedProxyRestartTarget();
|
|
16470
|
+
proxyRestartTarget = proxyTargetBindsPanel(ctx, dispatchProxy)
|
|
16471
|
+
? dispatchProxy
|
|
16472
|
+
: undefined;
|
|
16473
|
+
if (proxyRestartTarget) {
|
|
16474
|
+
preflightArgv = [...proxyRestartTarget.argv];
|
|
16475
|
+
preflightArgvGeneration = proxyRestartTarget.generation;
|
|
16476
|
+
}
|
|
16477
|
+
}
|
|
16478
|
+
const healthBase = proxyRestartTarget?.backendBase ?? captureRebootHealthBase(ctx);
|
|
16413
16479
|
// THE BINDING RULE APPLIES AT THE DISPATCH POINT, NOT ONLY BEFORE THE AWAIT.
|
|
16414
16480
|
//
|
|
16415
16481
|
// The check above happens before the preflight; a tab or connection rebind
|
|
@@ -16422,7 +16488,8 @@ CHECKED FOR YOU: the graph read this message prescribes was just run, and it ` +
|
|
|
16422
16488
|
//
|
|
16423
16489
|
// Same rule, same exclusions: only a LOCAL target we cannot tie to the
|
|
16424
16490
|
// instance this server accounts for is refused.
|
|
16425
|
-
const dispatchBound =
|
|
16491
|
+
const dispatchBound = proxyRestartTarget != null ||
|
|
16492
|
+
(healthBase != null && sameHttpBase(getComfyUIBaseUrl(), healthBase));
|
|
16426
16493
|
if (!dispatchBound && !isRemoteMode() && !isCloudMode()) {
|
|
16427
16494
|
return restartRefusedPreservingBinding(ctx, "Refusing to restart ComfyUI: the panel connection changed while the restart " +
|
|
16428
16495
|
"was being prepared, and I can no longer confirm which ComfyUI this tab " +
|
|
@@ -16614,6 +16681,7 @@ CHECKED FOR YOU: the graph read this message prescribes was just run, and it ` +
|
|
|
16614
16681
|
// server replaced at the same URL between the reboot and here. That gap is real
|
|
16615
16682
|
// and tracked in #871; this gate narrows the window, it does not close it.
|
|
16616
16683
|
healthBase != null &&
|
|
16684
|
+
proxyRestartTarget == null &&
|
|
16617
16685
|
sameHttpBase(getComfyUIBaseUrl(), healthBase)) {
|
|
16618
16686
|
return runHeadlessManagedRestart({
|
|
16619
16687
|
healthBase,
|