comfyui-mcp 0.52.42 → 0.52.43

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.
@@ -124,7 +124,7 @@ import { startPanelConsoleHttpServer } from "./panel-console-http.js";
124
124
  import { readComfyuiCrashLog, formatCrashNote } from "../services/crash-log.js";
125
125
  import { QueueMonitor } from "../services/queue-monitor.js";
126
126
  import { RunCompletions, describe as describeCorrelation, } from "./run-completion-journal.js";
127
- import { createRunCompletionWatchdog, resolveHistoryCompletionImages } from "./run-completion-watchdog.js";
127
+ import { createRunCompletionWatchdog, resolveHistoryCompletionImages, resolveHistoryCompletionStatus, } from "./run-completion-watchdog.js";
128
128
  import { AskAnswers, preview as previewQuestion } from "./ask-answer-journal.js";
129
129
  import { initRunpodWatcher, getRunpodWatcher } from "../services/runpod-watch.js";
130
130
  import { getPod } from "../services/runpod-client.js";
@@ -2914,6 +2914,12 @@ export async function runPanelOrchestrator() {
2914
2914
  backendForTab,
2915
2915
  backendOfKey: backendOf,
2916
2916
  info: (msg) => logger.info(msg),
2917
+ // panel#1557 — a unique-canvas reconnect that hello'd without `backend`
2918
+ // joined the default conversation; claiming puts it on this one so the
2919
+ // pin we just wrote is not immediately invalidated at resolution.
2920
+ claimTab: (tab, backend) => {
2921
+ tabBackends.set(tab, backend);
2922
+ },
2917
2923
  }));
2918
2924
  // #884 P1 (confirming gate 2) — a hello whose `backend` is absent or unknown
2919
2925
  // JOINS the default conversation, so its backend-qualified buffers must drain
@@ -3504,6 +3510,10 @@ export async function runPanelOrchestrator() {
3504
3510
  logger.warn(`[panel-orchestrator] readiness probe failed: ${err instanceof Error ? err.message : String(err)}`);
3505
3511
  }
3506
3512
  }
3513
+ // Assigned next to the queue-status timer below. Declared here so the hello
3514
+ // path can reconcile owed panel_run tickets the moment the panel reconnects
3515
+ // (#1556) without waiting for that timer to construct it.
3516
+ let runCompletionWatchdog;
3507
3517
  bridge.onPanelMessage = (event) => {
3508
3518
  // Connect ack: the instant a panel tab connects, the orchestrator announces
3509
3519
  // itself so "connected" means "a real agent is attending" — not merely "a
@@ -3958,6 +3968,12 @@ export async function runPanelOrchestrator() {
3958
3968
  // are change-only, so a tab connecting MID-render would otherwise wait for
3959
3969
  // the next state transition to learn a job is already running.
3960
3970
  bridge.push(buildQueueStatusFrame(QueueMonitor.snapshot()), panelTab);
3971
+ // #1556 — a hello is a reconnect (or the first chance after a missed
3972
+ // ComfyUI WS frame). Look up every still-owed panel_run in /history NOW
3973
+ // and journal a completion if ComfyUI already finished it, instead of
3974
+ // waiting the synthesis grace. Exactly-once: the journal skips a run it
3975
+ // already holds.
3976
+ void runCompletionWatchdog?.reconcile(RunCompletions.owedCompletions().map((t) => t.promptId));
3961
3977
  // Seed the RunPod control panel too — a tab that just connected gets the
3962
3978
  // current pod-status frame (or a cleared one when nothing is watched).
3963
3979
  const rpFrame = getRunpodWatcher()?.current();
@@ -5899,9 +5915,10 @@ export async function runPanelOrchestrator() {
5899
5915
  // after the grace is synthesised into the SAME journal the real frame uses.
5900
5916
  // See run-completion-watchdog.ts for why it waits, and why the panel's frame
5901
5917
  // still wins whenever it is coming.
5902
- const runCompletionWatchdog = createRunCompletionWatchdog({
5918
+ const wd = createRunCompletionWatchdog({
5903
5919
  awaiting: (promptId) => RunCompletions.awaitingCompletion(promptId),
5904
5920
  resolveOutputs: (promptId) => resolveHistoryCompletionImages(promptId),
5921
+ lookupStatus: (promptId) => resolveHistoryCompletionStatus(promptId),
5905
5922
  deliver: (payload, ticket) => {
5906
5923
  // The SAME arrival path the panel's frame takes: correlated once, here,
5907
5924
  // against the ticket that is still open — so the agent is told this is the
@@ -5914,13 +5931,14 @@ export async function runPanelOrchestrator() {
5914
5931
  flushRunCompletions(ticket.tabId);
5915
5932
  },
5916
5933
  });
5934
+ runCompletionWatchdog = wd;
5917
5935
  const queueStatusBroadcaster = createQueueStatusBroadcaster(() => QueueMonitor.snapshot(), (frame) => void bridge.push(frame),
5918
5936
  // TEE, not a second drain: drainCompletions() splices, so the watchdog has
5919
5937
  // to read the same array the broadcaster is handed rather than call it
5920
5938
  // again — a second call would race and each consumer would see only half.
5921
5939
  () => {
5922
5940
  const completions = QueueMonitor.drainCompletions();
5923
- runCompletionWatchdog.observe(completions);
5941
+ wd.observe(completions);
5924
5942
  return completions;
5925
5943
  });
5926
5944
  // Each tick first refreshes the monitor over HTTP (GET /queue + /history
@@ -5934,7 +5952,7 @@ export async function runPanelOrchestrator() {
5934
5952
  // …and only THEN expire the watchdog's arms: the broadcaster tick is what
5935
5953
  // feeds it (the drain tee above), so ticking it first would let an
5936
5954
  // observation sit a whole extra second before it is even armed. #1789.
5937
- runCompletionWatchdog.tick();
5955
+ wd.tick();
5938
5956
  });
5939
5957
  }, 1000);
5940
5958
  queueStatusTimer.unref?.();