@nyte-ai/plugin 0.0.23 → 0.0.24

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 (79) hide show
  1. package/THIRD-PARTY-NOTICES.md +2 -38
  2. package/dist/chunks/{billing-2v3g7rd9.js → bash-description-2v3g7rd9.js} +1 -1
  3. package/dist/chunks/{billing-3j77ss7y.js → bash-description-3j77ss7y.js} +1 -1
  4. package/dist/chunks/{billing-bv5zr32b.js → bash-description-dnvgk30y.js} +2 -2
  5. package/dist/chunks/{billing-hg64tqf1.js → bash-description-hg64tqf1.js} +1 -1
  6. package/dist/chunks/{billing-r2ftaajy.js → bash-description-necnb2k7.js} +2 -7
  7. package/dist/chunks/{billing-mvc33pv6.js → bash-description-qnwggxq3.js} +1 -1
  8. package/dist/chunks/{billing-svrhh5a5.js → bash-description-svrhh5a5.js} +1 -1
  9. package/dist/chunks/{billing-wbe8w0te.js → bash-description-wbe8w0te.js} +1 -1
  10. package/dist/chunks/{billing-wmcbg6fw.js → bash-description-wmcbg6fw.js} +1 -1
  11. package/dist/chunks/{billing-sxc70w72.js → bash-description-yyd9jznf.js} +1 -1
  12. package/dist/chunks/{billing-gs2h17jb.js → bash-description-zz15raxk.js} +1 -1
  13. package/dist/src/acp/connection.js +3 -3
  14. package/dist/src/acp/index.js +6 -6
  15. package/dist/src/acp/registry.js +2 -2
  16. package/dist/src/acp/thread.js +2 -2
  17. package/dist/src/acp/transcript.js +2 -2
  18. package/dist/src/acp/translate.js +1 -1
  19. package/dist/src/approvals/approvals.js +1 -1
  20. package/dist/src/approvals/schema.js +1 -1
  21. package/dist/src/canvas/canvas-compile.js +3 -3
  22. package/dist/src/canvas/canvas-libraries.js +1 -1
  23. package/dist/src/canvas/canvas-preview.js +3 -3
  24. package/dist/src/canvas/canvas-protocol.d.ts +1 -1
  25. package/dist/src/canvas/canvas-protocol.js +2 -2
  26. package/dist/src/canvas/canvas.js +5 -5
  27. package/dist/src/canvas/schema.js +3 -3
  28. package/dist/src/claude-code-sdk/index.js +6 -6
  29. package/dist/src/claude-code-sdk/session.js +2 -2
  30. package/dist/src/claude-code-sdk/transcript.js +2 -2
  31. package/dist/src/claude-code-sdk/translate.js +1 -1
  32. package/dist/src/find-on-path.js +1 -1
  33. package/dist/src/question/client/questions-tui.js +1 -1
  34. package/dist/src/question/client/questions.js +1 -1
  35. package/dist/src/question/question.js +2 -2
  36. package/dist/src/question/schema.js +1 -1
  37. package/package.json +4 -8
  38. package/dist/chunks/billing-0y7dfkp2.js +0 -146
  39. package/dist/chunks/billing-3scqmkzb.js +0 -559
  40. package/dist/chunks/billing-8rjk35gr.js +0 -444
  41. package/dist/chunks/billing-9qc0eqh4.js +0 -174
  42. package/dist/chunks/billing-a9vqn66p.js +0 -351
  43. package/dist/chunks/billing-cy1rg619.js +0 -302
  44. package/dist/chunks/billing-ejx2hv52.js +0 -323
  45. package/dist/chunks/billing-j643d12p.js +0 -197
  46. package/dist/chunks/billing-s4rrspsk.js +0 -7
  47. package/dist/chunks/billing-t1qrxe16.js +0 -41
  48. package/dist/chunks/billing-tzr3cebf.js +0 -20
  49. package/dist/examples/claude-code/LICENSE +0 -21
  50. package/dist/examples/claude-code/billing.d.ts +0 -7
  51. package/dist/examples/claude-code/billing.js +0 -11
  52. package/dist/examples/claude-code/claude-cli.d.ts +0 -35
  53. package/dist/examples/claude-code/claude-cli.js +0 -15
  54. package/dist/examples/claude-code/env.d.ts +0 -1
  55. package/dist/examples/claude-code/env.js +0 -6
  56. package/dist/examples/claude-code/index.d.ts +0 -24
  57. package/dist/examples/claude-code/index.js +0 -149
  58. package/dist/examples/claude-code/inert-mcp.d.ts +0 -1
  59. package/dist/examples/claude-code/inert-mcp.js +0 -6
  60. package/dist/examples/claude-code/model-catalog.d.ts +0 -27
  61. package/dist/examples/claude-code/model-catalog.js +0 -12
  62. package/dist/examples/claude-code/process.d.ts +0 -22
  63. package/dist/examples/claude-code/process.js +0 -25
  64. package/dist/examples/claude-code/replay.d.ts +0 -4
  65. package/dist/examples/claude-code/replay.js +0 -11
  66. package/dist/examples/claude-code/stream.d.ts +0 -3
  67. package/dist/examples/claude-code/stream.js +0 -16
  68. package/dist/examples/claude-code/transcript.d.ts +0 -83
  69. package/dist/examples/claude-code/transcript.js +0 -23
  70. package/dist/examples/claude-code/turn-relay.d.ts +0 -48
  71. package/dist/examples/claude-code/turn-relay.js +0 -9
  72. package/dist/examples/claude-code/wire.d.ts +0 -372
  73. package/dist/examples/claude-code/wire.js +0 -18
  74. /package/dist/chunks/{billing-4vz9pxyx.js → bash-description-4vz9pxyx.js} +0 -0
  75. /package/dist/chunks/{billing-6z2kgtyt.js → bash-description-6z2kgtyt.js} +0 -0
  76. /package/dist/chunks/{billing-9nn3yp18.js → bash-description-9nn3yp18.js} +0 -0
  77. /package/dist/chunks/{billing-h13r0byk.js → bash-description-h13r0byk.js} +0 -0
  78. /package/dist/chunks/{billing-ye3wk5r3.js → bash-description-ye3wk5r3.js} +0 -0
  79. /package/dist/chunks/{billing-zfpm2rt0.js → bash-description-zfpm2rt0.js} +0 -0
