comfyui-mcp 0.44.0 → 0.46.0

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.
Files changed (64) hide show
  1. package/README.md +2 -2
  2. package/dist/config.js +159 -11
  3. package/dist/config.js.map +1 -1
  4. package/dist/orchestrator/ai-proposer.js +5 -0
  5. package/dist/orchestrator/ai-proposer.js.map +1 -1
  6. package/dist/orchestrator/antigravity-backend.js +394 -52
  7. package/dist/orchestrator/antigravity-backend.js.map +1 -1
  8. package/dist/orchestrator/claude-backend.js +13 -0
  9. package/dist/orchestrator/claude-backend.js.map +1 -1
  10. package/dist/orchestrator/codex-backend.js +12 -1
  11. package/dist/orchestrator/codex-backend.js.map +1 -1
  12. package/dist/orchestrator/gemini-backend.js +8 -1
  13. package/dist/orchestrator/gemini-backend.js.map +1 -1
  14. package/dist/orchestrator/grok-backend.js +9 -5
  15. package/dist/orchestrator/grok-backend.js.map +1 -1
  16. package/dist/orchestrator/index.js +603 -50
  17. package/dist/orchestrator/index.js.map +1 -1
  18. package/dist/orchestrator/panel-agent.js +21 -5
  19. package/dist/orchestrator/panel-agent.js.map +1 -1
  20. package/dist/orchestrator/panel-console-http.js +1 -0
  21. package/dist/orchestrator/panel-console-http.js.map +1 -1
  22. package/dist/orchestrator/panel-tools.js +140 -9
  23. package/dist/orchestrator/panel-tools.js.map +1 -1
  24. package/dist/services/ai-toolkit.js +260 -3
  25. package/dist/services/ai-toolkit.js.map +1 -1
  26. package/dist/services/download-progress.js +177 -7
  27. package/dist/services/download-progress.js.map +1 -1
  28. package/dist/services/missing-models.js +295 -0
  29. package/dist/services/missing-models.js.map +1 -0
  30. package/dist/services/openai-provider-registry.js +20 -1
  31. package/dist/services/openai-provider-registry.js.map +1 -1
  32. package/dist/services/panel-secrets.js +58 -7
  33. package/dist/services/panel-secrets.js.map +1 -1
  34. package/dist/services/process-control.js +154 -4
  35. package/dist/services/process-control.js.map +1 -1
  36. package/dist/services/runpod-client.js +157 -9
  37. package/dist/services/runpod-client.js.map +1 -1
  38. package/dist/services/runpod-ssh.js +594 -0
  39. package/dist/services/runpod-ssh.js.map +1 -0
  40. package/dist/services/runpod-watch.js +192 -13
  41. package/dist/services/runpod-watch.js.map +1 -1
  42. package/dist/services/secure-bridge.js +22 -6
  43. package/dist/services/secure-bridge.js.map +1 -1
  44. package/dist/services/trainer-bootstrap.js +142 -0
  45. package/dist/services/trainer-bootstrap.js.map +1 -0
  46. package/dist/services/training-config.js +4 -1
  47. package/dist/services/training-config.js.map +1 -1
  48. package/dist/services/training-jobs.js +1332 -253
  49. package/dist/services/training-jobs.js.map +1 -1
  50. package/dist/tools/apps.js +222 -0
  51. package/dist/tools/apps.js.map +1 -0
  52. package/dist/tools/index.js +4 -0
  53. package/dist/tools/index.js.map +1 -1
  54. package/dist/tools/missing-models.js +151 -0
  55. package/dist/tools/missing-models.js.map +1 -0
  56. package/dist/tools/process-control.js +1 -1
  57. package/dist/tools/process-control.js.map +1 -1
  58. package/dist/tools/runpod.js +205 -17
  59. package/dist/tools/runpod.js.map +1 -1
  60. package/dist/tools/train.js +138 -5
  61. package/dist/tools/train.js.map +1 -1
  62. package/docker/trainer/Dockerfile +4 -2
  63. package/package.json +1 -1
  64. package/scripts/gen-tool-docs.ts +43 -4
@@ -8,17 +8,54 @@
8
8
  //
9
9
  // This no-ops entirely when COMFYUI_MCP_PROGRESS_DIR is unset — i.e. for every
10
10
  // normal (non-panel) use of the MCP — so it costs nothing outside the panel.
11
- import { mkdirSync, writeFileSync, rmSync } from "node:fs";
12
- import { join } from "node:path";
11
+ import { mkdirSync, readFileSync, readdirSync, writeFileSync, rmSync } from "node:fs";
12
+ import { createHash } from "node:crypto";
13
+ import { basename, dirname, join } from "node:path";
13
14
  const PROGRESS_DIR = process.env.COMFYUI_MCP_PROGRESS_DIR || "";
15
+ /** Late-bound by the ORCHESTRATOR at startup (its own process has no env var —
16
+ * codex finding: the control channel was dead for in-process direct/mobile
17
+ * tool calls). progressEnabled() stays env-only on purpose: runpod.ts uses it
18
+ * as the spawned-child discriminator, and the orchestrator is NOT a child. */
19
+ let lateBoundDir = "";
20
+ export function setProgressDir(dir) {
21
+ lateBoundDir = dir;
22
+ }
23
+ function channelDir() {
24
+ return PROGRESS_DIR || lateBoundDir;
25
+ }
14
26
  const lastWriteAt = new Map();
