comfyui-mcp 0.30.0 → 0.31.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.
- package/README.md +17 -1
- package/dist/config.js +27 -1
- package/dist/config.js.map +1 -1
- package/dist/orchestrator/agent-backend.js +42 -0
- package/dist/orchestrator/agent-backend.js.map +1 -1
- package/dist/orchestrator/ai-proposer.js +106 -0
- package/dist/orchestrator/ai-proposer.js.map +1 -0
- package/dist/orchestrator/backend-readiness.js +78 -1
- package/dist/orchestrator/backend-readiness.js.map +1 -1
- package/dist/orchestrator/chatgpt-oauth-backend.js +349 -0
- package/dist/orchestrator/chatgpt-oauth-backend.js.map +1 -0
- package/dist/orchestrator/claude-backend.js +8 -0
- package/dist/orchestrator/claude-backend.js.map +1 -1
- package/dist/orchestrator/copilot-backend.js +265 -0
- package/dist/orchestrator/copilot-backend.js.map +1 -0
- package/dist/orchestrator/glm-backend.js +20 -0
- package/dist/orchestrator/glm-backend.js.map +1 -0
- package/dist/orchestrator/grok-backend.js +1470 -0
- package/dist/orchestrator/grok-backend.js.map +1 -0
- package/dist/orchestrator/history.js +181 -0
- package/dist/orchestrator/history.js.map +1 -0
- package/dist/orchestrator/index.js +620 -138
- package/dist/orchestrator/index.js.map +1 -1
- package/dist/orchestrator/kimi-backend.js +26 -0
- package/dist/orchestrator/kimi-backend.js.map +1 -0
- package/dist/orchestrator/oauth-bridge.js +92 -0
- package/dist/orchestrator/oauth-bridge.js.map +1 -0
- package/dist/orchestrator/oauth-bridge.test.js +129 -0
- package/dist/orchestrator/oauth-bridge.test.js.map +1 -0
- package/dist/orchestrator/ollama-backend.js +71 -8
- package/dist/orchestrator/ollama-backend.js.map +1 -1
- package/dist/orchestrator/panel-agent.js +25 -0
- package/dist/orchestrator/panel-agent.js.map +1 -1
- package/dist/orchestrator/panel-console-http.js +470 -0
- package/dist/orchestrator/panel-console-http.js.map +1 -0
- package/dist/orchestrator/panel-mcp-http.js +2 -2
- package/dist/orchestrator/panel-mcp-http.js.map +1 -1
- package/dist/orchestrator/panel-tools.js +71 -7
- package/dist/orchestrator/panel-tools.js.map +1 -1
- package/dist/services/a2ui-spec.js +207 -0
- package/dist/services/a2ui-spec.js.map +1 -0
- package/dist/services/a2ui-spec.test.js +174 -0
- package/dist/services/a2ui-spec.test.js.map +1 -0
- package/dist/services/civitai-lookup.js +5 -0
- package/dist/services/civitai-lookup.js.map +1 -1
- package/dist/services/civitai-resolver.js +160 -3
- package/dist/services/civitai-resolver.js.map +1 -1
- package/dist/services/code-provider-auth-redact.test.js +83 -0
- package/dist/services/code-provider-auth-redact.test.js.map +1 -0
- package/dist/services/code-provider-auth.js +561 -0
- package/dist/services/code-provider-auth.js.map +1 -0
- package/dist/services/comfy-cli.js +276 -0
- package/dist/services/comfy-cli.js.map +1 -0
- package/dist/services/download-cache.js +7 -1
- package/dist/services/download-cache.js.map +1 -1
- package/dist/services/lora-catalog.js +329 -0
- package/dist/services/lora-catalog.js.map +1 -0
- package/dist/services/model-resolver.js +65 -4
- package/dist/services/model-resolver.js.map +1 -1
- package/dist/services/node-management.js +36 -53
- package/dist/services/node-management.js.map +1 -1
- package/dist/services/oauth-flow.js +314 -0
- package/dist/services/oauth-flow.js.map +1 -0
- package/dist/services/oauth-flow.test.js +179 -0
- package/dist/services/oauth-flow.test.js.map +1 -0
- package/dist/services/oauth-landing.test.js +45 -0
- package/dist/services/oauth-landing.test.js.map +1 -0
- package/dist/services/panel-secrets.js +132 -1
- package/dist/services/panel-secrets.js.map +1 -1
- package/dist/services/prompt-overrides.js +103 -0
- package/dist/services/prompt-overrides.js.map +1 -0
- package/dist/services/ui-bridge.js +52 -2
- package/dist/services/ui-bridge.js.map +1 -1
- package/dist/services/workflow-health.js +13 -0
- package/dist/services/workflow-health.js.map +1 -1
- package/dist/services/workflow-target-store.js +64 -0
- package/dist/services/workflow-target-store.js.map +1 -0
- package/dist/tools/comfy-cli.js +257 -0
- package/dist/tools/comfy-cli.js.map +1 -0
- package/dist/tools/index.js +6 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/model-explorer.js +114 -0
- package/dist/tools/model-explorer.js.map +1 -0
- package/dist/tools/model-extras.js +146 -3
- package/dist/tools/model-extras.js.map +1 -1
- package/dist/tools/model-management.js +11 -2
- package/dist/tools/model-management.js.map +1 -1
- package/dist/tools/node-management.js +21 -10
- package/dist/tools/node-management.js.map +1 -1
- package/dist/tools/prompt-director.js +32 -0
- package/dist/tools/prompt-director.js.map +1 -0
- package/dist/tools/workflow-compose.js +67 -5
- package/dist/tools/workflow-compose.js.map +1 -1
- package/dist/utils/html-to-markdown.js +86 -0
- package/dist/utils/html-to-markdown.js.map +1 -0
- package/package.json +1 -1
- package/packs/ltx23-distill-3stage/install-runpod.sh +58 -0
- package/packs/ltx23-distill-3stage/install-windows.bat +63 -0
- package/packs/ltx23-distill-3stage/manifest.yaml +63 -0
- package/packs/ltx23-distill-3stage/pack.yaml +37 -0
- package/packs/ltx23-distill-3stage/workflow.json +906 -0
- package/plugin/.mcp.json +4 -8
- package/plugin/hooks/vram-check.mjs +52 -9
- package/plugin/skills/civitai/SKILL.md +52 -78
- package/plugin/skills/comfyui-core/SKILL.md +2 -2
- package/plugin/skills/local-llm-free/SKILL.md +2 -2
- package/scripts/check-pack-models.mjs +11 -1
- package/scripts/gen-tool-docs.ts +2 -0
- package/scripts/mock-panel.mjs +92 -52
- package/scripts/runpod-release.mjs +18 -2
- package/scripts/test-generate.mjs +61 -0
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
// GitHub Copilot chat backend — Task 5b of the in-panel OAuth plan.
|
|
2
|
+
// EXPERIMENTAL, ISOLATED, ToS-risk (the user explicitly accepted this when
|
|
3
|
+
// asking for it): a failure anywhere in this module must surface only as a
|
|
4
|
+
// normal turn/prepare error on THIS backend — it can never affect
|
|
5
|
+
// Grok/Codex/Claude/other backends. See OAUTH_PROVIDERS.copilot
|
|
6
|
+
// (experimental: true, in oauth-flow.ts) and oauth-bridge.ts's
|
|
7
|
+
// allow_experimental gate, which is what makes a `~/.comfyui-mcp/copilot-
|
|
8
|
+
// auth.json` ghu_ token exist in the first place.
|
|
9
|
+
//
|
|
10
|
+
// REUSE vs COPILOT-SPECIFIC:
|
|
11
|
+
// Copilot's chat endpoint is OpenAI chat-completions compatible, so this
|
|
12
|
+
// backend is a THIN subclass of OllamaBackend's "openai" dialect — exactly the
|
|
13
|
+
// GlmBackend/KimiBackend pattern (glm-backend.ts / kimi-backend.ts), NOT the
|
|
14
|
+
// Grok/Codex Responses-API adapter (grok-backend.ts's GrokDirectBackend),
|
|
15
|
+
// because Copilot is a real /chat/completions endpoint, not /responses. The
|
|
16
|
+
// inherited chatStream/readOpenAiSse/run/runTurn/dispatch/buildModelTools all
|
|
17
|
+
// apply unchanged. The ONLY Copilot-specific parts, all isolated to this file:
|
|
18
|
+
// 1. the ghu_ → short-lived Copilot bearer exchange
|
|
19
|
+
// (GET https://api.github.com/copilot_internal/v2/token)
|
|
20
|
+
// 2. the "editor identity" headers GitHub requires on BOTH the exchange and
|
|
21
|
+
// every chat/completions call (Editor-Version / Editor-Plugin-Version /
|
|
22
|
+
// User-Agent / Copilot-Integration-Id) — GitHub 403s the exchange
|
|
23
|
+
// WITHOUT them even on a fully licensed Copilot account (this is the
|
|
24
|
+
// documented `github-copilot-token-exchange-needs-editor-headers` gotcha)
|
|
25
|
+
// 3. the token source: ~/.comfyui-mcp/copilot-auth.json via
|
|
26
|
+
// `resolveCopilotOAuth` (code-provider-auth.ts), mirroring
|
|
27
|
+
// `resolveGrokOAuth` but WITHOUT refresh — ghu_ has no refresh_token; a
|
|
28
|
+
// dead/revoked one can only be fixed by re-running Copilot sign-in.
|
|
29
|
+
//
|
|
30
|
+
// UNVERIFIED AGAINST THE LIVE api.githubcopilot.com CONTRACT (flagged per the
|
|
31
|
+
// task brief — Task 8 validates live with a real, licensed account):
|
|
32
|
+
// - the exact exchange response shape ({token, expires_at, endpoints:{api}})
|
|
33
|
+
// - the chat/completions and /models paths and their exact request/response
|
|
34
|
+
// shapes
|
|
35
|
+
// - whether the signed-in account is Copilot-licensed at all (a 403 from the
|
|
36
|
+
// exchange is ambiguous between "no license" and "bad/stale editor
|
|
37
|
+
// headers" — see the skill note above)
|
|
38
|
+
// - the default model slug (Copilot's catalog changes over time; utility
|
|
39
|
+
// models share a rate-limit bucket per the `copilot-utility-models-
|
|
40
|
+
// shared-rate-limit` gotcha, so a busy account may 429 even with a
|
|
41
|
+
// correct slug — this backend does not special-case that; it surfaces the
|
|
42
|
+
// 429 like any other HTTP error)
|
|
43
|
+
// Both base URLs AND the default model are overridable via env so a live
|
|
44
|
+
// mismatch is a config flip, not a code change.
|
|
45
|
+
import { ValidationError } from "../utils/errors.js";
|
|
46
|
+
import { logger } from "../utils/logger.js";
|
|
47
|
+
import { COPILOT_CAPABILITIES } from "./agent-backend.js";
|
|
48
|
+
import { OllamaBackend } from "./ollama-backend.js";
|
|
49
|
+
import { resolveCopilotOAuth, } from "../services/code-provider-auth.js";
|
|
50
|
+
import { assertAllowedTokenHost, OAUTH_PROVIDERS, redactTokens } from "../services/oauth-flow.js";
|
|
51
|
+
function msgOf(err) {
|
|
52
|
+
return err instanceof Error ? err.message : String(err);
|
|
53
|
+
}
|
|
54
|
+
/** GET endpoint that exchanges the long-lived `ghu_` token for a short-lived
|
|
55
|
+
* Copilot API bearer. Overridable — the exact host/path is UNVERIFIED
|
|
56
|
+
* offline (see the module doc above). */
|
|
57
|
+
export const COPILOT_TOKEN_EXCHANGE_URL = process.env.COMFYUI_MCP_COPILOT_TOKEN_URL?.trim() ||
|
|
58
|
+
"https://api.github.com/copilot_internal/v2/token";
|
|
59
|
+
/** Base URL for Copilot's OpenAI-compatible chat/completions + /models.
|
|
60
|
+
* Overridable — a live exchange response's `endpoints.api` (when present)
|
|
61
|
+
* wins over this default for the REST of that token's lifetime (individual
|
|
62
|
+
* vs. business accounts may route to different hosts per the exchange
|
|
63
|
+
* response, per research). */
|
|
64
|
+
export const COPILOT_API_BASE = process.env.COMFYUI_MCP_COPILOT_API_BASE?.trim().replace(/\/+$/, "") ||
|
|
65
|
+
"https://api.githubcopilot.com";
|
|
66
|
+
/** UNVERIFIED against the live Copilot model catalog (slugs change — see the
|
|
67
|
+
* module doc). Override with COMFYUI_MCP_COPILOT_MODEL, or rely on the
|
|
68
|
+
* inherited listModels() (a live GET /models probe) to surface the account's
|
|
69
|
+
* real, currently-provisioned slugs. */
|
|
70
|
+
export const COPILOT_DEFAULT_MODEL = process.env.COMFYUI_MCP_COPILOT_MODEL?.trim() || "gpt-4.1";
|
|
71
|
+
/**
|
|
72
|
+
* GitHub's VS Code Copilot Chat "editor identity" — REQUIRED on both the
|
|
73
|
+
* token exchange and every chat/completions call, or GitHub 403s even a fully
|
|
74
|
+
* licensed account (see the `github-copilot-token-exchange-needs-editor-
|
|
75
|
+
* headers` gotcha). Exact version numbers are not strictly validated by
|
|
76
|
+
* GitHub — kept as a plausible, recognizable VS Code Copilot Chat identity
|
|
77
|
+
* rather than an app-branded User-Agent (which IS rejected).
|
|
78
|
+
*/
|
|
79
|
+
const EDITOR_IDENTITY_HEADERS = {
|
|
80
|
+
"Editor-Version": "vscode/1.95.0",
|
|
81
|
+
"Editor-Plugin-Version": "copilot-chat/0.22.0",
|
|
82
|
+
"User-Agent": "GitHubCopilotChat/0.22.0",
|
|
83
|
+
"Copilot-Integration-Id": "vscode-chat",
|
|
84
|
+
};
|
|
85
|
+
// Uses the shared `redactTokens` from oauth-flow.ts (single source of truth —
|
|
86
|
+
// this file used to carry a local `redactCopilotTokens` copy; its extra
|
|
87
|
+
// ghp_/`token\s+` rules were folded into the exported superset, no coverage
|
|
88
|
+
// lost) to strip token-shaped material from provider error text before it
|
|
89
|
+
// can reach a thrown message or a log line. Never logs/throws the raw ghu_ or
|
|
90
|
+
// the exchanged short-lived bearer.
|
|
91
|
+
/** `github.com` / `githubcopilot.com` — the same allowlist the OAuth engine
|
|
92
|
+
* already enforces for Copilot's device-code flow (oauth-flow.ts), reused
|
|
93
|
+
* here for the token-exchange + chat/completions DATA calls. */
|
|
94
|
+
function copilotApiHostAllowlist() {
|
|
95
|
+
return OAUTH_PROVIDERS.copilot?.apiHostAllowlist ?? ["github.com", "githubcopilot.com"];
|
|
96
|
+
}
|
|
97
|
+
/** Append a "re-run Copilot sign-in" hint to a 401/403 error message exactly
|
|
98
|
+
* once (idempotent — never double-appends if the message already carries a
|
|
99
|
+
* hint, e.g. from `exchangeCopilotToken` below). */
|
|
100
|
+
function withCopilotAuthHint(err) {
|
|
101
|
+
const message = msgOf(err);
|
|
102
|
+
if (/\b(401|403)\b/.test(message) && !/re-run copilot sign-in/i.test(message)) {
|
|
103
|
+
return new Error(`${message} Re-run Copilot sign-in from the panel.`);
|
|
104
|
+
}
|
|
105
|
+
return err instanceof Error ? err : new Error(message);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Step 1 of the two-step Copilot contract: exchange the long-lived `ghu_`
|
|
109
|
+
* token for a short-lived Copilot API bearer. Host-allowlisted before any
|
|
110
|
+
* network call; any error body is redacted before it can reach a thrown
|
|
111
|
+
* message. A 401/403 here is the PRIMARY "you're not signed in / not
|
|
112
|
+
* licensed" failure mode, so it gets the explicit re-sign-in hint.
|
|
113
|
+
*/
|
|
114
|
+
async function exchangeCopilotToken(ghuToken, fetchFn) {
|
|
115
|
+
assertAllowedTokenHost(COPILOT_TOKEN_EXCHANGE_URL, copilotApiHostAllowlist());
|
|
116
|
+
const res = await fetchFn(COPILOT_TOKEN_EXCHANGE_URL, {
|
|
117
|
+
method: "GET",
|
|
118
|
+
headers: {
|
|
119
|
+
Authorization: `token ${ghuToken}`,
|
|
120
|
+
Accept: "application/json",
|
|
121
|
+
...EDITOR_IDENTITY_HEADERS,
|
|
122
|
+
},
|
|
123
|
+
signal: AbortSignal.timeout(15_000),
|
|
124
|
+
});
|
|
125
|
+
const text = await res.text();
|
|
126
|
+
if (!res.ok) {
|
|
127
|
+
const hint = res.status === 401 || res.status === 403
|
|
128
|
+
? " Re-run Copilot sign-in from the panel (this also happens if the signed-in account has no active Copilot subscription)."
|
|
129
|
+
: "";
|
|
130
|
+
throw new ValidationError(`GitHub Copilot token exchange failed (${res.status}): ${redactTokens(text).slice(0, 300)}.${hint}`);
|
|
131
|
+
}
|
|
132
|
+
let payload;
|
|
133
|
+
try {
|
|
134
|
+
payload = JSON.parse(text);
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
throw new ValidationError("GitHub Copilot token exchange returned an unparseable response.");
|
|
138
|
+
}
|
|
139
|
+
const token = payload.token?.trim();
|
|
140
|
+
if (!token) {
|
|
141
|
+
throw new ValidationError("GitHub Copilot token exchange response is missing 'token'.");
|
|
142
|
+
}
|
|
143
|
+
const expiresAtMs = typeof payload.expires_at === "number" && Number.isFinite(payload.expires_at)
|
|
144
|
+
? payload.expires_at * 1000
|
|
145
|
+
: Date.now() + 20 * 60_000; // conservative fallback if the field is absent/renamed
|
|
146
|
+
// The exchange response's endpoints.api can route to a per-account host, but a
|
|
147
|
+
// server-supplied host is UNTRUSTED — if it isn't allowlisted, DROP it and
|
|
148
|
+
// fall back to the default base rather than dialing an off-allowlist host with
|
|
149
|
+
// the live bearer. (The default base itself is re-checked in
|
|
150
|
+
// ensureFreshCopilotToken before setOpenAiAuth, so a bad env override there is
|
|
151
|
+
// rejected outright — see below.)
|
|
152
|
+
const advertised = payload.endpoints?.api?.trim().replace(/\/+$/, "");
|
|
153
|
+
let apiBase = COPILOT_API_BASE;
|
|
154
|
+
if (advertised) {
|
|
155
|
+
try {
|
|
156
|
+
assertAllowedTokenHost(advertised, copilotApiHostAllowlist());
|
|
157
|
+
apiBase = advertised;
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
logger.warn(`[copilot-backend] token exchange advertised a non-allowlisted api host — ignoring it and using the default base.`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return { token, expiresAtMs, apiBase };
|
|
164
|
+
}
|
|
165
|
+
/** Refresh 60s before the bearer's reported expiry — matches the skew used
|
|
166
|
+
* elsewhere in code-provider-auth.ts (TOKEN_REFRESH_SKEW_MS-style guard). */
|
|
167
|
+
const COPILOT_TOKEN_REFRESH_SKEW_MS = 60_000;
|
|
168
|
+
/**
|
|
169
|
+
* GitHub Copilot chat — OpenAI-compatible chat/completions + the same 6-tool
|
|
170
|
+
* router as Ollama/GLM/Kimi. See the module doc above for the full contract,
|
|
171
|
+
* the reuse rationale, and the unverified-offline items.
|
|
172
|
+
*/
|
|
173
|
+
export class CopilotBackend extends OllamaBackend {
|
|
174
|
+
capabilities = COPILOT_CAPABILITIES;
|
|
175
|
+
ghuToken = null;
|
|
176
|
+
copilotBearer = null;
|
|
177
|
+
copilotBearerExpiresAtMs = 0;
|
|
178
|
+
resolveOAuth;
|
|
179
|
+
fetchFn;
|
|
180
|
+
constructor(deps = {}) {
|
|
181
|
+
super({
|
|
182
|
+
...deps,
|
|
183
|
+
backendId: "copilot",
|
|
184
|
+
api: "openai",
|
|
185
|
+
host: COPILOT_API_BASE, // placeholder until the first exchange resolves endpoints.api
|
|
186
|
+
apiKey: "pending-oauth", // never dialed with this value — ensureFreshCopilotToken() runs first
|
|
187
|
+
model: deps.model ?? COPILOT_DEFAULT_MODEL,
|
|
188
|
+
});
|
|
189
|
+
this.resolveOAuth = deps.resolveCopilotOAuth ?? resolveCopilotOAuth;
|
|
190
|
+
this.fetchFn = deps.fetch ?? fetch;
|
|
191
|
+
}
|
|
192
|
+
/** Adds GitHub's required editor-identity headers on top of the inherited
|
|
193
|
+
* Bearer-token header — applies to every chat/completions and /models call
|
|
194
|
+
* (OllamaBackend's "openai" dialect reads authHeaders() for both). */
|
|
195
|
+
authHeaders() {
|
|
196
|
+
const base = super.authHeaders();
|
|
197
|
+
if (!base.authorization)
|
|
198
|
+
return base;
|
|
199
|
+
return { ...base, ...EDITOR_IDENTITY_HEADERS };
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Exchange (or reuse a cached, still-fresh) short-lived Copilot bearer.
|
|
203
|
+
* Called from prepare() (session start) AND before EVERY turn (see run()
|
|
204
|
+
* below) so a long-lived panel session survives the token's short,
|
|
205
|
+
* GitHub-controlled lifetime. The short-lived bearer is held ONLY in this
|
|
206
|
+
* instance's memory — never written to disk (only the ghu_ persists, in
|
|
207
|
+
* copilot-auth.json, and this function never rewrites that file).
|
|
208
|
+
*/
|
|
209
|
+
async ensureFreshCopilotToken() {
|
|
210
|
+
const nowMs = Date.now();
|
|
211
|
+
if (this.copilotBearer && nowMs < this.copilotBearerExpiresAtMs - COPILOT_TOKEN_REFRESH_SKEW_MS) {
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
if (!this.ghuToken) {
|
|
215
|
+
const creds = await this.resolveOAuth();
|
|
216
|
+
this.ghuToken = creds.ghuToken;
|
|
217
|
+
}
|
|
218
|
+
const { token, expiresAtMs, apiBase } = await exchangeCopilotToken(this.ghuToken, this.fetchFn);
|
|
219
|
+
// FINAL GATE before the live bearer is ever attached to a host: apiBase is
|
|
220
|
+
// either the allowlist-checked exchange endpoint or COPILOT_API_BASE (which
|
|
221
|
+
// may be a COMFYUI_MCP_COPILOT_API_BASE env override). An off-allowlist
|
|
222
|
+
// override must be REJECTED here — never silently dialed — so the inherited
|
|
223
|
+
// ollama-backend prepare()/chatStream()/listModels() (which attach the
|
|
224
|
+
// bearer to this.host) can only ever hit an allowlisted host.
|
|
225
|
+
assertAllowedTokenHost(apiBase, copilotApiHostAllowlist());
|
|
226
|
+
this.copilotBearer = token;
|
|
227
|
+
this.copilotBearerExpiresAtMs = expiresAtMs;
|
|
228
|
+
this.setOpenAiAuth(apiBase, token);
|
|
229
|
+
}
|
|
230
|
+
async prepare() {
|
|
231
|
+
await this.ensureFreshCopilotToken();
|
|
232
|
+
try {
|
|
233
|
+
await super.prepare(); // GET {apiBase}/models reachability check + connectTools()
|
|
234
|
+
}
|
|
235
|
+
catch (err) {
|
|
236
|
+
throw withCopilotAuthHint(err);
|
|
237
|
+
}
|
|
238
|
+
logger.info(`[copilot-backend] ready (experimental — see task-5b report for the unverified contract items)`);
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Wrap the incoming turn channel so the Copilot bearer is refreshed BEFORE
|
|
242
|
+
* every turn, not just once at session start — a panel session can easily
|
|
243
|
+
* outlive the short-lived exchange token. Best-effort: a refresh failure
|
|
244
|
+
* mid-session is logged and the turn proceeds with whatever token is
|
|
245
|
+
* cached; if that token is actually stale the ensuing chat/completions call
|
|
246
|
+
* 401s and is surfaced through OllamaBackend's own turn-error path (a
|
|
247
|
+
* normal `result:false` + assistant error — never an unhandled rejection
|
|
248
|
+
* that could park the panel's turn-gate).
|
|
249
|
+
*/
|
|
250
|
+
async *wrapChannel(channel) {
|
|
251
|
+
for await (const turn of channel) {
|
|
252
|
+
try {
|
|
253
|
+
await this.ensureFreshCopilotToken();
|
|
254
|
+
}
|
|
255
|
+
catch (err) {
|
|
256
|
+
logger.warn(`[copilot-backend] token refresh before turn failed (${msgOf(err)}) — attempting the turn with the existing token.`);
|
|
257
|
+
}
|
|
258
|
+
yield turn;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
async *run(opts) {
|
|
262
|
+
yield* super.run({ ...opts, channel: this.wrapChannel(opts.channel) });
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
//# sourceMappingURL=copilot-backend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot-backend.js","sourceRoot":"","sources":["../../src/orchestrator/copilot-backend.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,2EAA2E;AAC3E,2EAA2E;AAC3E,kEAAkE;AAClE,gEAAgE;AAChE,+DAA+D;AAC/D,0EAA0E;AAC1E,kDAAkD;AAClD,EAAE;AACF,6BAA6B;AAC7B,yEAAyE;AACzE,+EAA+E;AAC/E,6EAA6E;AAC7E,0EAA0E;AAC1E,4EAA4E;AAC5E,8EAA8E;AAC9E,+EAA+E;AAC/E,sDAAsD;AACtD,8DAA8D;AAC9D,8EAA8E;AAC9E,6EAA6E;AAC7E,uEAAuE;AACvE,0EAA0E;AAC1E,+EAA+E;AAC/E,8DAA8D;AAC9D,gEAAgE;AAChE,6EAA6E;AAC7E,yEAAyE;AACzE,EAAE;AACF,8EAA8E;AAC9E,qEAAqE;AACrE,+EAA+E;AAC/E,8EAA8E;AAC9E,aAAa;AACb,+EAA+E;AAC/E,uEAAuE;AACvE,2CAA2C;AAC3C,2EAA2E;AAC3E,wEAAwE;AACxE,uEAAuE;AACvE,8EAA8E;AAC9E,qCAAqC;AACrC,yEAAyE;AACzE,gDAAgD;AAEhD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAA0B,MAAM,qBAAqB,CAAC;AAC5E,OAAO,EACL,mBAAmB,GAGpB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,sBAAsB,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAElG,SAAS,KAAK,CAAC,GAAY;IACzB,OAAO,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAC1D,CAAC;AAED;;0CAE0C;AAC1C,MAAM,CAAC,MAAM,0BAA0B,GACrC,OAAO,CAAC,GAAG,CAAC,6BAA6B,EAAE,IAAI,EAAE;IACjD,kDAAkD,CAAC;AAErD;;;;+BAI+B;AAC/B,MAAM,CAAC,MAAM,gBAAgB,GAC3B,OAAO,CAAC,GAAG,CAAC,4BAA4B,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;IACpE,+BAA+B,CAAC;AAElC;;;yCAGyC;AACzC,MAAM,CAAC,MAAM,qBAAqB,GAAG,OAAO,CAAC,GAAG,CAAC,yBAAyB,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;AAEhG;;;;;;;GAOG;AACH,MAAM,uBAAuB,GAA2B;IACtD,gBAAgB,EAAE,eAAe;IACjC,uBAAuB,EAAE,qBAAqB;IAC9C,YAAY,EAAE,0BAA0B;IACxC,wBAAwB,EAAE,aAAa;CACxC,CAAC;AAEF,8EAA8E;AAC9E,wEAAwE;AACxE,4EAA4E;AAC5E,0EAA0E;AAC1E,8EAA8E;AAC9E,oCAAoC;AAEpC;;iEAEiE;AACjE,SAAS,uBAAuB;IAC9B,OAAO,eAAe,CAAC,OAAO,EAAE,gBAAgB,IAAI,CAAC,YAAY,EAAE,mBAAmB,CAAC,CAAC;AAC1F,CAAC;AAED;;qDAEqD;AACrD,SAAS,mBAAmB,CAAC,GAAY;IACvC,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,IAAI,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9E,OAAO,IAAI,KAAK,CAAC,GAAG,OAAO,yCAAyC,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;AACzD,CAAC;AAQD;;;;;;GAMG;AACH,KAAK,UAAU,oBAAoB,CACjC,QAAgB,EAChB,OAAqB;IAErB,sBAAsB,CAAC,0BAA0B,EAAE,uBAAuB,EAAE,CAAC,CAAC;IAC9E,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,0BAA0B,EAAE;QACpD,MAAM,EAAE,KAAK;QACb,OAAO,EAAE;YACP,aAAa,EAAE,SAAS,QAAQ,EAAE;YAClC,MAAM,EAAE,kBAAkB;YAC1B,GAAG,uBAAuB;SAC3B;QACD,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;KACpC,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAC9B,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,GACR,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;YACtC,CAAC,CAAC,yHAAyH;YAC3H,CAAC,CAAC,EAAE,CAAC;QACT,MAAM,IAAI,eAAe,CACvB,yCAAyC,GAAG,CAAC,MAAM,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,IAAI,EAAE,CACpG,CAAC;IACJ,CAAC;IACD,IAAI,OAA8E,CAAC;IACnF,IAAI,CAAC;QACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAmB,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,eAAe,CAAC,iEAAiE,CAAC,CAAC;IAC/F,CAAC;IACD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC;IACpC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,eAAe,CAAC,4DAA4D,CAAC,CAAC;IAC1F,CAAC;IACD,MAAM,WAAW,GACf,OAAO,OAAO,CAAC,UAAU,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC;QAC3E,CAAC,CAAC,OAAO,CAAC,UAAU,GAAG,IAAI;QAC3B,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC,CAAC,uDAAuD;IACvF,+EAA+E;IAC/E,2EAA2E;IAC3E,+EAA+E;IAC/E,6DAA6D;IAC7D,+EAA+E;IAC/E,kCAAkC;IAClC,MAAM,UAAU,GAAG,OAAO,CAAC,SAAS,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACtE,IAAI,OAAO,GAAG,gBAAgB,CAAC;IAC/B,IAAI,UAAU,EAAE,CAAC;QACf,IAAI,CAAC;YACH,sBAAsB,CAAC,UAAU,EAAE,uBAAuB,EAAE,CAAC,CAAC;YAC9D,OAAO,GAAG,UAAU,CAAC;QACvB,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,CAAC,IAAI,CACT,kHAAkH,CACnH,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;AACzC,CAAC;AAED;8EAC8E;AAC9E,MAAM,6BAA6B,GAAG,MAAM,CAAC;AAE7C;;;;GAIG;AACH,MAAM,OAAO,cAAe,SAAQ,aAAa;IACtC,YAAY,GAAG,oBAAoB,CAAC;IAErC,QAAQ,GAAkB,IAAI,CAAC;IAC/B,aAAa,GAAkB,IAAI,CAAC;IACpC,wBAAwB,GAAG,CAAC,CAAC;IAC7B,YAAY,CAAoE;IAChF,OAAO,CAAe;IAE9B,YACE,OAQI,EAAE;QAEN,KAAK,CAAC;YACJ,GAAG,IAAI;YACP,SAAS,EAAE,SAAS;YACpB,GAAG,EAAE,QAAQ;YACb,IAAI,EAAE,gBAAgB,EAAE,8DAA8D;YACtF,MAAM,EAAE,eAAe,EAAE,sEAAsE;YAC/F,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,qBAAqB;SAC3C,CAAC,CAAC;QACH,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,mBAAmB,IAAI,mBAAmB,CAAC;QACpE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC;IACrC,CAAC;IAED;;2EAEuE;IACpD,WAAW;QAC5B,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;QACjC,IAAI,CAAC,IAAI,CAAC,aAAa;YAAE,OAAO,IAAI,CAAC;QACrC,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,uBAAuB,EAAE,CAAC;IACjD,CAAC;IAED;;;;;;;OAOG;IACK,KAAK,CAAC,uBAAuB;QACnC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,aAAa,IAAI,KAAK,GAAG,IAAI,CAAC,wBAAwB,GAAG,6BAA6B,EAAE,CAAC;YAChG,OAAO;QACT,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;YACxC,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;QACjC,CAAC;QACD,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,MAAM,oBAAoB,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAChG,2EAA2E;QAC3E,4EAA4E;QAC5E,wEAAwE;QACxE,4EAA4E;QAC5E,uEAAuE;QACvE,8DAA8D;QAC9D,sBAAsB,CAAC,OAAO,EAAE,uBAAuB,EAAE,CAAC,CAAC;QAC3D,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;QAC3B,IAAI,CAAC,wBAAwB,GAAG,WAAW,CAAC;QAC5C,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACrC,CAAC;IAEQ,KAAK,CAAC,OAAO;QACpB,MAAM,IAAI,CAAC,uBAAuB,EAAE,CAAC;QACrC,IAAI,CAAC;YACH,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,2DAA2D;QACpF,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,mBAAmB,CAAC,GAAG,CAAC,CAAC;QACjC,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,+FAA+F,CAAC,CAAC;IAC/G,CAAC;IAED;;;;;;;;;OASG;IACK,KAAK,CAAC,CAAC,WAAW,CAAC,OAAmC;QAC5D,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;YACjC,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,uBAAuB,EAAE,CAAC;YACvC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,CAAC,IAAI,CACT,uDAAuD,KAAK,CAAC,GAAG,CAAC,kDAAkD,CACpH,CAAC;YACJ,CAAC;YACD,MAAM,IAAI,CAAC;QACb,CAAC;IACH,CAAC;IAEQ,KAAK,CAAC,CAAC,GAAG,CAAC,IAAyB;QAC3C,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACzE,CAAC;CACF"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { GLM_CAPABILITIES } from "./agent-backend.js";
|
|
2
|
+
import { OllamaBackend } from "./ollama-backend.js";
|
|
3
|
+
import { resolveGlmCodeCredentials } from "../services/code-provider-auth.js";
|
|
4
|
+
export const GLM_DEFAULT_MODEL = process.env.COMFYUI_MCP_GLM_MODEL?.trim() || "glm-4.7";
|
|
5
|
+
/** Z.AI GLM Coding Plan — OpenAI-compatible chat/completions + 6-tool router. */
|
|
6
|
+
export class GlmBackend extends OllamaBackend {
|
|
7
|
+
capabilities = GLM_CAPABILITIES;
|
|
8
|
+
constructor(deps = {}) {
|
|
9
|
+
const creds = resolveGlmCodeCredentials();
|
|
10
|
+
super({
|
|
11
|
+
...deps,
|
|
12
|
+
backendId: "glm",
|
|
13
|
+
api: "openai",
|
|
14
|
+
host: creds.baseUrl,
|
|
15
|
+
apiKey: creds.apiKey,
|
|
16
|
+
model: deps.model ?? GLM_DEFAULT_MODEL,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=glm-backend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glm-backend.js","sourceRoot":"","sources":["../../src/orchestrator/glm-backend.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,aAAa,EAA0B,MAAM,qBAAqB,CAAC;AAC5E,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAE9E,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;AAExF,iFAAiF;AACjF,MAAM,OAAO,UAAW,SAAQ,aAAa;IAClC,YAAY,GAAG,gBAAgB,CAAC;IAEzC,YAAY,OAAyE,EAAE;QACrF,MAAM,KAAK,GAAG,yBAAyB,EAAE,CAAC;QAC1C,KAAK,CAAC;YACJ,GAAG,IAAI;YACP,SAAS,EAAE,KAAK;YAChB,GAAG,EAAE,QAAQ;YACb,IAAI,EAAE,KAAK,CAAC,OAAO;YACnB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,iBAAiB;SACvC,CAAC,CAAC;IACL,CAAC;CACF"}
|