@@ -1,146 +0,0 @@
1
- // examples/claude-code/wire.ts
2
- import { Type } from "typebox";
3
- import { Value } from "typebox/value";
4
- var recordSchema = Type.Record(Type.String(), Type.Unknown());
5
- var usageSchema = Type.Object({
6
- input_tokens: Type.Number(),
7
- output_tokens: Type.Number(),
8
- cache_read_input_tokens: Type.Optional(Type.Number()),
9
- cache_creation_input_tokens: Type.Optional(Type.Number()),
10
- cache_creation: Type.Optional(Type.Object({ ephemeral_1h_input_tokens: Type.Optional(Type.Number()) })),
11
- output_tokens_details: Type.Optional(Type.Object({ thinking_tokens: Type.Optional(Type.Number()) }))
12
- });
13
- var contentSchema = Type.Union([
14
- Type.Object({ type: Type.Literal("text"), text: Type.String() }),
15
- Type.Object({
16
- type: Type.Literal("thinking"),
17
- thinking: Type.String(),
18
- signature: Type.Optional(Type.String())
19
- }),
20
- Type.Object({ type: Type.Literal("redacted_thinking"), data: Type.String() }),
21
- Type.Object({
22
- type: Type.Literal("tool_use"),
23
- id: Type.String(),
24
- name: Type.String(),
25
- input: recordSchema
26
- })
27
- ]);
28
- var messageSchema2 = Type.Intersect([
29
- recordSchema,
30
- Type.Object({
31
- id: Type.Optional(Type.String()),
32
- role: Type.Literal("assistant"),
33
- content: Type.Array(contentSchema),
34
- usage: Type.Optional(usageSchema),
35
- stop_reason: Type.Optional(Type.Union([Type.String(), Type.Null()])),
36
- stop_sequence: Type.Optional(Type.Union([Type.String(), Type.Null()]))
37
- })
38
- ]);
39
- var streamEventSchema = Type.Union([
40
- Type.Object({ type: Type.Literal("message_start"), message: messageSchema2 }),
41
- Type.Object({
42
- type: Type.Literal("content_block_start"),
43
- index: Type.Integer({ minimum: 0 }),
44
- content_block: contentSchema
45
- }),
46
- Type.Object({
47
- type: Type.Literal("content_block_delta"),
48
- index: Type.Integer({ minimum: 0 }),
49
- delta: Type.Union([
50
- Type.Object({ type: Type.Literal("text_delta"), text: Type.String() }),
51
- Type.Object({ type: Type.Literal("thinking_delta"), thinking: Type.String() }),
52
- Type.Object({ type: Type.Literal("signature_delta"), signature: Type.String() }),
53
- Type.Object({ type: Type.Literal("input_json_delta"), partial_json: Type.String() })
54
- ])
55
- }),
56
- Type.Object({ type: Type.Literal("content_block_stop"), index: Type.Integer({ minimum: 0 }) }),
57
- Type.Object({
58
- type: Type.Literal("message_delta"),
59
- delta: Type.Object({
60
- stop_reason: Type.Optional(Type.Union([Type.String(), Type.Null()])),
61
- stop_sequence: Type.Optional(Type.Union([Type.String(), Type.Null()]))
62
- }),
63
- usage: Type.Optional(Type.Partial(usageSchema))
64
- }),
65
- Type.Object({ type: Type.Literal("message_stop") }),
66
- Type.Object({
67
- type: Type.Literal("error"),
68
- error: Type.Optional(Type.Object({ type: Type.Optional(Type.String()), message: Type.Optional(Type.String()) }))
69
- })
70
- ]);
71
- var outputEventSchema = Type.Union([
72
- Type.Object({
73
- type: Type.Literal("assistant"),
74
- message: messageSchema2,
75
- error: Type.Optional(Type.Unknown())
76
- }),
77
- Type.Object({
78
- type: Type.Literal("result"),
79
- subtype: Type.Optional(Type.String()),
80
- is_error: Type.Optional(Type.Boolean()),
81
- num_turns: Type.Optional(Type.Number()),
82
- usage: Type.Optional(usageSchema),
83
- total_cost_usd: Type.Optional(Type.Number()),
84
- modelUsage: Type.Optional(recordSchema)
85
- }),
86
- Type.Object({ type: Type.Literal("stream_event"), event: streamEventSchema }),
87
- Type.Object({
88
- type: Type.Literal("rate_limit_event"),
89
- rate_limit_info: Type.Optional(Type.Object({
90
- status: Type.Optional(Type.String()),
91
- rateLimitType: Type.Optional(Type.String()),
92
- resetsAt: Type.Optional(Type.Number()),
93
- isUsingOverage: Type.Optional(Type.Boolean()),
94
- overageStatus: Type.Optional(Type.String()),
95
- overageDisabledReason: Type.Optional(Type.String())
96
- }))
97
- }),
98
- Type.Object({ type: Type.Literal("control_response"), response: recordSchema })
99
- ]);
100
- var requestMessageSchema = Type.Object({
101
- role: Type.Optional(Type.String()),
102
- content: Type.Optional(Type.Unknown())
103
- });
104
- var requestMessagesSchema = Type.Array(requestMessageSchema);
105
- var requestSchema = Type.Intersect([
106
- recordSchema,
107
- Type.Object({ messages: requestMessagesSchema, system: Type.Optional(Type.Unknown()) })
108
- ]);
109
- function matchesRecord2(value) {
110
- return Value.Check(recordSchema, value);
111
- }
112
- function parseRecord2(text) {
113
- const value = JSON.parse(text);
114
- if (!matchesRecord2(value))
115
- throw new Error("Expected a JSON object");
116
- return value;
117
- }
118
- function parseStreamEvent2(text) {
119
- const value = JSON.parse(text);
120
- if (matchesRecord2(value) && value.type === "ping")
121
- return;
122
- if (!Value.Check(streamEventSchema, value))
123
- throw new Error("Invalid Anthropic stream event");
124
- return value;
125
- }
126
- function parseOutputEvent2(text) {
127
- const value = parseRecord2(text);
128
- if (!["assistant", "result", "stream_event", "rate_limit_event", "control_response"].includes(String(value.type)))
129
- return;
130
- if (!Value.Check(outputEventSchema, value))
131
- throw new Error("Invalid Claude Code output event");
132
- return value;
133
- }
134
- function parseRequest2(body) {
135
- const value = JSON.parse(body.toString("utf8"));
136
- if (!Value.Check(requestSchema, value))
137
- throw new Error("Invalid Claude Code request");
138
- return value;
139
- }
140
- function parseRequestMessages2(value) {
141
- if (!Value.Check(requestMessagesSchema, value))
142
- throw new Error("Invalid Claude Code replay messages");
143
- return value;
144
- }
145
-
146
- export { messageSchema2, matchesRecord2, parseRecord2, parseStreamEvent2, parseOutputEvent2, parseRequest2, parseRequestMessages2 };
@@ -1,559 +0,0 @@
1
- import {
2
- usageCreditsAllowed2,
3
- usageCreditsChargeError2
4
- } from "./billing-tzr3cebf.js";
5
- import {
6
- INERT_MCP_SOURCE2
7
- } from "./billing-t1qrxe16.js";
8
- import {
9
- matchesRecord2,
10
- parseOutputEvent2
11
- } from "./billing-0y7dfkp2.js";
12
- import {
13
- configuredCommand2,
14
- readyClaudeCommand2,
15
- spawnCommand2,
16
- childExit2,
17
- killProcessTree2,
18
- processEnvironment2
19
- } from "./billing-cy1rg619.js";
20
- import {
21
- deriveInitialUserPrefix2,
22
- deriveInitialSystemMessages2,
23
- rewriteInitialRequest2
24
- } from "./billing-j643d12p.js";
25
- import {
26
- TurnRelay2
27
- } from "./billing-a9vqn66p.js";
28
- import {
29
- TOOL_PREFIX2
30
- } from "./billing-ejx2hv52.js";
31
-
32
- // examples/claude-code/claude-cli.ts
33
- import { createHash } from "node:crypto";
34
- import { mkdtemp, rm, writeFile } from "node:fs/promises";
35
- import { tmpdir } from "node:os";
36
- import { join, resolve as resolvePath } from "node:path";
37
- import { createInterface } from "node:readline";
38
- import { registerSessionResourceCleanup } from "@nyte-ai/ai";
39
- class AsyncQueue {
40
- values = [];
41
- waiters = [];
42
- ended = false;
43
- failure;
44
- push(value) {
45
- const waiter = this.waiters.shift();
46
- if (waiter)
47
- waiter({ value, done: false });
48
- else
49
- this.values.push(value);
50
- }
51
- end(error) {
52
- this.ended = true;
53
- this.failure = error;
54
- for (const waiter of this.waiters.splice(0))
55
- waiter({ value: undefined, done: true });
56
- }
57
- async next(signal, timeoutMs) {
58
- if (this.values.length)
59
- return this.values.shift();
60
- if (this.ended) {
61
- if (this.failure)
62
- throw this.failure;
63
- return;
64
- }
65
- signal?.throwIfAborted();
66
- return new Promise((resolve, reject) => {
67
- let settled = false;
68
- const finish = (fn) => {
69
- if (settled)
70
- return;
71
- settled = true;
72
- clearTimeout(timer);
73
- signal?.removeEventListener("abort", onAbort);
74
- const index = this.waiters.findIndex((pending) => pending === waiter);
75
- if (index >= 0)
76
- this.waiters.splice(index, 1);
77
- fn();
78
- };
79
- const waiter = (item) => finish(() => {
80
- if (item.done && this.failure)
81
- reject(this.failure);
82
- else
83
- resolve(item.done ? undefined : item.value);
84
- });
85
- const onAbort = () => finish(() => reject(signal?.reason ?? new Error("Claude Code request aborted")));
86
- const timer = setTimeout(() => finish(() => reject(new Error("Claude Code stream timed out"))), timeoutMs);
87
- this.waiters.push(waiter);
88
- signal?.addEventListener("abort", onAbort, { once: true });
89
- });
90
- }
91
- }
92
- async function writeFrame(child, frame) {
93
- const input = child.stdin;
94
- if (!input?.writable)
95
- throw new Error("Claude Code stdin closed during history replay");
96
- if (!input.write(`${JSON.stringify(frame)}
97
- `)) {
98
- await new Promise((resolve, reject) => {
99
- input.once("drain", resolve);
100
- input.once("error", reject);
101
- });
102
- }
103
- }
104
- function nativeErrorText(event) {
105
- const messageError = event.message.error;
106
- if (!event.error && !messageError)
107
- return;
108
- return event.message.content.filter((block) => block.type === "text").map((block) => block.text).join(`
109
- `);
110
- }
111
- var CLAUDE_PROCESS_MAX_AGE_MS = 5 * 60 * 1000;
112
- var MAX_CACHED_CLAUDE_PROCESSES = 2;
113
- function canonicalJson(value) {
114
- if (value === undefined)
115
- return "null";
116
- if (value === null || typeof value !== "object")
117
- return JSON.stringify(value);
118
- if (Array.isArray(value))
119
- return `[${value.map(canonicalJson).join(",")}]`;
120
- if (!matchesRecord2(value))
121
- throw new Error("Expected a JSON value");
122
- return `{${Object.entries(value).filter(([, child]) => child !== undefined).toSorted(([left], [right]) => left.localeCompare(right)).map(([key, child]) => `${JSON.stringify(key)}:${canonicalJson(child)}`).join(",")}}`;
123
- }
124
- function digest(value) {
125
- return createHash("sha256").update(canonicalJson(value)).digest("hex");
126
- }
127
- function frameHistoryHash(frames) {
128
- return digest(frames.map((frame) => ({
129
- type: frame.type,
130
- message: frame.message
131
- })));
132
- }
133
- function launchPlan(input) {
134
- const timeoutMs = input.timeoutMs ?? 180000;
135
- const env = processEnvironment2(input.env, input.extraBody);
136
- return {
137
- env,
138
- timeoutMs,
139
- fingerprint: digest({
140
- command: configuredCommand2(env),
141
- cwd: resolvePath(input.cwd ?? process.cwd()),
142
- env,
143
- extraBody: input.extraBody,
144
- manifest: input.manifest,
145
- model: input.model,
146
- systemPrompt: input.systemPrompt,
147
- timeoutMs,
148
- upstreamUrl: input.upstreamUrl ?? "https://api.anthropic.com"
149
- })
150
- };
151
- }
152
-
153
- class ClaudeProcess {
154
- busy = false;
155
- createdAt = Date.now();
156
- lastUsed = this.createdAt;
157
- tipHash;
158
- expiryTimer;
159
- closed = false;
160
- stderr = "";
161
- fingerprint;
162
- root;
163
- child;
164
- relay;
165
- queue;
166
- readTask;
167
- exitOutcome;
168
- timeoutMs;
169
- constructor(fingerprint, root, child, relay, queue, readTask, exitOutcome, timeoutMs) {
170
- this.fingerprint = fingerprint;
171
- this.root = root;
172
- this.child = child;
173
- this.relay = relay;
174
- this.queue = queue;
175
- this.readTask = readTask;
176
- this.exitOutcome = exitOutcome;
177
- this.timeoutMs = timeoutMs;
178
- child.stderr?.setEncoding("utf8");
179
- child.stderr?.on("data", (chunk) => this.stderr = (this.stderr + chunk).slice(-65536));
180
- }
181
- static async create(input, plan) {
182
- input.signal?.throwIfAborted();
183
- const command = await readyClaudeCommand2({ ...process.env, ...input.env }, input.signal);
184
- const root = await mkdtemp(join(tmpdir(), "nyte-claude-code-"));
185
- const toolsPath = join(root, "tools.json");
186
- const settingsPath = join(root, "settings.json");
187
- const systemPath = join(root, "system.md");
188
- const inertMcpPath = join(root, "inert-mcp.mjs");
189
- let child;
190
- let relay;
191
- try {
192
- await Promise.all([
193
- writeFile(inertMcpPath, INERT_MCP_SOURCE2, "utf8"),
194
- writeFile(toolsPath, JSON.stringify(input.manifest), "utf8"),
195
- writeFile(settingsPath, JSON.stringify({ env: { CLAUDE_CODE_EXTRA_BODY: JSON.stringify(input.extraBody) } }), "utf8"),
196
- writeFile(systemPath, input.systemPrompt, "utf8")
197
- ]);
198
- relay = new TurnRelay2(input.upstreamUrl ?? "https://api.anthropic.com", plan.timeoutMs);
199
- const env = { ...plan.env, ANTHROPIC_BASE_URL: await relay.start() };
200
- const mcp = {
201
- mcpServers: {
202
- nyte: {
203
- command: process.versions.bun === undefined ? process.execPath : "node",
204
- args: [inertMcpPath, toolsPath],
205
- env: { ELECTRON_RUN_AS_NODE: "1" }
206
- }
207
- }
208
- };
209
- const args = [
210
- "-p",
211
- "--model",
212
- input.model,
213
- "--input-format",
214
- "stream-json",
215
- "--output-format",
216
- "stream-json",
217
- "--verbose",
218
- "--include-partial-messages",
219
- "--tools",
220
- "",
221
- "--system-prompt-file",
222
- systemPath,
223
- "--settings",
224
- settingsPath,
225
- "--setting-sources",
226
- "",
227
- "--strict-mcp-config",
228
- "--disable-slash-commands",
229
- "--max-turns",
230
- "1",
231
- "--permission-mode",
232
- "dontAsk",
233
- "--no-session-persistence",
234
- "--mcp-config",
235
- JSON.stringify(mcp)
236
- ];
237
- child = spawnCommand2(command, args, {
238
- cwd: input.cwd ?? process.cwd(),
239
- env,
240
- detached: process.platform !== "win32",
241
- windowsHide: true,
242
- stdio: ["pipe", "pipe", "pipe"]
243
- });
244
- const queue = new AsyncQueue;
245
- if (child.stdout === null)
246
- throw new Error("Claude Code stdout is unavailable");
247
- const reader = createInterface({ input: child.stdout, crlfDelay: Infinity });
248
- const readTask = (async () => {
249
- try {
250
- for await (const line of reader) {
251
- if (!line.trim())
252
- continue;
253
- try {
254
- const event = parseOutputEvent2(line);
255
- if (event !== undefined)
256
- queue.push(event);
257
- } catch (error) {
258
- throw new Error(`Invalid Claude Code stream-json output: ${line.slice(0, 300)}`, {
259
- cause: error
260
- });
261
- }
262
- }
263
- queue.end();
264
- } catch (error) {
265
- queue.end(error instanceof Error ? error : new Error(String(error)));
266
- }
267
- })();
268
- const exitOutcome = childExit2(child).then((code) => ({ code }), (error) => ({ error: error instanceof Error ? error : new Error(String(error)) }));
269
- return new ClaudeProcess(plan.fingerprint, root, child, relay, queue, readTask, exitOutcome, plan.timeoutMs);
270
- } catch (error) {
271
- relay?.abort();
272
- if (child && child.exitCode === null)
273
- killProcessTree2(child);
274
- await relay?.close();
275
- await rm(root, { recursive: true, force: true });
276
- throw error;
277
- }
278
- }
279
- isAlive() {
280
- return !this.closed && this.child.exitCode === null && !!this.child.stdin?.writable;
281
- }
282
- isExpired(now = Date.now()) {
283
- return now - this.createdAt >= CLAUDE_PROCESS_MAX_AGE_MS;
284
- }
285
- canContinue(input) {
286
- if (!this.tipHash || input.frames.length === 0)
287
- return false;
288
- return frameHistoryHash(input.frames.slice(0, -1)) === this.tipHash;
289
- }
290
- clearExpiryTimer() {
291
- if (this.expiryTimer)
292
- clearTimeout(this.expiryTimer);
293
- this.expiryTimer = undefined;
294
- }
295
- armExpiryTimer(expire) {
296
- this.clearExpiryTimer();
297
- this.lastUsed = Date.now();
298
- const remainingLifetime = CLAUDE_PROCESS_MAX_AGE_MS - (this.lastUsed - this.createdAt);
299
- this.expiryTimer = setTimeout(expire, Math.max(0, remainingLifetime));
300
- this.expiryTimer.unref?.();
301
- }
302
- commit(input, message) {
303
- if (message.content.some((block) => block.type === "tool_use")) {
304
- this.tipHash = undefined;
305
- return false;
306
- }
307
- this.tipHash = frameHistoryHash([
308
- ...input.frames,
309
- { type: "assistant", message: { role: "assistant", content: message.content } }
310
- ]);
311
- return true;
312
- }
313
- async run(input, continuation) {
314
- if (!this.isAlive())
315
- throw new Error("Claude Code process is no longer available");
316
- input.signal?.throwIfAborted();
317
- let sawMessageStop = false;
318
- const deliver = (event) => {
319
- if (event.type === "message_stop")
320
- sawMessageStop = true;
321
- input.onEvent?.(event);
322
- };
323
- const canonicalInitialUser = input.frames.find((frame) => frame.type === "user")?.message.content ?? [];
324
- this.relay.beginTurn(deliver, input.initialUserPrefix || input.initialSystemMessages || input.nativeSystemInjections ? (body) => rewriteInitialRequest2(body, input.initialUserPrefix, canonicalInitialUser, input.initialSystemMessages, input.nativeSystemInjections) : undefined, input.betas);
325
- const abort = () => {
326
- this.relay.abort();
327
- this.closeNow();
328
- };
329
- input.signal?.addEventListener("abort", abort, { once: true });
330
- const assistants = [];
331
- let result;
332
- let nativeError;
333
- let rateLimit;
334
- try {
335
- const frames = continuation ? input.frames.slice(-1) : input.frames;
336
- for (const frame of frames) {
337
- await writeFrame(this.child, frame);
338
- if (frame.shouldQuery === false) {
339
- for (;; ) {
340
- const event = await this.queue.next(input.signal, this.timeoutMs);
341
- if (!event)
342
- throw await this.exitError("Claude Code exited before acknowledging history replay");
343
- if (event.type === "result") {
344
- if (event.num_turns !== 0 || event.is_error) {
345
- throw new Error("Claude Code rejected zero-turn history replay");
346
- }
347
- break;
348
- }
349
- }
350
- }
351
- }
352
- for (;; ) {
353
- const event = await this.queue.next(input.signal, this.timeoutMs);
354
- if (!event)
355
- throw await this.exitError("Claude Code exited before completing its response");
356
- if (event.type === "assistant") {
357
- const error = nativeErrorText(event);
358
- if (error !== undefined)
359
- nativeError = error;
360
- else
361
- assistants.push(event.message);
362
- } else if (event.type === "result") {
363
- result = event;
364
- break;
365
- } else if (event.type === "rate_limit_event") {
366
- if (event.rate_limit_info && typeof event.rate_limit_info === "object")
367
- rateLimit = event.rate_limit_info;
368
- } else if (event.type === "stream_event" && !this.relay.used) {
369
- deliver(event.event);
370
- }
371
- }
372
- await this.relay.settled();
373
- input.signal?.throwIfAborted();
374
- let message;
375
- if (this.relay.used) {
376
- if (this.relay.status !== 200 || !this.relay.capture.complete || !this.relay.capture.message) {
377
- let detail = `status ${this.relay.status ?? "unknown"}, capture ${this.relay.capture.complete ? "complete" : "incomplete"}`;
378
- if (this.relay.failure)
379
- detail += `, relay failure ${this.relay.failure}`;
380
- if (this.relay.denied)
381
- detail += `, native retries denied ${this.relay.denied}`;
382
- const upstreamError = this.relay.errorText();
383
- if (upstreamError)
384
- detail += `, upstream said: ${upstreamError.slice(0, 500)}`;
385
- throw new Error(`Incomplete Claude Code upstream response (${detail})`);
386
- }
387
- message = this.relay.capture.message;
388
- sawMessageStop = true;
389
- } else {
390
- message = assistants.at(-1);
391
- }
392
- if (!message || !sawMessageStop || !result) {
393
- throw new Error(`Incomplete Claude Code response: assistant, message_stop and one result required${this.stderr ? ` (${this.stderr.trim().slice(-500)})` : ""}`);
394
- }
395
- const nativeFailureHandled = this.relay.denied > 0 || message.stop_reason === "refusal";
396
- if (nativeError && !nativeFailureHandled)
397
- throw new Error(`Claude Code API error: ${nativeError}`);
398
- const hasTools = message.content.some((block) => block.type === "tool_use");
399
- const maxTurnsBoundary = hasTools && result.subtype === "error_max_turns";
400
- if (!maxTurnsBoundary && !nativeFailureHandled && (result.is_error || result.subtype !== "success")) {
401
- throw new Error(`Claude Code request failed: ${result.subtype ?? "unknown result"}`);
402
- }
403
- for (const block of message.content) {
404
- if (block.type !== "tool_use")
405
- continue;
406
- if (!block.name.startsWith(TOOL_PREFIX2) || !input.toolNames.has(block.name.slice(TOOL_PREFIX2.length))) {
407
- throw new Error("Claude Code returned a tool outside Nyte's current tool inventory");
408
- }
409
- }
410
- const usage = message.usage ?? result.usage;
411
- if (!usage || typeof usage.input_tokens !== "number" || typeof usage.output_tokens !== "number") {
412
- throw new Error("Claude Code response did not include complete token usage");
413
- }
414
- if (rateLimit?.isUsingOverage === true && !usageCreditsAllowed2({ ...process.env, ...input.env })) {
415
- throw usageCreditsChargeError2(rateLimit);
416
- }
417
- return {
418
- message,
419
- usage,
420
- relay: {
421
- upstreamRequests: Number(this.relay.used),
422
- blockedRequests: this.relay.denied,
423
- requestId: this.relay.requestId
424
- },
425
- initialUserPrefix: input.initialUserPrefix ?? deriveInitialUserPrefix2(this.relay.originalRequestBody, canonicalInitialUser),
426
- initialSystemMessages: input.initialSystemMessages ?? deriveInitialSystemMessages2(this.relay.originalRequestBody),
427
- rateLimit
428
- };
429
- } finally {
430
- input.signal?.removeEventListener("abort", abort);
431
- this.relay.finishTurn();
432
- }
433
- }
434
- async close() {
435
- this.closeNow();
436
- await Promise.allSettled([this.readTask, this.exitOutcome, this.relay.close()]);
437
- await rm(this.root, { recursive: true, force: true });
438
- }
439
- closeNow() {
440
- if (this.closed)
441
- return;
442
- this.closed = true;
443
- this.clearExpiryTimer();
444
- this.relay.abort();
445
- if (this.child.exitCode === null)
446
- killProcessTree2(this.child);
447
- }
448
- async exitError(fallback) {
449
- const outcome = await this.exitOutcome;
450
- if (outcome.error)
451
- return outcome.error;
452
- const detail = this.stderr.trim().slice(-500);
453
- return new Error(`${fallback} (exit ${outcome.code ?? "unknown"}${detail ? `: ${detail}` : ""})`);
454
- }
455
- }
456
- var processCache = new Map;
457
- var managerTail = Promise.resolve();
458
- async function withManagerLock(operation) {
459
- const previous = managerTail;
460
- const pending = Promise.withResolvers();
461
- managerTail = pending.promise;
462
- await previous;
463
- try {
464
- return await operation();
465
- } finally {
466
- pending.resolve();
467
- }
468
- }
469
- async function expireProcess(sessionId, worker) {
470
- const expired = await withManagerLock(() => {
471
- if (processCache.get(sessionId) !== worker || worker.busy || !worker.isExpired())
472
- return false;
473
- processCache.delete(sessionId);
474
- return true;
475
- });
476
- if (expired)
477
- await worker.close();
478
- }
479
- async function discardProcess(acquired) {
480
- const { sessionId, worker } = acquired;
481
- if (sessionId && processCache.get(sessionId) === worker) {
482
- await withManagerLock(() => {
483
- if (processCache.get(sessionId) === worker)
484
- processCache.delete(sessionId);
485
- });
486
- }
487
- await worker.close();
488
- }
489
- async function acquireProcess(input, plan) {
490
- return withManagerLock(async () => {
491
- const sessionId = input.sessionId;
492
- const cached = sessionId ? processCache.get(sessionId) : undefined;
493
- if (sessionId && cached && !cached.busy) {
494
- cached.clearExpiryTimer();
495
- if (cached.isAlive() && !cached.isExpired() && cached.fingerprint === plan.fingerprint && cached.canContinue(input)) {
496
- cached.busy = true;
497
- return { worker: cached, retained: true, continuation: true, sessionId };
498
- }
499
- processCache.delete(sessionId);
500
- await cached.close();
501
- }
502
- const retain = !!sessionId && !cached?.busy;
503
- if (retain) {
504
- while (processCache.size >= MAX_CACHED_CLAUDE_PROCESSES) {
505
- const victim = [...processCache.entries()].filter(([, worker]) => !worker.busy).toSorted((left, right) => left[1].lastUsed - right[1].lastUsed)[0];
506
- if (!victim)
507
- break;
508
- processCache.delete(victim[0]);
509
- await victim[1].close();
510
- }
511
- }
512
- const worker = await ClaudeProcess.create(input, plan);
513
- worker.busy = true;
514
- const retained = retain && processCache.size < MAX_CACHED_CLAUDE_PROCESSES;
515
- if (retained && sessionId)
516
- processCache.set(sessionId, worker);
517
- return { worker, retained, continuation: false, sessionId };
518
- });
519
- }
520
- async function closeClaudeProcesses(sessionId) {
521
- const workers = await withManagerLock(() => {
522
- if (sessionId) {
523
- const worker = processCache.get(sessionId);
524
- processCache.delete(sessionId);
525
- return worker ? [worker] : [];
526
- }
527
- const all = [...processCache.values()];
528
- processCache.clear();
529
- return all;
530
- });
531
- await Promise.allSettled(workers.map((worker) => worker.close()));
532
- }
533
- registerSessionResourceCleanup((sessionId) => {
534
- closeClaudeProcesses(sessionId);
535
- });
536
- async function runClaudeRequest2(input) {
537
- input.signal?.throwIfAborted();
538
- const plan = launchPlan(input);
539
- const acquired = await acquireProcess(input, plan);
540
- try {
541
- const output = await acquired.worker.run(input, acquired.continuation);
542
- const stable = acquired.worker.commit(input, output.message);
543
- if (stable && acquired.retained && acquired.sessionId && processCache.get(acquired.sessionId) === acquired.worker) {
544
- acquired.worker.busy = false;
545
- const sessionId = acquired.sessionId;
546
- acquired.worker.armExpiryTimer(() => {
547
- expireProcess(sessionId, acquired.worker);
548
- });
549
- } else {
550
- await discardProcess(acquired);
551
- }
552
- return output;
553
- } catch (error) {
554
- await discardProcess(acquired);
555
- throw error;
556
- }
557
- }
558
-
559
- export { runClaudeRequest2 };