15
27
  /** True when running under the panel orchestrator (progress channel is active). */
16
28
  export function progressEnabled() {
17
29
  return !!PROGRESS_DIR;
18
30
  }
19
- function fileFor(id) {
31
+ function fileFor(id, target) {
20
32
  // The id is a hex hash from callers, but stay defensive about the filename.
21
- return join(PROGRESS_DIR, `${id.replace(/[^a-zA-Z0-9_.-]/g, "_")}.json`);
33
+ // Include a TARGET discriminator (codex finding: the same URL downloaded for
34
+ // local AND pod concurrently shared one file — the last writer's target won
35
+ // the per-pod idle veto and a pod could be auto-stopped mid-transfer).
36
+ const disc = createHash("sha1")
37
+ .update(target ?? `pid:${process.pid}`)
38
+ .digest("hex")
39
+ .slice(0, 8);
40
+ return join(PROGRESS_DIR, `${id.replace(/[^a-zA-Z0-9_.-]/g, "_")}-${disc}.json`);
41
+ }
42
+ /** Credential-free form of a target URL for persisted rows / control files:
43
+ * strips userinfo (https://user:pass@host) before anything hits disk or a
44
+ * bridge frame (codex finding — raw COMFYUI_URL was being broadcast). */
45
+ function redactUrl(raw) {
46
+ try {
47
+ const u = new URL(raw);
48
+ u.username = "";
49
+ u.password = "";
50
+ // Query/fragment can carry credentials too (?token=secret) — the contract
51
+ // is credential-free before disk/broadcast (codex finding).
52
+ u.search = "";
53
+ u.hash = "";
54
+ return u.toString().replace(/\/+$/, "");
55
+ }
56
+ catch {
57
+ return raw.split("@").pop() ?? raw; // unparseable — drop anything before the last @
58
+ }
22
59
  }
23
60
  /**
24
61
  * Write a progress snapshot for one download. The in-flight "downloading" state
@@ -36,19 +73,152 @@ export function reportDownloadProgress(p, force = false) {
36
73
  lastWriteAt.set(p.id, now);
37
74
  try {
38
75
  mkdirSync(PROGRESS_DIR, { recursive: true });
39
- writeFileSync(fileFor(p.id), JSON.stringify({ ...p, updated: now }));
76
+ // Stamp the writer's OWN target (the spawned MCP child's COMFYUI_URL): the
77
+ // idle-stop veto scopes by it, and after a retarget the respawned child
78
+ // reports against the new host while stale rows age out (codex finding:
79
+ // a process-wide count let any download disable any pod's auto-stop).
80
+ // Redacted — target URLs can carry userinfo (codex finding).
81
+ const rawTarget = p.target ?? (process.env.COMFYUI_URL?.trim() || undefined);
82
+ const target = rawTarget ? redactUrl(rawTarget) : undefined;
83
+ writeFileSync(fileFor(p.id, target), JSON.stringify({ ...p, target, updated: now }));
40
84
  }
41
85
  catch {
42
86
  // best-effort — progress is cosmetic, never fail a download over it
43
87
  }
44
88
  }
45
- /** Remove a download's progress file (e.g. on cancel). */
89
+ /** Remove a download's progress file(s) (e.g. on cancel). Target-scoped files
90
+ * share the id prefix, so clear every variant for the logical download. */
46
91
  export function clearDownloadProgress(id) {
47
92
  if (!PROGRESS_DIR)
48
93
  return;
49
94
  lastWriteAt.delete(id);
50
95
  try {
51
- rmSync(fileFor(id), { force: true });
96
+ const prefix = `${id.replace(/[^a-zA-Z0-9_.-]/g, "_")}-`;
97
+ for (const f of readdirSync(PROGRESS_DIR)) {
98
+ if (f.startsWith(prefix) && f.endsWith(".json"))
99
+ rmSync(join(PROGRESS_DIR, f), { force: true });
100
+ }
101
+ }
102
+ catch {
103
+ // ignore
104
+ }
105
+ }
106
+ const CONTROL_TTL_MS = 60_000; // a request older than this is stale — ignore
107
+ /** Per-request control files are prefixed so the orchestrator consumes EXACTLY
108
+ * the file it read (no read-then-delete race between agent children, and no
109
+ * timestamp-collision identity problems — codex finding). Kept OUT of
110
+ * pollDownloads' tray rows via the "control-" prefix (applied-acks too). */
111
+ export const CONTROL_PREFIX = "control-";
112
+ const REQUEST_PREFIX = `${CONTROL_PREFIX}target-`;
113
+ const APPLIED_PREFIX = `${CONTROL_PREFIX}applied-`;
114
+ let controlSeq = 0;
115
+ function controlDirPath(dir = channelDir()) {
116
+ return dir || null;
117
+ }
118
+ /** Ask the orchestrator to retarget (+ optionally watch a pod). Returns the
119
+ * request file path (for awaitTargetApplied), or null when the channel is
120
+ * inactive (no progress dir). */
121
+ export function requestTargetChange(req) {
122
+ const dir = controlDirPath();
123
+ if (!dir)
124
+ return null;
125
+ try {
126
+ mkdirSync(dir, { recursive: true });
127
+ // Redact any credential-bearing target URL before it touches disk (codex).
128
+ const safe = {
129
+ ...req,
130
+ ...(req.url ? { url: redactUrl(req.url) } : {}),
131
+ ...(req.connectWhenReady ? { connectWhenReady: { ...req.connectWhenReady, url: redactUrl(req.connectWhenReady.url) } } : {}),
132
+ };
133
+ // Unique-per-request file: consumption deletes exactly this name — a second
134
+ // child's request can never be clobbered by the first's delete.
135
+ const file = join(dir, `${REQUEST_PREFIX}${process.pid}-${Date.now()}-${controlSeq++}.json`);
136
+ writeFileSync(file, JSON.stringify({ ...safe, updated: Date.now() }));
137
+ return file;
138
+ }
139
+ catch {
140
+ return null; // best-effort — the caller's own retarget still happened
141
+ }
142
+ }
143
+ /** The ack file the orchestrator writes after applying a given request file. */
144
+ function appliedFileFor(requestFile) {
145
+ return join(dirname(requestFile), `${APPLIED_PREFIX}${basename(requestFile).slice(REQUEST_PREFIX.length)}`);
146
+ }
147
+ /** Child side: wait for the orchestrator to apply our request and report the
148
+ * RESULTING target (its own remembered LAN fallback included — the child
149
+ * can't compute it, codex finding). Returns the ack, or null on timeout —
150
+ * callers must then report honestly rather than guess 127.0.0.1. */
151
+ export async function awaitTargetApplied(requestFile, timeoutMs = 4_000) {
152
+ const ack = appliedFileFor(requestFile);
153
+ const start = Date.now();
154
+ for (;;) {
155
+ try {
156
+ const raw = JSON.parse(readFileSync(ack, "utf-8"));
157
+ if (typeof raw?.url === "string") {
158
+ rmSync(ack, { force: true }); // consumed — don't leak it into a later poll
159
+ return { url: raw.url, applied: raw.applied !== false };
160
+ }
161
+ }
162
+ catch {
163
+ // not applied yet
164
+ }
165
+ if (Date.now() - start > timeoutMs)
166
+ return null;
167
+ await new Promise((r) => setTimeout(r, 150));
168
+ }
169
+ }
170
+ /** Orchestrator side: all fresh pending requests (within TTL), oldest first.
171
+ * The dir is EXPLICIT: the orchestrator computes progressDir itself while the
172
+ * module-level env capture is unset in its own process (codex finding — the
173
+ * channel was write-only: children stamped, nobody read). */
174
+ export function listTargetChangeRequests(dir) {
175
+ const out = [];
176
+ let files = [];
177
+ try {
178
+ files = readdirSync(dir).filter((f) => f.startsWith(REQUEST_PREFIX) && f.endsWith(".json"));
179
+ }
180
+ catch {
181
+ return out;
182
+ }
183
+ for (const f of files) {
184
+ try {
185
+ const file = join(dir, f);
186
+ const raw = JSON.parse(readFileSync(file, "utf-8"));
187
+ if (typeof raw?.updated !== "number")
188
+ continue;
189
+ if (!raw.url && !raw.local && !raw.watchPodId && !raw.unwatch && !raw.connectWhenReady && !raw.stoppedPodId)
190
+ continue;
191
+ if (Date.now() - raw.updated > CONTROL_TTL_MS) {
192
+ rmSync(file, { force: true }); // reap stale requests while we're here
193
+ continue;
194
+ }
195
+ out.push({ req: raw, file });
196
+ }
197
+ catch {
198
+ // mid-write or corrupt — retry next tick
199
+ }
200
+ }
201
+ return out.sort((a, b) => a.req.updated - b.req.updated);
202
+ }
203
+ /** Orchestrator side: after applying a request, ack it with the RESULTING
204
+ * target so the requesting child can align its own process to the TRUE
205
+ * fallback/target (it can't compute the orchestrator's remembered LAN URL —
206
+ * codex finding). `applied` reports whether a guarded (onlyIfTarget) request
207
+ * was actually applied — a guarded-out request must not read as a successful
208
+ * local switch (codex finding). Best-effort; the child times out gracefully. */
209
+ export function ackTargetChange(requestFile, url, applied = true) {
210
+ try {
211
+ writeFileSync(appliedFileFor(requestFile), JSON.stringify({ url, applied, updated: Date.now() }));
212
+ }
213
+ catch {
214
+ // ignore
215
+ }
216
+ }
217
+ /** Orchestrator side: consume one applied request file (exactly the file that
218
+ * was read — never a newer replacement, since each request is its own file). */
219
+ export function consumeTargetChange(file) {
220
+ try {
221
+ rmSync(file, { force: true });
52
222
  }
53
223
  catch {
54
224
  // ignore
@@ -1 +1 @@
1
- {"version":3,"file":"download-progress.js","sourceRoot":"","sources":["../../src/services/download-progress.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,EAAE;AACF,+EAA+E;AAC/E,iFAAiF;AACjF,8EAA8E;AAC9E,iFAAiF;AACjF,wEAAwE;AACxE,EAAE;AACF,+EAA+E;AAC/E,6EAA6E;AAE7E,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAmBjC,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,IAAI,EAAE,CAAC;AAChE,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;AAE9C,mFAAmF;AACnF,MAAM,UAAU,eAAe;IAC7B,OAAO,CAAC,CAAC,YAAY,CAAC;AACxB,CAAC;AAED,SAAS,OAAO,CAAC,EAAU;IACzB,4EAA4E;IAC5E,OAAO,IAAI,CAAC,YAAY,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;AAC3E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CACpC,CAAoC,EACpC,KAAK,GAAG,KAAK;IAEb,IAAI,CAAC,YAAY;QAAE,OAAO;IAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,KAAK,aAAa,EAAE,CAAC;QACzC,IAAI,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG;YAAE,OAAO;IACvD,CAAC;IACD,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IAC3B,IAAI,CAAC;QACH,SAAS,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7C,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;IACvE,CAAC;IAAC,MAAM,CAAC;QACP,oEAAoE;IACtE,CAAC;AACH,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,qBAAqB,CAAC,EAAU;IAC9C,IAAI,CAAC,YAAY;QAAE,OAAO;IAC1B,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACvB,IAAI,CAAC;QACH,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,SAAS;IACX,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"download-progress.js","sourceRoot":"","sources":["../../src/services/download-progress.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,EAAE;AACF,+EAA+E;AAC/E,iFAAiF;AACjF,8EAA8E;AAC9E,iFAAiF;AACjF,wEAAwE;AACxE,EAAE;AACF,+EAA+E;AAC/E,6EAA6E;AAE7E,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACtF,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAwBpD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,IAAI,EAAE,CAAC;AAChE;;;+EAG+E;AAC/E,IAAI,YAAY,GAAG,EAAE,CAAC;AACtB,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,YAAY,GAAG,GAAG,CAAC;AACrB,CAAC;AACD,SAAS,UAAU;IACjB,OAAO,YAAY,IAAI,YAAY,CAAC;AACtC,CAAC;AACD,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;AAE9C,mFAAmF;AACnF,MAAM,UAAU,eAAe;IAC7B,OAAO,CAAC,CAAC,YAAY,CAAC;AACxB,CAAC;AAED,SAAS,OAAO,CAAC,EAAU,EAAE,MAAe;IAC1C,4EAA4E;IAC5E,6EAA6E;IAC7E,4EAA4E;IAC5E,uEAAuE;IACvE,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC;SAC5B,MAAM,CAAC,MAAM,IAAI,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC;SACtC,MAAM,CAAC,KAAK,CAAC;SACb,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACf,OAAO,IAAI,CAAC,YAAY,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,CAAC;AACnF,CAAC;AAED;;0EAE0E;AAC1E,SAAS,SAAS,CAAC,GAAW;IAC5B,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QACvB,CAAC,CAAC,QAAQ,GAAG,EAAE,CAAC;QAChB,CAAC,CAAC,QAAQ,GAAG,EAAE,CAAC;QAChB,0EAA0E;QAC1E,4DAA4D;QAC5D,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC;QACd,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC;QACZ,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,GAAG,CAAC,CAAC,gDAAgD;IACtF,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CACpC,CAAoC,EACpC,KAAK,GAAG,KAAK;IAEb,IAAI,CAAC,YAAY;QAAE,OAAO;IAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,KAAK,aAAa,EAAE,CAAC;QACzC,IAAI,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG;YAAE,OAAO;IACvD,CAAC;IACD,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IAC3B,IAAI,CAAC;QACH,SAAS,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7C,2EAA2E;QAC3E,wEAAwE;QACxE,wEAAwE;QACxE,sEAAsE;QACtE,6DAA6D;QAC7D,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC,CAAC;QAC7E,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC5D,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;IACvF,CAAC;IAAC,MAAM,CAAC;QACP,oEAAoE;IACtE,CAAC;AACH,CAAC;AAED;4EAC4E;AAC5E,MAAM,UAAU,qBAAqB,CAAC,EAAU;IAC9C,IAAI,CAAC,YAAY;QAAE,OAAO;IAC1B,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACvB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,GAAG,CAAC;QACzD,KAAK,MAAM,CAAC,IAAI,WAAW,CAAC,YAAY,CAAC,EAAE,CAAC;YAC1C,IAAI,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAAE,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAClG,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,SAAS;IACX,CAAC;AACH,CAAC;AAqDD,MAAM,cAAc,GAAG,MAAM,CAAC,CAAC,8CAA8C;AAC7E;;;6EAG6E;AAC7E,MAAM,CAAC,MAAM,cAAc,GAAG,UAAU,CAAC;AACzC,MAAM,cAAc,GAAG,GAAG,cAAc,SAAS,CAAC;AAClD,MAAM,cAAc,GAAG,GAAG,cAAc,UAAU,CAAC;AACnD,IAAI,UAAU,GAAG,CAAC,CAAC;AAEnB,SAAS,cAAc,CAAC,MAAc,UAAU,EAAE;IAChD,OAAO,GAAG,IAAI,IAAI,CAAC;AACrB,CAAC;AAED;;kCAEkC;AAClC,MAAM,UAAU,mBAAmB,CAAC,GAAyC;IAC3E,MAAM,GAAG,GAAG,cAAc,EAAE,CAAC;IAC7B,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,IAAI,CAAC;QACH,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACpC,2EAA2E;QAC3E,MAAM,IAAI,GAAyC;YACjD,GAAG,GAAG;YACN,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/C,GAAG,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,EAAE,GAAG,GAAG,CAAC,gBAAgB,EAAE,GAAG,EAAE,SAAS,CAAC,GAAG,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC7H,CAAC;QACF,4EAA4E;QAC5E,gEAAgE;QAChE,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,cAAc,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,UAAU,EAAE,OAAO,CAAC,CAAC;QAC7F,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;QACtE,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC,CAAC,yDAAyD;IACxE,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,SAAS,cAAc,CAAC,WAAmB;IACzC,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,GAAG,cAAc,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAC9G,CAAC;AAED;;;qEAGqE;AACrE,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,WAAmB,EAAE,SAAS,GAAG,KAAK;IAC7E,MAAM,GAAG,GAAG,cAAc,CAAC,WAAW,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,SAAS,CAAC;QACR,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,EAAE,OAAO,CAAC,CAAwC,CAAC;YAC1F,IAAI,OAAO,GAAG,EAAE,GAAG,KAAK,QAAQ,EAAE,CAAC;gBACjC,MAAM,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,6CAA6C;gBAC3E,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;YAC1D,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,kBAAkB;QACpB,CAAC;QACD,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,SAAS;YAAE,OAAO,IAAI,CAAC;QAChD,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC;AAOD;;;8DAG8D;AAC9D,MAAM,UAAU,wBAAwB,CAAC,GAAW;IAClD,MAAM,GAAG,GAA0B,EAAE,CAAC;IACtC,IAAI,KAAK,GAAa,EAAE,CAAC;IACzB,IAAI,CAAC;QACH,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;IAC9F,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAC;IACb,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAwB,CAAC;YAC3E,IAAI,OAAO,GAAG,EAAE,OAAO,KAAK,QAAQ;gBAAE,SAAS;YAC/C,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,GAAG,CAAC,UAAU,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,gBAAgB,IAAI,CAAC,GAAG,CAAC,YAAY;gBAAE,SAAS;YACtH,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,CAAC,OAAO,GAAG,cAAc,EAAE,CAAC;gBAC9C,MAAM,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,uCAAuC;gBACtE,SAAS;YACX,CAAC;YACD,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/B,CAAC;QAAC,MAAM,CAAC;YACP,yCAAyC;QAC3C,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAC3D,CAAC;AAED;;;;;iFAKiF;AACjF,MAAM,UAAU,eAAe,CAAC,WAAmB,EAAE,GAAW,EAAE,OAAO,GAAG,IAAI;IAC9E,IAAI,CAAC;QACH,aAAa,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;IACpG,CAAC;IAAC,MAAM,CAAC;QACP,SAAS;IACX,CAAC;AACH,CAAC;AAED;iFACiF;AACjF,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,IAAI,CAAC;QACH,MAAM,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,SAAS;IACX,CAAC;AACH,CAAC"}
@@ -0,0 +1,295 @@
1
+ // Missing-model resolution: figure out which model files a workflow wants but
2
+ // this ComfyUI doesn't have, then find installable candidates for them.
3
+ //
4
+ // WHY THIS EXISTS: `extract_workflow_dependencies` / `install_workflow_dependencies`
5
+ // resolve the custom NODE PACKS a workflow needs — they never touch the missing
6
+ // MODEL side of the same problem. So "open this Template and make it runnable"
7
+ // took two manual hops: the agent had to infer which checkpoint/VAE/LoRA was
8
+ // missing, then find it itself. Reported in the help channel (seanmcmagic).
9
+ //
10
+ // DETECTION: we do NOT hardcode widget names. ComfyUI publishes every model
11
+ // selector as a COMBO whose options are the server's ACTUAL filenames:
12
+ //
13
+ // CheckpointLoaderSimple.input.required.ckpt_name = [["a.safetensors", …], {…}]
14
+ //
15
+ // So a workflow value that is a model-looking filename and is NOT in its combo's
16
+ // option list is missing — which covers every model type, including ones from
17
+ // custom packs we've never heard of, with no per-node mapping to maintain.
18
+ //
19
+ // SIZE IS NOT VRAM: weights are the floor, not the ceiling (activations, latents
20
+ // and context sit on top), so `fitVerdict` deliberately reserves headroom rather
21
+ // than pretending file size == requirement.
22
+ /** Weight-file extensions. Used to tell a model value from an ordinary enum. */
23
+ const MODEL_EXTS = new Set([".safetensors", ".ckpt", ".pt", ".pth", ".bin", ".gguf", ".sft", ".onnx"]);
24
+ /** Widget name → models/ subdirectory. Only used to say WHERE a download should
25
+ * land; detection never depends on it, so an unknown widget degrades to
26
+ * `undefined` rather than dropping the missing model. */
27
+ const DIR_BY_WIDGET = {
28
+ ckpt_name: "checkpoints",
29
+ lora_name: "loras",
30
+ vae_name: "vae",
31
+ control_net_name: "controlnet",
32
+ controlnet_name: "controlnet",
33
+ unet_name: "diffusion_models",
34
+ model_name: "upscale_models",
35
+ clip_name: "text_encoders",
36
+ clip_name1: "text_encoders",
37
+ clip_name2: "text_encoders",
38
+ style_model_name: "style_models",
39
+ embedding_name: "embeddings",
40
+ gligen_name: "gligen",
41
+ hypernetwork_name: "hypernetworks",
42
+ ipadapter_file: "ipadapter",
43
+ };
44
+ /** Strip directory + extension, lowercase — the comparable identity of a model. */
45
+ export function fileStem(name) {
46
+ const base = name.split(/[/\\]/).pop() ?? name;
47
+ return base.replace(/\.[^.]+$/, "").toLowerCase();
48
+ }
49
+ function hasModelExt(name) {
50
+ const base = name.split(/[/\\]/).pop() ?? name;
51
+ const dot = base.lastIndexOf(".");
52
+ if (dot < 0)
53
+ return false;
54
+ return MODEL_EXTS.has(base.slice(dot).toLowerCase());
55
+ }
56
+ /**
57
+ * Read the precision / quantisation out of a weight filename.
58
+ *
59
+ * This is what makes a fuzzy match set useful instead of opaque: the same model
60
+ * ships as fp16 / fp8 / several GGUF quants at wildly different sizes, and on a
61
+ * constrained GPU the quantised one is the whole answer.
62
+ *
63
+ * GGUF is checked FIRST: a name can contain both "gguf" and a dtype-looking
64
+ * token, and the container is what decides whether it loads at all.
65
+ */
66
+ export function classifyPrecision(filename) {
67
+ const n = filename.toLowerCase();
68
+ if (/\.gguf$|[-_.]gguf\b/.test(n)) {
69
+ // Q4_K_M, Q6_K, Q8_0, IQ3_XXS …
70
+ const m = n.match(/\b(iq|q)(\d+)(_[a-z0-9]+)*\b/);
71
+ return {
72
+ precision: "gguf",
73
+ quant: m ? m[0].toUpperCase() : undefined,
74
+ requiresPack: "ComfyUI-GGUF",
75
+ };
76
+ }
77
+ if (/\bnf4\b/.test(n))
78
+ return { precision: "nf4" };
79
+ // fp8_e4m3fn / fp8_e5m2 / float8
80
+ if (/\bfp8\b|\bfloat8\b|e4m3|e5m2/.test(n))
81
+ return { precision: "fp8" };
82
+ if (/\bbf16\b|\bbfloat16\b/.test(n))
83
+ return { precision: "bf16" };
84
+ if (/\bfp16\b|\bfloat16\b|\bhalf\b/.test(n))
85
+ return { precision: "fp16" };
86
+ if (/\bfp32\b|\bfloat32\b|\bfull\b/.test(n))
87
+ return { precision: "fp32" };
88
+ return { precision: "unknown" };
89
+ }
90
+ /**
91
+ * Can this file plausibly run on a card with `vramBytes` of VRAM?
92
+ *
93
+ * Weights are the floor, not the ceiling — activations/latents/context also live
94
+ * in VRAM — so we reserve headroom instead of claiming a 15.9 GB file "fits" a
95
+ * 16 GB card. Anything above 80% of VRAM is reported as `tight`, not `fits`.
96
+ */
97
+ export function fitVerdict(sizeBytes, vramBytes) {
98
+ if (!sizeBytes || !vramBytes || sizeBytes <= 0 || vramBytes <= 0)
99
+ return "unknown";
100
+ const ratio = sizeBytes / vramBytes;
101
+ if (ratio > 1)
102
+ return "too_big";
103
+ if (ratio > 0.8)
104
+ return "tight";
105
+ return "fits";
106
+ }
107
+ /** How well does `candidate` answer the request for `wanted`? */
108
+ export function matchQuality(wanted, candidate) {
109
+ const w = (wanted.split(/[/\\]/).pop() ?? wanted).toLowerCase();
110
+ const c = (candidate.split(/[/\\]/).pop() ?? candidate).toLowerCase();
111
+ if (w === c)
112
+ return "exact";
113
+ if (fileStem(wanted) === fileStem(candidate))
114
+ return "stem";
115
+ return "fuzzy";
116
+ }
117
+ const MATCH_RANK = { exact: 0, stem: 1, fuzzy: 2 };
118
+ const FIT_RANK = { fits: 0, tight: 1, unknown: 2, too_big: 3 };
119
+ /**
120
+ * Order candidates the way a human would pick: closest name first, then what
121
+ * actually fits the card, then larger (higher-quality) files before smaller.
122
+ * Stable — equal candidates keep their input order.
123
+ */
124
+ export function rankCandidates(wanted, candidates) {
125
+ return candidates
126
+ .map((c, i) => ({ ...c, match: matchQuality(wanted, c.filename), _i: i }))
127
+ .sort((a, b) => {
128
+ const m = MATCH_RANK[a.match] - MATCH_RANK[b.match];
129
+ if (m !== 0)
130
+ return m;
131
+ const f = FIT_RANK[a.fit ?? "unknown"] - FIT_RANK[b.fit ?? "unknown"];
132
+ if (f !== 0)
133
+ return f;
134
+ const s = (b.size_bytes ?? 0) - (a.size_bytes ?? 0);
135
+ if (s !== 0)
136
+ return s;
137
+ return a._i - b._i;
138
+ })
139
+ .map(({ _i, ...rest }) => rest);
140
+ }
141
+ /** The combo option list for an input spec, or null when it isn't a combo. */
142
+ function comboOptions(spec) {
143
+ if (!Array.isArray(spec) || spec.length === 0)
144
+ return null;
145
+ const first = spec[0];
146
+ if (!Array.isArray(first))
147
+ return null;
148
+ return first.filter((o) => typeof o === "string");
149
+ }
150
+ /**
151
+ * Find every model a workflow references that this server does not have.
152
+ *
153
+ * A value counts as a missing model when its input is a COMBO (so the server
154
+ * published the set it actually has) and the value is a model-looking filename
155
+ * absent from that set. Connections (`[nodeId, slot]` arrays) and non-model
156
+ * enums are ignored.
157
+ *
158
+ * `directory` is a best-effort hint for where a download should land; it is
159
+ * never required, so an unrecognised widget still reports its missing model.
160
+ */
161
+ export function findMissingModels(workflow, objectInfo) {
162
+ const missing = [];
163
+ const seen = new Set();
164
+ for (const [nodeId, rawNode] of Object.entries(workflow)) {
165
+ if (!rawNode || typeof rawNode !== "object")
166
+ continue;
167
+ const node = rawNode;
168
+ const classType = node.class_type;
169
+ if (!classType || !node.inputs)
170
+ continue;
171
+ const def = objectInfo[classType];
172
+ if (!def?.input)
173
+ continue;
174
+ const specs = { ...(def.input.required ?? {}), ...(def.input.optional ?? {}) };
175
+ for (const [widget, value] of Object.entries(node.inputs)) {
176
+ // A wired connection, not a widget value.
177
+ if (Array.isArray(value))
178
+ continue;
179
+ if (typeof value !== "string" || value.length === 0)
180
+ continue;
181
+ const options = comboOptions(specs[widget]);
182
+ if (!options)
183
+ continue; // not a combo → not a model selector
184
+ if (options.includes(value))
185
+ continue; // present on this server
186
+ // Only claim "missing MODEL" when it looks like a weight file — otherwise
187
+ // it's an ordinary enum drift and not ours to fix.
188
+ if (!hasModelExt(value) && !options.some(hasModelExt))
189
+ continue;
190
+ const key = `${value.toLowerCase()}|${widget}`;
191
+ if (seen.has(key))
192
+ continue;
193
+ seen.add(key);
194
+ missing.push({
195
+ node_id: nodeId,
196
+ node_type: classType,
197
+ widget,
198
+ name: value,
199
+ directory: DIR_BY_WIDGET[widget],
200
+ });
201
+ }
202
+ }
203
+ return missing;
204
+ }
205
+ /** models/ subdir → CivitAI `types` filter, so a LoRA hunt can't return checkpoints. */
206
+ const CIVITAI_TYPE_BY_DIR = {
207
+ checkpoints: ["Checkpoint"],
208
+ loras: ["LORA", "LoCon"],
209
+ vae: ["VAE"],
210
+ controlnet: ["Controlnet"],
211
+ embeddings: ["TextualInversion"],
212
+ upscale_models: ["Upscaler"],
213
+ };
214
+ const MB = 1024 * 1024;
215
+ /**
216
+ * Find installable candidates for ONE missing model, annotated with precision,
217
+ * size and whether it fits this GPU, best first.
218
+ *
219
+ * Deliberately does NOT auto-pick: the same filename ships across quants and
220
+ * base models, so we return a ranked, annotated list and let the caller decide.
221
+ * Network failures degrade to fewer candidates rather than failing the lookup —
222
+ * a partial answer beats none when one provider is down.
223
+ */
224
+ export async function resolveCandidates(missing, deps, opts = {}) {
225
+ const limit = opts.limit ?? 8;
226
+ const query = fileStem(missing.name);
227
+ const vram = await deps.vramBytes().catch(() => undefined);
228
+ const out = [];
229
+ const civitaiTypes = missing.directory ? CIVITAI_TYPE_BY_DIR[missing.directory] : undefined;
230
+ const hits = await deps.searchCivitai(query, civitaiTypes).catch(() => []);
231
+ for (const h of hits) {
232
+ const size = typeof h.size_mb === "number" ? Math.round(h.size_mb * MB) : undefined;
233
+ const p = classifyPrecision(h.name);
234
+ out.push({
235
+ filename: h.name,
236
+ source: "civitai",
237
+ civitai_model_id: h.model_id,
238
+ civitai_version_id: h.version_id,
239
+ size_bytes: size,
240
+ precision: p.precision,
241
+ quant: p.quant,
242
+ requires_pack: p.requiresPack,
243
+ base_model: h.base_model,
244
+ fit: fitVerdict(size, vram),
245
+ });
246
+ }
247
+ // Expand generously: the QUANTISED repo (e.g. city96/FLUX.1-dev-gguf) is
248
+ // routinely ranked below the official one, and on a constrained GPU it is the
249
+ // only candidate that actually helps — slicing too tightly drops exactly the
250
+ // answer the user needs.
251
+ const repos = await deps.searchHf(query).catch(() => []);
252
+ for (const repo of repos.slice(0, 6)) {
253
+ const files = await deps.hfRepoFiles(repo.id).catch(() => []);
254
+ for (const f of files) {
255
+ const p = classifyPrecision(f.filename);
256
+ out.push({
257
+ filename: f.filename,
258
+ source: "huggingface",
259
+ url: `https://huggingface.co/${repo.id}/resolve/main/${f.filename}`,
260
+ size_bytes: f.size_bytes,
261
+ precision: p.precision,
262
+ quant: p.quant,
263
+ requires_pack: p.requiresPack,
264
+ fit: fitVerdict(f.size_bytes, vram),
265
+ });
266
+ }
267
+ }
268
+ return rankCandidates(missing.name, dedupeCandidates(out)).slice(0, limit);
269
+ }
270
+ /**
271
+ * Collapse the same file offered by several repos/providers into one row.
272
+ *
273
+ * Popular weights are mirrored widely, so an un-deduped list wastes most of its
274
+ * slots showing `flux1-dev.safetensors` three times instead of the fp8 and GGUF
275
+ * variants that are the actual reason to look. Keyed on filename + precision +
276
+ * quant so genuinely different builds stay distinct; the entry that knows its
277
+ * size wins, since size drives the fit verdict.
278
+ */
279
+ export function dedupeCandidates(candidates) {
280
+ const best = new Map();
281
+ for (const c of candidates) {
282
+ const key = `${(c.filename.split(/[/\\]/).pop() ?? c.filename).toLowerCase()}|${c.precision}|${c.quant ?? ""}`;
283
+ const prev = best.get(key);
284
+ if (!prev) {
285
+ best.set(key, c);
286
+ continue;
287
+ }
288
+ const prevKnows = typeof prev.size_bytes === "number" && prev.size_bytes > 0;
289
+ const nextKnows = typeof c.size_bytes === "number" && c.size_bytes > 0;
290
+ if (!prevKnows && nextKnows)
291
+ best.set(key, c);
292
+ }
293
+ return [...best.values()];
294
+ }
295
+ //# sourceMappingURL=missing-models.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"missing-models.js","sourceRoot":"","sources":["../../src/services/missing-models.ts"],"names":[],"mappings":"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"}
@@ -31,7 +31,7 @@ export const OPENAI_KEY_PROVIDERS = [
31
31
  {
32
32
  id: "glm",
33
33
  slotLabel: "GLM / Zhipu",
34
- slotHelp: "GLM provider",
34
+ slotHelp: "Z.AI Coding Plan (GLM / Zhipu)",
35
35
  envKeys: ["GLM_API_KEY", "ZHIPU_API_KEY", "ZHIPUAI_API_KEY", "ZAI_API_KEY"],
36
36
  modelEnv: "COMFYUI_MCP_GLM_MODEL",
37
37
  defaultModel: process.env.COMFYUI_MCP_GLM_MODEL?.trim() || "glm-4.7",
@@ -84,4 +84,23 @@ export function simpleKeyProvider(id) {
84
84
  export function openAiKeyProviderModel(p) {
85
85
  return process.env[p.modelEnv] ?? p.defaultModel;
86
86
  }
87
+ /**
88
+ * One-line "which model am I on, and how do I change it?" hint for the panel's
89
+ * API Keys card.
90
+ *
91
+ * These providers ship a pinned default (glm-4.7, kimi-for-coding, kimi-k3) and
92
+ * a `modelEnv` override, but NOTHING in the UI ever said the override existed —
93
+ * so a user on a newer model (e.g. GLM 5.2) had no way to discover they could
94
+ * point at it without reading the source. Generated from the registry rather
95
+ * than hand-written per provider, so it can never drift from the real default.
96
+ *
97
+ * Reports the ACTIVE model (env override if set, else the default) and names the
98
+ * env var either way, so the card also answers "why am I not on the model I set?".
99
+ */
100
+ export function providerModelHint(p) {
101
+ const active = openAiKeyProviderModel(p);
102
+ return active === p.defaultModel
103
+ ? `Model ${active} (default) — set ${p.modelEnv} to use another.`
104
+ : `Model ${active} (via ${p.modelEnv}; default ${p.defaultModel}).`;
105
+ }
87
106
  //# sourceMappingURL=openai-provider-registry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"openai-provider-registry.js","sourceRoot":"","sources":["../../src/services/openai-provider-registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"openai-provider-registry.js","sourceRoot":"","sources":["../../src/services/openai-provider-registry.ts"],"names":[],"mappings":"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"}