comfyui-mcp 0.18.0 → 0.19.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 +58 -2
- package/dist/config.js +57 -3
- package/dist/config.js.map +1 -1
- package/dist/orchestrator/agent-backend.js +33 -0
- package/dist/orchestrator/agent-backend.js.map +1 -0
- package/dist/orchestrator/claude-backend.js +475 -0
- package/dist/orchestrator/claude-backend.js.map +1 -0
- package/dist/orchestrator/codex-backend.js +1086 -0
- package/dist/orchestrator/codex-backend.js.map +1 -0
- package/dist/orchestrator/index.js +312 -16
- package/dist/orchestrator/index.js.map +1 -1
- package/dist/orchestrator/panel-agent.js +349 -346
- package/dist/orchestrator/panel-agent.js.map +1 -1
- package/dist/orchestrator/panel-mcp-http.js +190 -0
- package/dist/orchestrator/panel-mcp-http.js.map +1 -0
- package/dist/orchestrator/panel-tools.js +809 -359
- package/dist/orchestrator/panel-tools.js.map +1 -1
- package/dist/orchestrator/session-store.js +71 -0
- package/dist/orchestrator/session-store.js.map +1 -0
- package/dist/services/api-nodes.js +109 -0
- package/dist/services/api-nodes.js.map +1 -1
- package/dist/services/crash-log.js +222 -0
- package/dist/services/crash-log.js.map +1 -0
- package/dist/services/env-capabilities.js +404 -0
- package/dist/services/env-capabilities.js.map +1 -0
- package/dist/services/model-resolver.js +25 -3
- package/dist/services/model-resolver.js.map +1 -1
- package/dist/services/workflow-slicer.js +123 -0
- package/dist/services/workflow-slicer.js.map +1 -0
- package/dist/tools/index.js +2 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/model-extras.js +6 -2
- package/dist/tools/model-extras.js.map +1 -1
- package/dist/tools/model-management.js +12 -2
- package/dist/tools/model-management.js.map +1 -1
- package/dist/tools/skills-access.js +480 -0
- package/dist/tools/skills-access.js.map +1 -0
- package/dist/tools/workflow-library.js +140 -0
- package/dist/tools/workflow-library.js.map +1 -1
- package/package.json +14 -2
- package/packs/anima/workflow.json +27 -27
- package/packs/anima-img2img/workflow.json +12 -12
- package/packs/anima-inpaint/workflow.json +6 -6
- package/packs/anima-txt2img/workflow.json +12 -12
- package/packs/cozy-flow/workflow.json +1 -1
- package/packs/ideogram/workflow.json +16 -16
- package/packs/ideogram-img2img/workflow.json +9 -9
- package/packs/ideogram-txt2img/workflow.json +9 -9
- package/packs/krea2/workflow.json +4265 -0
- package/packs/krea2-txt2img/install-runpod.sh +40 -0
- package/packs/krea2-txt2img/install-windows.bat +45 -0
- package/packs/krea2-txt2img/manifest.yaml +29 -0
- package/packs/krea2-txt2img/pack.yaml +32 -0
- package/packs/krea2-txt2img/workflow.json +1871 -0
- package/packs/ltx-2.3-extender/workflow.json +9 -9
- package/packs/ltx-2.3-extender-no-audio/workflow.json +9 -9
- package/packs/ltx-2.3-flf/workflow.json +13 -13
- package/packs/ltx-2.3-xy-plot/workflow.json +27 -27
- package/packs/wan-pusa-extend/manifest.yaml +43 -0
- package/packs/wan-pusa-extend/pack.yaml +51 -0
- package/packs/wan-pusa-extend/workflow.json +1 -0
- package/plugin/skills/krea2-txt2img/SKILL.md +83 -0
- package/plugin/skills/triton-sageattention/SKILL.md +363 -0
- package/plugin/skills/video-extend/SKILL.md +505 -0
- package/plugin/skills/video-upscale/SKILL.md +329 -0
- package/plugin/skills/wan-flf-video/SKILL.md +26 -1
- package/plugin/skills/wan-t2v-video/SKILL.md +12 -0
- package/plugin/skills/workflow-layout/SKILL.md +14 -5
- package/scripts/codex-comfyui-mcp-check.mjs +53 -0
- package/scripts/codex-knowledge-parity-smoke.mjs +202 -0
- package/scripts/codex-parity-smoke.mjs +177 -0
- package/scripts/gen-tool-docs.ts +33 -2
- package/scripts/mock-panel.mjs +34 -3
- package/scripts/panel-load-workflow-smoke.mjs +210 -0
- package/scripts/slice-pipeline.mjs +15 -61
- package/scripts/test-agent.mjs +108 -13
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
// Claude Agent SDK backend — the provider-specific adapter behind the
|
|
2
|
+
// AgentBackend port. It owns everything that knows about
|
|
3
|
+
// `@anthropic-ai/claude-agent-sdk`: the lazy SDK import, the `query()` call,
|
|
4
|
+
// Claude `Options` building (including forkSession/resumeSessionAt/resume),
|
|
5
|
+
// model/command enumeration, the live model setter, interrupt, and the
|
|
6
|
+
// normalization of `SDKMessage` → canonical `AgentEvent`.
|
|
7
|
+
//
|
|
8
|
+
// PanelAgent keeps all provider-agnostic orchestration (queue, turn-gate, bridge
|
|
9
|
+
// push, rewind-anchor tracking, self-restart) and drives this backend via
|
|
10
|
+
// `for await (const ev of backend.run({...}))`. See
|
|
11
|
+
// docs/design/agent-backend-injection.md.
|
|
12
|
+
import { logger } from "../utils/logger.js";
|
|
13
|
+
import { CLAUDE_CAPABILITIES, } from "./agent-backend.js";
|
|
14
|
+
// ---- reasoning effort mapping ----
|
|
15
|
+
// Effort is now a provider-neutral union (it must survive a provider switch — see
|
|
16
|
+
// panel-agent.ts Effort). The Agent SDK only accepts the Claude scale
|
|
17
|
+
// (low|medium|high|xhigh|max), so map any off-scale neutral value (Codex's
|
|
18
|
+
// "none"/"minimal") to the nearest valid Claude level. Shared levels pass through.
|
|
19
|
+
const CLAUDE_EFFORTS = new Set(["low", "medium", "high", "xhigh", "max"]);
|
|
20
|
+
function toClaudeEffort(effort) {
|
|
21
|
+
if (!effort)
|
|
22
|
+
return undefined;
|
|
23
|
+
const e = effort.toLowerCase();
|
|
24
|
+
if (CLAUDE_EFFORTS.has(e))
|
|
25
|
+
return e;
|
|
26
|
+
if (e === "none" || e === "minimal")
|
|
27
|
+
return "low"; // Codex's sub-low → Claude's floor
|
|
28
|
+
return undefined; // unknown → SDK default
|
|
29
|
+
}
|
|
30
|
+
// The Agent SDK is an OPTIONAL dependency (it pulls in ~100 packages and is only
|
|
31
|
+
// needed for the panel orchestrator), so load it lazily and fail with a clear
|
|
32
|
+
// message rather than at import time for everyone.
|
|
33
|
+
let queryFn = null;
|
|
34
|
+
export async function loadQuery() {
|
|
35
|
+
if (queryFn)
|
|
36
|
+
return queryFn;
|
|
37
|
+
try {
|
|
38
|
+
const mod = await import("@anthropic-ai/claude-agent-sdk");
|
|
39
|
+
queryFn = mod.query;
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
throw new Error("The panel orchestrator requires the optional dependency @anthropic-ai/claude-agent-sdk. Install it with: npm i @anthropic-ai/claude-agent-sdk");
|
|
43
|
+
}
|
|
44
|
+
return queryFn;
|
|
45
|
+
}
|
|
46
|
+
function msgOf(err) {
|
|
47
|
+
return err instanceof Error ? err.message : String(err);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Ask the SDK which models the current account can actually use — so the panel's
|
|
51
|
+
* picker reflects the live subscription instead of a hardcoded list. This is the
|
|
52
|
+
* only model-enumeration path that works on the subscription/OAuth lane:
|
|
53
|
+
* `query.supportedModels()` (the public Models API and `claude` CLI both require
|
|
54
|
+
* an API key, which we deliberately don't have here).
|
|
55
|
+
*
|
|
56
|
+
* Runs a minimal throwaway session — no MCP servers, no plugins/skills — so it's
|
|
57
|
+
* cheap; the control request resolves right after init, then we tear it down.
|
|
58
|
+
* Returns [] on any failure so the panel can fall back gracefully.
|
|
59
|
+
*/
|
|
60
|
+
export async function fetchSupportedModels(model) {
|
|
61
|
+
const query = await loadQuery();
|
|
62
|
+
let stop = false;
|
|
63
|
+
let wake = null;
|
|
64
|
+
// An idle channel: keeps the control connection open without ever consuming a
|
|
65
|
+
// turn, until we tear it down.
|
|
66
|
+
async function* idle() {
|
|
67
|
+
while (!stop) {
|
|
68
|
+
await new Promise((resolve) => {
|
|
69
|
+
wake = resolve;
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const q = query({
|
|
74
|
+
prompt: idle(),
|
|
75
|
+
options: {
|
|
76
|
+
model,
|
|
77
|
+
permissionMode: "bypassPermissions",
|
|
78
|
+
allowDangerouslySkipPermissions: true,
|
|
79
|
+
strictMcpConfig: true,
|
|
80
|
+
mcpServers: {},
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
// The transport is pumped by iterating the query — do it in the background so
|
|
84
|
+
// the control request (supportedModels) gets its response.
|
|
85
|
+
const drain = (async () => {
|
|
86
|
+
try {
|
|
87
|
+
for await (const _ of q) {
|
|
88
|
+
void _;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
// torn down below
|
|
93
|
+
}
|
|
94
|
+
})();
|
|
95
|
+
let timer;
|
|
96
|
+
try {
|
|
97
|
+
// Never hang forever: a stuck probe would leave a permanently-pending
|
|
98
|
+
// cached promise and the panel would never get its model list.
|
|
99
|
+
const models = await Promise.race([
|
|
100
|
+
q.supportedModels(),
|
|
101
|
+
new Promise((_, reject) => {
|
|
102
|
+
timer = setTimeout(() => reject(new Error("supportedModels timed out")), 20000);
|
|
103
|
+
}),
|
|
104
|
+
]);
|
|
105
|
+
logger.info(`[panel-orchestrator] supportedModels: ${models.map((m) => m.value).join(", ") || "(none)"}`);
|
|
106
|
+
return models;
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
logger.warn(`[panel-orchestrator] supportedModels probe failed: ${msgOf(err)}`);
|
|
110
|
+
return [];
|
|
111
|
+
}
|
|
112
|
+
finally {
|
|
113
|
+
if (timer)
|
|
114
|
+
clearTimeout(timer);
|
|
115
|
+
stop = true;
|
|
116
|
+
// Cast re-widens: TS narrows the closure-mutated local back to its init value.
|
|
117
|
+
wake?.();
|
|
118
|
+
try {
|
|
119
|
+
await q.interrupt();
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
// already winding down
|
|
123
|
+
}
|
|
124
|
+
void drain;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Probe the SDK for the slash commands this account/session exposes (built-ins
|
|
129
|
+
* like /compact, plus any loaded skills) so the panel can surface them in the
|
|
130
|
+
* composer's completion menu. Same throwaway-session pattern as
|
|
131
|
+
* fetchSupportedModels; returns [] on any failure so the panel degrades cleanly.
|
|
132
|
+
*/
|
|
133
|
+
export async function fetchSupportedCommands(model) {
|
|
134
|
+
const query = await loadQuery();
|
|
135
|
+
let stop = false;
|
|
136
|
+
let wake = null;
|
|
137
|
+
async function* idle() {
|
|
138
|
+
while (!stop) {
|
|
139
|
+
await new Promise((resolve) => {
|
|
140
|
+
wake = resolve;
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
const q = query({
|
|
145
|
+
prompt: idle(),
|
|
146
|
+
options: {
|
|
147
|
+
model,
|
|
148
|
+
permissionMode: "bypassPermissions",
|
|
149
|
+
allowDangerouslySkipPermissions: true,
|
|
150
|
+
strictMcpConfig: true,
|
|
151
|
+
mcpServers: {},
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
const drain = (async () => {
|
|
155
|
+
try {
|
|
156
|
+
for await (const _ of q) {
|
|
157
|
+
void _;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
// torn down below
|
|
162
|
+
}
|
|
163
|
+
})();
|
|
164
|
+
let timer;
|
|
165
|
+
try {
|
|
166
|
+
const commands = await Promise.race([
|
|
167
|
+
q.supportedCommands(),
|
|
168
|
+
new Promise((_, reject) => {
|
|
169
|
+
timer = setTimeout(() => reject(new Error("supportedCommands timed out")), 20000);
|
|
170
|
+
}),
|
|
171
|
+
]);
|
|
172
|
+
logger.info(`[panel-orchestrator] supportedCommands: ${commands.map((c) => "/" + c.name).join(", ") || "(none)"}`);
|
|
173
|
+
return commands;
|
|
174
|
+
}
|
|
175
|
+
catch (err) {
|
|
176
|
+
logger.warn(`[panel-orchestrator] supportedCommands probe failed: ${msgOf(err)}`);
|
|
177
|
+
return [];
|
|
178
|
+
}
|
|
179
|
+
finally {
|
|
180
|
+
if (timer)
|
|
181
|
+
clearTimeout(timer);
|
|
182
|
+
stop = true;
|
|
183
|
+
wake?.();
|
|
184
|
+
try {
|
|
185
|
+
await q.interrupt();
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
// already winding down
|
|
189
|
+
}
|
|
190
|
+
void drain;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* The Claude Agent SDK adapter. One instance per PanelAgent; it holds the live
|
|
195
|
+
* `Query` for the current session and re-creates it on each `run()`.
|
|
196
|
+
*/
|
|
197
|
+
export class ClaudeBackend {
|
|
198
|
+
id = "claude";
|
|
199
|
+
capabilities = CLAUDE_CAPABILITIES;
|
|
200
|
+
deps;
|
|
201
|
+
q = null;
|
|
202
|
+
constructor(deps) {
|
|
203
|
+
this.deps = deps;
|
|
204
|
+
}
|
|
205
|
+
/** Preflight: lazy-load the Agent SDK once so a missing optional dependency
|
|
206
|
+
* fails fast (a clear "install @anthropic-ai/claude-agent-sdk" reject) rather
|
|
207
|
+
* than being retried as a dropped session inside the restart loop. Idempotent. */
|
|
208
|
+
async prepare() {
|
|
209
|
+
await loadQuery();
|
|
210
|
+
}
|
|
211
|
+
/** Fetch a ComfyUI image and wrap it as an Anthropic base64 image block, or
|
|
212
|
+
* null on any failure (the text reference still names it as a fallback). */
|
|
213
|
+
async fetchImageBlock(ref) {
|
|
214
|
+
if (!this.deps.comfyuiUrl || !ref?.filename)
|
|
215
|
+
return null;
|
|
216
|
+
try {
|
|
217
|
+
const u = new URL("/view", this.deps.comfyuiUrl);
|
|
218
|
+
u.searchParams.set("filename", ref.filename);
|
|
219
|
+
u.searchParams.set("type", ref.type || "input");
|
|
220
|
+
if (ref.subfolder)
|
|
221
|
+
u.searchParams.set("subfolder", ref.subfolder);
|
|
222
|
+
const res = await fetch(u, { signal: AbortSignal.timeout(15000) });
|
|
223
|
+
if (!res.ok)
|
|
224
|
+
return null;
|
|
225
|
+
let mt = (res.headers.get("content-type") || "").split(";")[0].trim().toLowerCase();
|
|
226
|
+
if (!["image/png", "image/jpeg", "image/gif", "image/webp"].includes(mt)) {
|
|
227
|
+
mt = "image/png"; // Anthropic-supported set; ComfyUI outputs are PNG by default
|
|
228
|
+
}
|
|
229
|
+
const buf = Buffer.from(await res.arrayBuffer());
|
|
230
|
+
if (buf.length > 12 * 1024 * 1024)
|
|
231
|
+
return null; // keep context sane
|
|
232
|
+
return { type: "image", source: { type: "base64", media_type: mt, data: buf.toString("base64") } };
|
|
233
|
+
}
|
|
234
|
+
catch {
|
|
235
|
+
return null;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
/** Shape one provider-neutral turn into a Claude `SDKUserMessage`, resolving
|
|
239
|
+
* image refs to inline base64 blocks so the agent SEES them in this turn (no
|
|
240
|
+
* view_image/get_image round-trip). */
|
|
241
|
+
async shapeTurn(turn) {
|
|
242
|
+
const text = turn.text;
|
|
243
|
+
const images = turn.images ?? [];
|
|
244
|
+
let content = text;
|
|
245
|
+
if (images.length) {
|
|
246
|
+
const blocks = [];
|
|
247
|
+
for (const ref of images) {
|
|
248
|
+
const b = await this.fetchImageBlock(ref);
|
|
249
|
+
if (b)
|
|
250
|
+
blocks.push(b);
|
|
251
|
+
}
|
|
252
|
+
if (blocks.length)
|
|
253
|
+
content = [{ type: "text", text }, ...blocks];
|
|
254
|
+
}
|
|
255
|
+
return {
|
|
256
|
+
type: "user",
|
|
257
|
+
message: { role: "user", content },
|
|
258
|
+
parent_tool_use_id: null,
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
buildOptions(opts) {
|
|
262
|
+
const model = opts.model;
|
|
263
|
+
const effort = toClaudeEffort(opts.effort);
|
|
264
|
+
const resume = opts.resume;
|
|
265
|
+
const rewindAnchor = opts.rewindAnchor;
|
|
266
|
+
// Rewind: fork the conversation at the anchor (resume up to that message, then
|
|
267
|
+
// branch into a new session id) so everything after it is dropped. A null
|
|
268
|
+
// anchor means "fresh session" (handled by clearing resume below).
|
|
269
|
+
const rewindOpts = rewindAnchor
|
|
270
|
+
? { resume: opts.sessionId ?? resume, resumeSessionAt: rewindAnchor, forkSession: true }
|
|
271
|
+
: null;
|
|
272
|
+
return {
|
|
273
|
+
model,
|
|
274
|
+
permissionMode: "bypassPermissions",
|
|
275
|
+
// Required alongside bypassPermissions (intentional, isolated background agent).
|
|
276
|
+
allowDangerouslySkipPermissions: true,
|
|
277
|
+
// Stream partial assistant messages so the panel can show thinking + reply
|
|
278
|
+
// text live (token-by-token) instead of only the final block. route() turns
|
|
279
|
+
// these into onStream deltas; the final assistant message still commits the
|
|
280
|
+
// authoritative text via onSay (reconciled by message id).
|
|
281
|
+
includePartialMessages: true,
|
|
282
|
+
mcpServers: {
|
|
283
|
+
...this.deps.mcpServers,
|
|
284
|
+
// Live-graph control of THIS tab's open workflow (in-process; talks to
|
|
285
|
+
// the bridge). Lets the agent build on what the user sees.
|
|
286
|
+
...(this.deps.panelServer ? { panel: this.deps.panelServer } : {}),
|
|
287
|
+
},
|
|
288
|
+
// Only our comfyui MCP — never inherit the user's project/user MCP config
|
|
289
|
+
// (which may run a second comfyui that grabs the bridge port).
|
|
290
|
+
strictMcpConfig: true,
|
|
291
|
+
systemPrompt: {
|
|
292
|
+
type: "preset",
|
|
293
|
+
preset: "claude_code",
|
|
294
|
+
append: this.deps.systemAppend,
|
|
295
|
+
},
|
|
296
|
+
// Reasoning effort, when the picker has set one.
|
|
297
|
+
...(effort ? { effort } : {}),
|
|
298
|
+
// Load the bundled comfyui-mcp plugin so the agent has model expertise
|
|
299
|
+
// (IDEOGRAM/WAN/LTX/Qwen/… skills) out of the box — "install the package
|
|
300
|
+
// = expert agent". Omitted if the plugin dir can't be found.
|
|
301
|
+
...(this.deps.pluginPath
|
|
302
|
+
? {
|
|
303
|
+
plugins: [{ type: "local", path: this.deps.pluginPath }],
|
|
304
|
+
skills: "all",
|
|
305
|
+
}
|
|
306
|
+
: {}),
|
|
307
|
+
...(rewindOpts ?? (resume ? { resume } : {})),
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Open the Claude session and yield canonical AgentEvents. The user channel
|
|
312
|
+
* (PanelAgent's gated queue) is shaped turn-by-turn into `SDKUserMessage`s by
|
|
313
|
+
* `shapeTurn`; the SDK's `SDKMessage`s are normalized into `AgentEvent`s.
|
|
314
|
+
*/
|
|
315
|
+
async *run(opts) {
|
|
316
|
+
const query = await loadQuery();
|
|
317
|
+
const self = this;
|
|
318
|
+
// Wrap the neutral channel: shape each turn into the SDK's native form right
|
|
319
|
+
// before it's read, so PanelAgent never deals in SDKUserMessage.
|
|
320
|
+
async function* prompt() {
|
|
321
|
+
for await (const turn of opts.channel) {
|
|
322
|
+
yield await self.shapeTurn(turn);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
const q = query({ prompt: prompt(), options: this.buildOptions(opts) });
|
|
326
|
+
this.q = q;
|
|
327
|
+
for await (const message of q) {
|
|
328
|
+
// LIVENESS: every SDKMessage — including the ones route() doesn't translate
|
|
329
|
+
// (tool-progress, rate-limit, etc.) — is a sign the session is alive, so
|
|
330
|
+
// re-arm PanelAgent's idle watchdog. Claude already streams continuously, so
|
|
331
|
+
// this is effectively a no-op for behavior here; it keeps the watchdog's
|
|
332
|
+
// re-arm source uniform across both backends via the port.
|
|
333
|
+
opts.onActivity?.();
|
|
334
|
+
yield* this.route(message);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
/** Switch the model live (the SDK applies it to the next turn). */
|
|
338
|
+
async setModel(model) {
|
|
339
|
+
try {
|
|
340
|
+
// setModel is live: no session restart, the next turn uses it.
|
|
341
|
+
await this.q?.setModel?.(model);
|
|
342
|
+
}
|
|
343
|
+
catch (err) {
|
|
344
|
+
logger.debug(`[claude-backend] setModel: ${msgOf(err)}`);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
async interrupt() {
|
|
348
|
+
await this.q?.interrupt();
|
|
349
|
+
}
|
|
350
|
+
/** Permanently dispose of the live SDK query. The Agent SDK has no explicit
|
|
351
|
+
* "dispose" beyond interrupt(), which both stops the in-flight turn and lets
|
|
352
|
+
* the underlying transport wind down once the prompt generator is no longer
|
|
353
|
+
* iterated (PanelAgent.stop() closes the channel before calling this). We then
|
|
354
|
+
* drop our reference so the query can be GC'd. Idempotent + safe when never
|
|
355
|
+
* started (q is null) — and a true no-op for Claude's behavior: stop() already
|
|
356
|
+
* called interrupt(), so this only releases the reference. */
|
|
357
|
+
async close() {
|
|
358
|
+
const q = this.q;
|
|
359
|
+
this.q = null;
|
|
360
|
+
if (!q)
|
|
361
|
+
return;
|
|
362
|
+
try {
|
|
363
|
+
await q.interrupt();
|
|
364
|
+
}
|
|
365
|
+
catch {
|
|
366
|
+
// already winding down / never fully started
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
async listModels() {
|
|
370
|
+
return [];
|
|
371
|
+
}
|
|
372
|
+
/** Normalize one SDK message into zero or more canonical AgentEvents. */
|
|
373
|
+
*route(message) {
|
|
374
|
+
switch (message.type) {
|
|
375
|
+
case "system":
|
|
376
|
+
if (message.subtype === "init") {
|
|
377
|
+
yield {
|
|
378
|
+
type: "session",
|
|
379
|
+
sessionId: message.session_id,
|
|
380
|
+
...(message.model ? { model: message.model } : {}),
|
|
381
|
+
};
|
|
382
|
+
logger.info(`[panel-agent] init model=${message.model} session=${message.session_id.slice(0, 8)} apiKeySource=${message.apiKeySource} skills=${message.skills?.length ?? 0}`);
|
|
383
|
+
}
|
|
384
|
+
else if (message.subtype === "thinking_tokens") {
|
|
385
|
+
// Live extended-thinking token count → drives a "thinking… (N)" meter
|
|
386
|
+
// so the user can see the agent reasoning (not stuck) before any text.
|
|
387
|
+
const t = message.estimated_tokens;
|
|
388
|
+
if (typeof t === "number") {
|
|
389
|
+
yield { type: "thinking", tokens: t };
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
break;
|
|
393
|
+
case "stream_event": {
|
|
394
|
+
// Live partial output (includePartialMessages). Turn the raw Anthropic
|
|
395
|
+
// stream events into thinking/reply deltas the panel renders token-by-
|
|
396
|
+
// token. The authoritative text still commits via the `assistant` case.
|
|
397
|
+
const ev = message.event;
|
|
398
|
+
if (!ev)
|
|
399
|
+
break;
|
|
400
|
+
const evType = ev.type;
|
|
401
|
+
if (evType === "message_start") {
|
|
402
|
+
const mid = ev.message?.id;
|
|
403
|
+
yield { type: "stream_start", id: typeof mid === "string" ? mid : null };
|
|
404
|
+
}
|
|
405
|
+
else if (evType === "content_block_delta") {
|
|
406
|
+
const d = ev.delta;
|
|
407
|
+
if (!d)
|
|
408
|
+
break;
|
|
409
|
+
if (d.type === "thinking_delta" && typeof d.thinking === "string" && d.thinking) {
|
|
410
|
+
yield { type: "assistant_delta", text: d.thinking, thinking: true };
|
|
411
|
+
}
|
|
412
|
+
else if (d.type === "text_delta" && typeof d.text === "string" && d.text) {
|
|
413
|
+
yield { type: "assistant_delta", text: d.text };
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
else if (evType === "message_stop") {
|
|
417
|
+
yield { type: "stream_end" };
|
|
418
|
+
}
|
|
419
|
+
break;
|
|
420
|
+
}
|
|
421
|
+
case "assistant": {
|
|
422
|
+
// Remember this message's UUID — it's the rewind anchor for the turn.
|
|
423
|
+
const auid = message.uuid;
|
|
424
|
+
// Each assistant API response carries the CURRENT context size — report
|
|
425
|
+
// it live so the meter updates throughout the turn, not just at the end.
|
|
426
|
+
const u = message.message?.usage;
|
|
427
|
+
// Commit the authoritative reply text as ONE message. With streaming on,
|
|
428
|
+
// the panel already showed a live preview (matched by this message id);
|
|
429
|
+
// the commit replaces it with the final text. Without streaming (or for
|
|
430
|
+
// injected events), it just renders a normal bubble.
|
|
431
|
+
const content = (message.message?.content ?? []);
|
|
432
|
+
const text = content
|
|
433
|
+
.filter((b) => b.type === "text" && typeof b.text === "string")
|
|
434
|
+
.map((b) => b.text)
|
|
435
|
+
.join("\n\n")
|
|
436
|
+
.trim();
|
|
437
|
+
const id = message.message?.id;
|
|
438
|
+
yield {
|
|
439
|
+
type: "assistant",
|
|
440
|
+
text,
|
|
441
|
+
...(typeof auid === "string" ? { uuid: auid } : {}),
|
|
442
|
+
...(id ? { id } : {}),
|
|
443
|
+
...(u ? { usage: u } : {}),
|
|
444
|
+
};
|
|
445
|
+
break;
|
|
446
|
+
}
|
|
447
|
+
case "result": {
|
|
448
|
+
// Cache the context window + cost from the result, then re-report using
|
|
449
|
+
// the last assistant usage (the true current context).
|
|
450
|
+
const m = message;
|
|
451
|
+
let contextWindow;
|
|
452
|
+
for (const mu of Object.values(m.modelUsage ?? {})) {
|
|
453
|
+
if (mu?.contextWindow && (contextWindow === undefined || mu.contextWindow > contextWindow)) {
|
|
454
|
+
contextWindow = mu.contextWindow;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
yield {
|
|
458
|
+
type: "result",
|
|
459
|
+
ok: message.subtype === "success",
|
|
460
|
+
subtype: message.subtype,
|
|
461
|
+
...(contextWindow !== undefined ? { contextWindow } : {}),
|
|
462
|
+
...(typeof m.total_cost_usd === "number" ? { costUsd: m.total_cost_usd } : {}),
|
|
463
|
+
};
|
|
464
|
+
break;
|
|
465
|
+
}
|
|
466
|
+
default:
|
|
467
|
+
// Parity with the original route(): other SDK message types (incl. SDK
|
|
468
|
+
// rate-limit and tool-progress events) are not surfaced — the panel never
|
|
469
|
+
// consumed them. The canonical AgentEvent union still declares `rate_limit`
|
|
470
|
+
// and `tool_call` for other backends / a future Claude enhancement to emit.
|
|
471
|
+
break;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
//# sourceMappingURL=claude-backend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-backend.js","sourceRoot":"","sources":["../../src/orchestrator/claude-backend.ts"],"names":[],"mappings":"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"}
|