comfyui-mcp 0.48.31 → 0.48.32
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.
|
@@ -193,6 +193,17 @@ let panelRebootTimingOverride = null;
|
|
|
193
193
|
// COMFYUI_PANEL_REBOOT_* env overrides are set absurdly high (coordinator codex P2).
|
|
194
194
|
const MAX_REBOOT_SETTLE_MS = 10_000; // 10s
|
|
195
195
|
const MAX_REBOOT_BUDGET_MS = 240_000; // 240s → settle+budget ≤ 250s < 300s outer
|
|
196
|
+
// #404: hard ceiling on how long the panel_restart_comfyui CONFIRMATION card waits for
|
|
197
|
+
// a yes/no answer. A restart is user-initiated, so a present user answers in seconds;
|
|
198
|
+
// the failure mode is an unanswered/undelivered card AFTER a prior restart's reconnect
|
|
199
|
+
// (the "second restart in one turn" repro: the panel tab is backgrounded or still
|
|
200
|
+
// re-registering, so the card is never seen/answered). Previously the confirm inherited
|
|
201
|
+
// the full remaining ~255s budget, so it blocked for ~4 minutes and read as an
|
|
202
|
+
// indefinite hang (the user killed it at ~2min). Bounding the WAIT here — well under the
|
|
203
|
+
// ~240s ask deadline and the ~300s tools/call budget — makes an unanswered card fail
|
|
204
|
+
// fast with an actionable retry / restart_comfyui hint. It NEVER shortcuts the
|
|
205
|
+
// confirmation itself (no auto-confirm): it bounds only how long we wait for the answer.
|
|
206
|
+
const RESTART_CONFIRM_TIMEOUT_MS = 90_000; // 90s
|
|
196
207
|
function parsePositiveNumberEnv(name, fallback) {
|
|
197
208
|
const raw = process.env[name];
|
|
198
209
|
if (raw == null || raw === "")
|
|
@@ -242,6 +253,8 @@ export const __panelToolsTestHooks = {
|
|
|
242
253
|
loopbackProbeUrl,
|
|
243
254
|
/** Compute reboot timing from env WITH the P2 hard caps (bypasses any override). */
|
|
244
255
|
computeRebootTimingFromEnv,
|
|
256
|
+
/** #404: the hard ceiling on the panel_restart_comfyui confirmation-card wait. */
|
|
257
|
+
RESTART_CONFIRM_TIMEOUT_MS,
|
|
245
258
|
/** Zero out the post-drop retry settle so retry-once tests don't sleep. */
|
|
246
259
|
setRetrySettleMs(ms) {
|
|
247
260
|
retrySettleMsOverride = ms;
|
|
@@ -341,6 +354,7 @@ const MUTATING_GRAPH_EDIT_CMDS = new Set([
|
|
|
341
354
|
"graph_connect",
|
|
342
355
|
"graph_disconnect",
|
|
343
356
|
"graph_set_widget",
|
|
357
|
+
"graph_set_node_property",
|
|
344
358
|
"graph_move_node",
|
|
345
359
|
"graph_resize_node",
|
|
346
360
|
"graph_set_title",
|
|
@@ -2819,6 +2833,15 @@ export function buildPanelToolDefs() {
|
|
|
2819
2833
|
// Give the guarded write the bounded refresh ack budget.
|
|
2820
2834
|
return ctx.call({ cmd: "graph_set_widget", node_id: args.node_id, widget: args.widget, value }, OBJECT_INFO_REFRESH_ACK_TIMEOUT_MS);
|
|
2821
2835
|
}),
|
|
2836
|
+
def("panel_set_property", "Set a node's LiteGraph PROPERTY (the right-click → Properties panel), NOT a widget — the counterpart to panel_set_widget, which only reaches `widgets`. Many custom nodes are configured entirely through node properties: e.g. the rgthree Fast Groups Bypasser's filters `matchTitle`, `matchColors`, `sort`, and `toggleRestriction` are node properties, and without `matchTitle` the node enumerates EVERY group in the workflow (a footgun). Sets node.properties[name] and, when the node defines an onPropertyChanged callback (rgthree and many LiteGraph nodes do), invokes it so the change takes effect LIVE (e.g. rgthree re-filters its group list). Returns the previous and new value. Undoable with Ctrl+Z.", {
|
|
2837
|
+
node_id: z.number().int().describe("Node id from panel_graph_outline / panel_query_graph."),
|
|
2838
|
+
name: z
|
|
2839
|
+
.string()
|
|
2840
|
+
.describe("Property name from the node's right-click → Properties panel (e.g. 'matchTitle', 'matchColors', 'sort', 'toggleRestriction')."),
|
|
2841
|
+
value: z
|
|
2842
|
+
.union([z.string(), z.number(), z.boolean(), z.null()])
|
|
2843
|
+
.describe("New property value (string/number/boolean/null). For the rgthree Fast Groups Bypasser, matchTitle is a title substring/regex filter."),
|
|
2844
|
+
}, async (args, ctx) => ctx.call({ cmd: "graph_set_node_property", node_id: args.node_id, name: args.name, value: args.value })),
|
|
2822
2845
|
def("panel_move_node", "Move a node to a new canvas position [x, y] in the user's open graph. Undoable.", {
|
|
2823
2846
|
node_id: z.number().int().describe("Node id from panel_graph_outline / panel_query_graph."),
|
|
2824
2847
|
pos: xy().describe("New canvas [x, y] (two numbers)."),
|
|
@@ -3830,10 +3853,31 @@ export function buildPanelToolDefs() {
|
|
|
3830
3853
|
// to the remaining budget (its deadline+grace can't overrun it — see confirm).
|
|
3831
3854
|
const OVERALL_MAX_MS = 255_000;
|
|
3832
3855
|
const overallDeadline = Date.now() + OVERALL_MAX_MS;
|
|
3833
|
-
|
|
3856
|
+
// #404: if the ONLY reachable client is canvas-less (a mobile mirror / remote /
|
|
3857
|
+
// headless viewer), a yes/no card can't render, so the confirm would block with
|
|
3858
|
+
// no way to answer. Detect that up front — exactly as panel_ask does — and fail
|
|
3859
|
+
// fast with an actionable message instead of dispatching a card into the void and
|
|
3860
|
+
// waiting out the whole budget. Points at the headless restart_comfyui fallback,
|
|
3861
|
+
// which needs no panel card. (A normal interactive tab returns null → proceed.)
|
|
3862
|
+
const surfaceErr = askSurfaceError(ctx);
|
|
3863
|
+
if (surfaceErr) {
|
|
3864
|
+
return fail(surfaceErr +
|
|
3865
|
+
" To restart the server without a panel confirmation card, use restart_comfyui.");
|
|
3866
|
+
}
|
|
3867
|
+
// #404: BOUND the confirmation wait. It previously inherited the full remaining
|
|
3868
|
+
// ~255s budget, so an unanswered/undelivered card (the panel tab backgrounded or
|
|
3869
|
+
// still reconnecting after a PRIOR restart — the second-restart-in-one-turn repro)
|
|
3870
|
+
// blocked for ~4 minutes and read as an indefinite hang. Cap it at
|
|
3871
|
+
// RESTART_CONFIRM_TIMEOUT_MS (still clamped under the outer budget). This bounds
|
|
3872
|
+
// only the WAIT — it never auto-confirms; on timeout we fail fast, below.
|
|
3873
|
+
const confirmBudget = Math.max(1, Math.min(RESTART_CONFIRM_TIMEOUT_MS, overallDeadline - Date.now()));
|
|
3874
|
+
const decision = await ctx.confirm("Restart ComfyUI now? It (and this agent) will go down briefly, then reconnect and resume automatically.", "Restart ComfyUI", confirmBudget);
|
|
3834
3875
|
if (decision === "timeout") {
|
|
3835
|
-
return ok(
|
|
3836
|
-
"
|
|
3876
|
+
return ok(`No confirmation received within ${Math.round(confirmBudget / 1000)}s, so I did NOT ` +
|
|
3877
|
+
"restart ComfyUI. The panel tab may be backgrounded or still reconnecting after a " +
|
|
3878
|
+
"previous restart, so the confirmation card wasn't answered. Tell me to restart it " +
|
|
3879
|
+
"and I'll re-ask, or use restart_comfyui to restart the server directly without a " +
|
|
3880
|
+
"panel card.");
|
|
3837
3881
|
}
|
|
3838
3882
|
if (decision !== "yes") {
|
|
3839
3883
|
return ok("Cancelled — ComfyUI was not restarted.");
|