@knightcodeai/cli 0.19.0 → 0.21.1
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/CHANGELOG.md +106 -0
- package/dist/bundle/chunks/anthropic-messages-EY2CGNFR.js +6 -0
- package/dist/bundle/chunks/azure-openai-responses-KGI5F27P.js +2 -0
- package/dist/bundle/chunks/bedrock-converse-stream.js +8 -5
- package/dist/bundle/chunks/chunk-424HQSAU.js +10 -0
- package/dist/bundle/chunks/{chunk-3QKQRXCZ.js → chunk-5O4LFJS7.js} +4 -4
- package/dist/bundle/chunks/chunk-5ZES34QN.js +2 -0
- package/dist/bundle/chunks/chunk-BLHRVYHG.js +9 -0
- package/dist/bundle/chunks/{chunk-RZDCZFG7.js → chunk-EJS73Z3L.js} +1 -1
- package/dist/bundle/chunks/chunk-F22TYE3W.js +7 -0
- package/dist/bundle/chunks/{chunk-C62RVFZT.js → chunk-FSAHEI7P.js} +6 -6
- package/dist/bundle/chunks/chunk-K6AEXKBA.js +30 -0
- package/dist/bundle/chunks/chunk-O2HKRIDR.js +16 -0
- package/dist/bundle/chunks/{chunk-KRDGPCZM.js → chunk-OLW2IS5G.js} +2 -2
- package/dist/bundle/chunks/chunk-QEVQ7EIS.js +2 -0
- package/dist/bundle/chunks/chunk-RRNUW65U.js +4 -0
- package/dist/bundle/chunks/{chunk-AA6MLWWY.js → chunk-TOEFTX4C.js} +1 -1
- package/dist/bundle/chunks/{chunk-IIS4JDFO.js → chunk-TOGJI36I.js} +147 -134
- package/dist/bundle/chunks/chunk-VLP4ZJF6.js +2 -0
- package/dist/bundle/chunks/{chunk-2QXPCKUQ.js → chunk-VQBEVSZH.js} +1 -1
- package/dist/bundle/chunks/chunk-XDEOVQPJ.js +108 -0
- package/dist/bundle/chunks/chunk-YDO6TXKD.js +2 -0
- package/dist/bundle/chunks/{cli-SIPOI5P3.js → cli-CIRIEG66.js} +1 -1
- package/dist/bundle/chunks/cloudflare-workers-ai-system-one-H3D4RYQQ.js +2 -0
- package/dist/bundle/chunks/{easter-egg-3d-BVWLABZN.js → easter-egg-3d-YLN6ACWS.js} +1 -1
- package/dist/bundle/chunks/{execute-6UIHV2DR.js → execute-P6HIB6ET.js} +1 -1
- package/dist/bundle/chunks/{google-generative-ai-RFCCCXK6.js → google-generative-ai-C3FLXY47.js} +1 -1
- package/dist/bundle/chunks/{google-vertex-WN3JAZCD.js → google-vertex-AXIPR47C.js} +1 -1
- package/dist/bundle/chunks/knightcode-messages-LTLKDRGW.js +8 -0
- package/dist/bundle/chunks/{llama-cpp-classify-FEWC5ZIH.js → llama-cpp-classify-J2EJVDIZ.js} +1 -1
- package/dist/bundle/chunks/mistral-conversations-N2UBIKKR.js +5 -0
- package/dist/bundle/chunks/{openai-codex-responses-3Y7R752C.js → openai-codex-responses-REOHLPAA.js} +1 -1
- package/dist/bundle/chunks/openai-completions-XONAGXPC.js +7 -0
- package/dist/bundle/chunks/{openai-decisions-MLI3SMFN.js → openai-decisions-ACB7F6SS.js} +1 -1
- package/dist/bundle/chunks/{openai-responses-BNRA5YTD.js → openai-responses-OHJS7C73.js} +1 -1
- package/dist/bundle/chunks/{openrouter-images-JWVDFQJ4.js → openrouter-images-SMNBEOPV.js} +1 -1
- package/dist/bundle/chunks/{runtime-AROIXIAV.js → runtime-WNZGA67H.js} +1 -1
- package/dist/bundle/chunks/typesafe-system-one-KB2F2YGV.js +2 -0
- package/dist/bundle/chunks/{virtual-modules-IYKQM2DL.js → virtual-modules-EU3BUTGN.js} +1 -1
- package/dist/bundle/cli-runtime.js +1 -1
- package/dist/core/export-html/template.css +9 -0
- package/dist/core/export-html/template.js +165 -45
- package/docs/app-server.md +168 -14
- package/docs/app-server.schema.json +7505 -1860
- package/docs/cli.md +3 -3
- package/docs/containerization.md +2 -2
- package/docs/custom-provider.md +2 -0
- package/docs/declarative-views.md +118 -0
- package/docs/desktop.md +109 -4
- package/docs/docs.json +4 -0
- package/docs/environment-variables.md +1 -0
- package/docs/extensions.md +7 -3
- package/docs/keybindings.md +1 -0
- package/docs/mcp.md +16 -2
- package/docs/message-types.md +1 -1
- package/docs/models-configuration.md +9 -0
- package/docs/models.md +8 -4
- package/docs/packages.md +2 -0
- package/docs/plan-mode.md +4 -0
- package/docs/settings.md +3 -3
- package/docs/slash-commands.md +2 -0
- package/docs/usage.md +23 -0
- package/examples/extensions/README.md +1 -0
- package/examples/extensions/custom-provider-anthropic/index.ts +27 -31
- package/examples/extensions/desktop-view.ts +72 -0
- package/examples/extensions/gondolin/index.ts +8 -10
- package/examples/extensions/gondolin/package-lock.json +20 -30
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/todo.ts +3 -0
- package/examples/mcp-app/server.mjs +177 -0
- package/package.json +1 -1
- package/dist/bundle/chunks/anthropic-messages-34POCEPV.js +0 -6
- package/dist/bundle/chunks/azure-openai-responses-ZZQJJY7B.js +0 -2
- package/dist/bundle/chunks/chunk-2QXUEOVY.js +0 -2
- package/dist/bundle/chunks/chunk-4CRI7BMY.js +0 -2
- package/dist/bundle/chunks/chunk-BTRAS32C.js +0 -7
- package/dist/bundle/chunks/chunk-FA32X2UJ.js +0 -7
- package/dist/bundle/chunks/chunk-GPHSXYPT.js +0 -2
- package/dist/bundle/chunks/chunk-JSLSFYBX.js +0 -108
- package/dist/bundle/chunks/chunk-OQHO44L6.js +0 -16
- package/dist/bundle/chunks/chunk-R7X2RAGR.js +0 -30
- package/dist/bundle/chunks/chunk-T47GKPON.js +0 -11
- package/dist/bundle/chunks/chunk-UU4A4NV5.js +0 -2
- package/dist/bundle/chunks/cloudflare-workers-ai-system-one-QHP5M5HC.js +0 -2
- package/dist/bundle/chunks/knightcode-messages-57CV36UV.js +0 -8
- package/dist/bundle/chunks/mistral-conversations-GIGX6BW6.js +0 -5
- package/dist/bundle/chunks/openai-completions-HBXENZUJ.js +0 -7
- package/dist/bundle/chunks/typesafe-system-one-5LELZY2F.js +0 -2
|
@@ -42,7 +42,7 @@ import {
|
|
|
42
42
|
type TextContent,
|
|
43
43
|
type ThinkingContent,
|
|
44
44
|
type Tool,
|
|
45
|
-
|
|
45
|
+
ToolCallArgumentsStream,
|
|
46
46
|
type ToolResultMessage,
|
|
47
47
|
type TranscriptContext,
|
|
48
48
|
} from "@knightcode/ai";
|
|
@@ -454,8 +454,9 @@ function streamCustomAnthropic(
|
|
|
454
454
|
const anthropicStream = client.messages.stream({ ...params }, { signal: options?.signal });
|
|
455
455
|
stream.push({ type: "start", partial: output });
|
|
456
456
|
|
|
457
|
-
|
|
458
|
-
|
|
457
|
+
// Stream state per Anthropic block index, kept off the content blocks so it never reaches partial messages.
|
|
458
|
+
// ToolCallArgumentsStream reads each argument delta once and shows the arguments parsed so far.
|
|
459
|
+
const openBlocks = new Map<number, { contentIndex: number; arguments?: ToolCallArgumentsStream }>();
|
|
459
460
|
|
|
460
461
|
for await (const event of anthropicStream) {
|
|
461
462
|
if (event.type === "message_start") {
|
|
@@ -468,15 +469,12 @@ function streamCustomAnthropic(
|
|
|
468
469
|
calculateCost(model, output.usage);
|
|
469
470
|
} else if (event.type === "content_block_start") {
|
|
470
471
|
if (event.content_block.type === "text") {
|
|
471
|
-
output.content.push({ type: "text", text: ""
|
|
472
|
+
output.content.push({ type: "text", text: "" });
|
|
473
|
+
openBlocks.set(event.index, { contentIndex: output.content.length - 1 });
|
|
472
474
|
stream.push({ type: "text_start", contentIndex: output.content.length - 1, partial: output });
|
|
473
475
|
} else if (event.content_block.type === "thinking") {
|
|
474
|
-
output.content.push({
|
|
475
|
-
|
|
476
|
-
thinking: "",
|
|
477
|
-
thinkingSignature: "",
|
|
478
|
-
index: event.index,
|
|
479
|
-
} as any);
|
|
476
|
+
output.content.push({ type: "thinking", thinking: "", thinkingSignature: "" });
|
|
477
|
+
openBlocks.set(event.index, { contentIndex: output.content.length - 1 });
|
|
480
478
|
stream.push({ type: "thinking_start", contentIndex: output.content.length - 1, partial: output });
|
|
481
479
|
} else if (event.content_block.type === "tool_use") {
|
|
482
480
|
output.content.push({
|
|
@@ -484,15 +482,18 @@ function streamCustomAnthropic(
|
|
|
484
482
|
id: event.content_block.id,
|
|
485
483
|
name: isOAuth ? fromClaudeCodeName(event.content_block.name, tools) : event.content_block.name,
|
|
486
484
|
arguments: {},
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
485
|
+
});
|
|
486
|
+
openBlocks.set(event.index, {
|
|
487
|
+
contentIndex: output.content.length - 1,
|
|
488
|
+
arguments: new ToolCallArgumentsStream(),
|
|
489
|
+
});
|
|
490
490
|
stream.push({ type: "toolcall_start", contentIndex: output.content.length - 1, partial: output });
|
|
491
491
|
}
|
|
492
492
|
} else if (event.type === "content_block_delta") {
|
|
493
|
-
const
|
|
494
|
-
|
|
495
|
-
|
|
493
|
+
const open = openBlocks.get(event.index);
|
|
494
|
+
if (!open) continue;
|
|
495
|
+
const index = open.contentIndex;
|
|
496
|
+
const block = output.content[index]!;
|
|
496
497
|
|
|
497
498
|
if (event.delta.type === "text_delta" && block.type === "text") {
|
|
498
499
|
block.text += event.delta.text;
|
|
@@ -505,11 +506,8 @@ function streamCustomAnthropic(
|
|
|
505
506
|
delta: event.delta.thinking,
|
|
506
507
|
partial: output,
|
|
507
508
|
});
|
|
508
|
-
} else if (event.delta.type === "input_json_delta" && block.type === "toolCall") {
|
|
509
|
-
|
|
510
|
-
try {
|
|
511
|
-
block.arguments = JSON.parse((block as any).partialJson);
|
|
512
|
-
} catch {}
|
|
509
|
+
} else if (event.delta.type === "input_json_delta" && block.type === "toolCall" && open.arguments) {
|
|
510
|
+
block.arguments = open.arguments.append(event.delta.partial_json);
|
|
513
511
|
stream.push({
|
|
514
512
|
type: "toolcall_delta",
|
|
515
513
|
contentIndex: index,
|
|
@@ -520,20 +518,19 @@ function streamCustomAnthropic(
|
|
|
520
518
|
block.thinkingSignature = (block.thinkingSignature || "") + (event.delta as any).signature;
|
|
521
519
|
}
|
|
522
520
|
} else if (event.type === "content_block_stop") {
|
|
523
|
-
const
|
|
524
|
-
|
|
525
|
-
|
|
521
|
+
const open = openBlocks.get(event.index);
|
|
522
|
+
if (!open) continue;
|
|
523
|
+
openBlocks.delete(event.index);
|
|
524
|
+
const index = open.contentIndex;
|
|
525
|
+
const block = output.content[index]!;
|
|
526
526
|
|
|
527
|
-
delete (block as any).index;
|
|
528
527
|
if (block.type === "text") {
|
|
529
528
|
stream.push({ type: "text_end", contentIndex: index, content: block.text, partial: output });
|
|
530
529
|
} else if (block.type === "thinking") {
|
|
531
530
|
stream.push({ type: "thinking_end", contentIndex: index, content: block.thinking, partial: output });
|
|
532
|
-
} else if (block.type === "toolCall") {
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
} catch {}
|
|
536
|
-
delete (block as any).partialJson;
|
|
531
|
+
} else if (block.type === "toolCall" && open.arguments) {
|
|
532
|
+
// One full parse of the complete text; malformed arguments are reported in `argumentsError`.
|
|
533
|
+
Object.assign(block, open.arguments.finish());
|
|
537
534
|
stream.push({ type: "toolcall_end", contentIndex: index, toolCall: block, partial: output });
|
|
538
535
|
}
|
|
539
536
|
} else if (event.type === "message_delta") {
|
|
@@ -563,7 +560,6 @@ function streamCustomAnthropic(
|
|
|
563
560
|
stream.push({ type: "done", reason: output.stopReason, message: output });
|
|
564
561
|
stream.end();
|
|
565
562
|
} catch (error) {
|
|
566
|
-
for (const block of output.content) delete (block as any).index;
|
|
567
563
|
output.stopReason = options?.signal?.aborted ? "aborted" : "error";
|
|
568
564
|
output.errorMessage = error instanceof Error ? error.message : JSON.stringify(error);
|
|
569
565
|
stream.push({ type: "error", reason: output.stopReason, error: output });
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Desktop View - declarative views in a widget, answering presses, and in a tool result
|
|
3
|
+
*
|
|
4
|
+
* Shows a widget with a toggle and a button, drawn by the terminal and by the desktop app from the same data
|
|
5
|
+
* (docs/declarative-views.md). In the desktop app the controls are live: a press reaches `ctx.ui.onViewEvent`, and
|
|
6
|
+
* the extension answers by setting the widget again. The `check_summary` tool returns a table view, which both
|
|
7
|
+
* clients draw in place of the tool's text output.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* knightcode --extension examples/extensions/desktop-view.ts
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { Type } from "@knightcode/ai";
|
|
14
|
+
import { defineTool, type ExtensionAPI, type ExtensionContext, type View } from "@knightcodeai/cli";
|
|
15
|
+
|
|
16
|
+
const WIDGET = "desktop-view:checks";
|
|
17
|
+
|
|
18
|
+
const checkSummary = defineTool({
|
|
19
|
+
name: "check_summary",
|
|
20
|
+
label: "Check summary",
|
|
21
|
+
description: "Summarize the project's checks as a table",
|
|
22
|
+
parameters: Type.Object({}),
|
|
23
|
+
async execute() {
|
|
24
|
+
const view: View = {
|
|
25
|
+
type: "table",
|
|
26
|
+
columns: ["check", "result"],
|
|
27
|
+
rows: [
|
|
28
|
+
["types", "passed"],
|
|
29
|
+
["tests", "2 failed"],
|
|
30
|
+
],
|
|
31
|
+
};
|
|
32
|
+
return { content: [{ type: "text", text: "types: passed\ntests: 2 failed" }], details: { view } };
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
export default function (knightcode: ExtensionAPI) {
|
|
37
|
+
// Per session: the factory runs again for every thread that loads the extension.
|
|
38
|
+
let verbose = false;
|
|
39
|
+
let resets = 0;
|
|
40
|
+
|
|
41
|
+
const show = (ctx: ExtensionContext) => {
|
|
42
|
+
const view: View = {
|
|
43
|
+
type: "stack",
|
|
44
|
+
children: [
|
|
45
|
+
{ type: "text", text: `Checks reset ${resets} time${resets === 1 ? "" : "s"}`, tone: "muted" },
|
|
46
|
+
{
|
|
47
|
+
type: "stack",
|
|
48
|
+
direction: "horizontal",
|
|
49
|
+
children: [
|
|
50
|
+
{ type: "field", id: "verbose", kind: "toggle", label: "Verbose", value: verbose },
|
|
51
|
+
{ type: "button", id: "reset", label: "Reset" },
|
|
52
|
+
],
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
};
|
|
56
|
+
ctx.ui.setWidget(WIDGET, view);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
knightcode.registerTool(checkSummary);
|
|
60
|
+
|
|
61
|
+
knightcode.on("session_start", (_event, ctx) => {
|
|
62
|
+
if (!ctx.hasUI) return;
|
|
63
|
+
show(ctx);
|
|
64
|
+
// Only where widgets are interactive (the desktop app); the terminal draws the controls as text.
|
|
65
|
+
ctx.ui.onViewEvent?.((event) => {
|
|
66
|
+
if (event.widgetKey !== WIDGET) return;
|
|
67
|
+
if (event.id === "verbose" && typeof event.value === "boolean") verbose = event.value;
|
|
68
|
+
if (event.id === "reset") resets++;
|
|
69
|
+
show(ctx);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
}
|
|
@@ -7,20 +7,20 @@
|
|
|
7
7
|
* isolated to the VM.
|
|
8
8
|
*
|
|
9
9
|
* Setup:
|
|
10
|
-
* cd packages/
|
|
10
|
+
* cd packages/cli/examples/extensions/gondolin
|
|
11
11
|
* npm install --ignore-scripts
|
|
12
12
|
*
|
|
13
13
|
* Usage:
|
|
14
14
|
* cd /path/to/project
|
|
15
|
-
* knightcode -e /path/to/knightcode/packages/
|
|
15
|
+
* knightcode -e /path/to/knightcode/packages/cli/examples/extensions/gondolin
|
|
16
16
|
*
|
|
17
17
|
* Requirements:
|
|
18
|
-
* - Node.js >=
|
|
18
|
+
* - Node.js >= 22.19.0 for @earendil-works/gondolin
|
|
19
19
|
* - QEMU installed (for example, `brew install qemu` on macOS)
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
22
|
import path from "node:path";
|
|
23
|
-
import { RealFSProvider, VM } from "@
|
|
23
|
+
import { RealFSProvider, VM } from "@earendil-works/gondolin";
|
|
24
24
|
import type { ExtensionAPI, ExtensionContext } from "@knightcodeai/cli";
|
|
25
25
|
import {
|
|
26
26
|
type BashOperations,
|
|
@@ -249,7 +249,6 @@ async function executeGondolinGrep(
|
|
|
249
249
|
const contextLines = params.context && params.context > 0 ? params.context : 0;
|
|
250
250
|
const effectiveLimit = Math.max(1, params.limit ?? DEFAULT_GREP_LIMIT);
|
|
251
251
|
const outputLines: string[] = [];
|
|
252
|
-
const details: GrepToolDetails = {};
|
|
253
252
|
let matchCount = 0;
|
|
254
253
|
let matchLimitReached = false;
|
|
255
254
|
let linesTruncated = false;
|
|
@@ -285,12 +284,14 @@ async function executeGondolinGrep(
|
|
|
285
284
|
signal,
|
|
286
285
|
);
|
|
287
286
|
|
|
288
|
-
if (matchCount === 0) return { content: [{ type: "text", text: "No matches found" }], details:
|
|
287
|
+
if (matchCount === 0) return { content: [{ type: "text", text: "No matches found" }], details: { matchCount: 0 } };
|
|
289
288
|
|
|
290
289
|
const rawOutput = outputLines.join("\n");
|
|
291
290
|
const truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });
|
|
292
291
|
const notices: string[] = [];
|
|
293
292
|
let output = truncation.content;
|
|
293
|
+
// The renderer counts output lines when this is missing, and context lines are not matches.
|
|
294
|
+
const details: GrepToolDetails = { matchCount };
|
|
294
295
|
|
|
295
296
|
if (matchLimitReached) {
|
|
296
297
|
details.matchLimitReached = effectiveLimit;
|
|
@@ -306,10 +307,7 @@ async function executeGondolinGrep(
|
|
|
306
307
|
}
|
|
307
308
|
if (notices.length > 0) output += `\n\n[${notices.join(". ")}]`;
|
|
308
309
|
|
|
309
|
-
return {
|
|
310
|
-
content: [{ type: "text", text: output }],
|
|
311
|
-
details: Object.keys(details).length > 0 ? details : undefined,
|
|
312
|
-
};
|
|
310
|
+
return { content: [{ type: "text", text: output }], details };
|
|
313
311
|
}
|
|
314
312
|
|
|
315
313
|
function sanitizeEnv(env: NodeJS.ProcessEnv | undefined): Record<string, string> | undefined {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"name": "knightcode-extension-gondolin",
|
|
9
9
|
"version": "0.84.3",
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@
|
|
11
|
+
"@earendil-works/gondolin": "0.14.0"
|
|
12
12
|
}
|
|
13
13
|
},
|
|
14
14
|
"node_modules/@cto.af/wtf8": {
|
|
@@ -20,32 +20,31 @@
|
|
|
20
20
|
"node": ">=20"
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
|
-
"node_modules/@
|
|
24
|
-
"version": "0.
|
|
25
|
-
"resolved": "https://registry.npmjs.org/@
|
|
26
|
-
"integrity": "sha512-
|
|
23
|
+
"node_modules/@earendil-works/gondolin": {
|
|
24
|
+
"version": "0.14.0",
|
|
25
|
+
"resolved": "https://registry.npmjs.org/@earendil-works/gondolin/-/gondolin-0.14.0.tgz",
|
|
26
|
+
"integrity": "sha512-MSw+EGcqFJeyKHdXEfm+nMRr74ytT4x8DGIohav0oPCHeVQAB9AajquM94cv2xqvIU3VDAaZZVC07IXsOY6OVQ==",
|
|
27
27
|
"license": "Apache-2.0",
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"cbor2": "^2.3.0",
|
|
30
|
-
"node-forge": "^1.3.3",
|
|
31
30
|
"ssh2": "^1.17.0",
|
|
32
|
-
"undici": "^6.
|
|
31
|
+
"undici": "^6.29.0"
|
|
33
32
|
},
|
|
34
33
|
"bin": {
|
|
35
34
|
"gondolin": "dist/bin/gondolin.js"
|
|
36
35
|
},
|
|
37
36
|
"engines": {
|
|
38
|
-
"node": ">=
|
|
37
|
+
"node": ">=22.19.0"
|
|
39
38
|
},
|
|
40
39
|
"optionalDependencies": {
|
|
41
|
-
"@
|
|
42
|
-
"@
|
|
40
|
+
"@earendil-works/gondolin-krun-runner-darwin-arm64": "0.14.0",
|
|
41
|
+
"@earendil-works/gondolin-krun-runner-linux-x64": "0.14.0"
|
|
43
42
|
}
|
|
44
43
|
},
|
|
45
|
-
"node_modules/@
|
|
46
|
-
"version": "0.
|
|
47
|
-
"resolved": "https://registry.npmjs.org/@
|
|
48
|
-
"integrity": "sha512-
|
|
44
|
+
"node_modules/@earendil-works/gondolin-krun-runner-darwin-arm64": {
|
|
45
|
+
"version": "0.14.0",
|
|
46
|
+
"resolved": "https://registry.npmjs.org/@earendil-works/gondolin-krun-runner-darwin-arm64/-/gondolin-krun-runner-darwin-arm64-0.14.0.tgz",
|
|
47
|
+
"integrity": "sha512-fvuhz1CZPaEbmXC0luZoXd1obAb0bjaaGJz33Jo63bhMlosYunAahItakh7cU0dnTlNFzufOSnpGOPqtuYjnpQ==",
|
|
49
48
|
"cpu": [
|
|
50
49
|
"arm64"
|
|
51
50
|
],
|
|
@@ -58,10 +57,10 @@
|
|
|
58
57
|
"gondolin-krun-runner": "bin/gondolin-krun-runner"
|
|
59
58
|
}
|
|
60
59
|
},
|
|
61
|
-
"node_modules/@
|
|
62
|
-
"version": "0.
|
|
63
|
-
"resolved": "https://registry.npmjs.org/@
|
|
64
|
-
"integrity": "sha512-
|
|
60
|
+
"node_modules/@earendil-works/gondolin-krun-runner-linux-x64": {
|
|
61
|
+
"version": "0.14.0",
|
|
62
|
+
"resolved": "https://registry.npmjs.org/@earendil-works/gondolin-krun-runner-linux-x64/-/gondolin-krun-runner-linux-x64-0.14.0.tgz",
|
|
63
|
+
"integrity": "sha512-91iw4smoOH/yOoAuQS6N2UZOxqSFwRhtk8rTyrokXBoWiWcveAzg4kHvnLcm40ZlNrWwzIDFrere4bkZeGDQcA==",
|
|
65
64
|
"cpu": [
|
|
66
65
|
"x64"
|
|
67
66
|
],
|
|
@@ -134,15 +133,6 @@
|
|
|
134
133
|
"license": "MIT",
|
|
135
134
|
"optional": true
|
|
136
135
|
},
|
|
137
|
-
"node_modules/node-forge": {
|
|
138
|
-
"version": "1.4.0",
|
|
139
|
-
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.4.0.tgz",
|
|
140
|
-
"integrity": "sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==",
|
|
141
|
-
"license": "(BSD-3-Clause OR GPL-2.0)",
|
|
142
|
-
"engines": {
|
|
143
|
-
"node": ">= 6.13.0"
|
|
144
|
-
}
|
|
145
|
-
},
|
|
146
136
|
"node_modules/safer-buffer": {
|
|
147
137
|
"version": "2.1.2",
|
|
148
138
|
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
|
@@ -173,9 +163,9 @@
|
|
|
173
163
|
"license": "Unlicense"
|
|
174
164
|
},
|
|
175
165
|
"node_modules/undici": {
|
|
176
|
-
"version": "6.
|
|
177
|
-
"resolved": "https://registry.npmjs.org/undici/-/undici-6.
|
|
178
|
-
"integrity": "sha512-
|
|
166
|
+
"version": "6.29.1",
|
|
167
|
+
"resolved": "https://registry.npmjs.org/undici/-/undici-6.29.1.tgz",
|
|
168
|
+
"integrity": "sha512-EvRlUt/QqAEvXdQeRMYUfwOQsfzpDztykrG2owGEE/rBOBoYv9uF39ZzsNDh4lTFHhTr2XOZjKkYgueD12ZmGA==",
|
|
179
169
|
"license": "MIT",
|
|
180
170
|
"engines": {
|
|
181
171
|
"node": ">=18.17"
|
|
@@ -273,6 +273,9 @@ export default function (knightcode: ExtensionAPI) {
|
|
|
273
273
|
|
|
274
274
|
case "clear":
|
|
275
275
|
return new Text(theme.fg("success", "✓ ") + theme.fg("muted", "Cleared all todos"), 0, 0);
|
|
276
|
+
|
|
277
|
+
default:
|
|
278
|
+
return new Text(result.content[0]?.type === "text" ? theme.fg("error", result.content[0].text) : "", 0, 0);
|
|
276
279
|
}
|
|
277
280
|
},
|
|
278
281
|
});
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* A stdio MCP server with one MCP App: a counter. It needs no dependencies (newline-delimited JSON-RPC over stdio).
|
|
4
|
+
*
|
|
5
|
+
* - `show_counter` (model and app): shows the counter; its `_meta.ui.resourceUri` names the app, `ui://counter/app.html`.
|
|
6
|
+
* - `increment` (app only, `_meta.ui.visibility: ["app"]`): changes the count, so outside Full access the desktop
|
|
7
|
+
* asks the user before it runs.
|
|
8
|
+
* - `read_count` (read-only): what the count is; an app may call it without asking.
|
|
9
|
+
*
|
|
10
|
+
* Add it to `~/.knightcode/agent/mcp.json`:
|
|
11
|
+
*
|
|
12
|
+
* { "mcpServers": { "counter": { "command": "node", "args": ["/path/to/server.mjs"], "exposure": "direct" } } }
|
|
13
|
+
*
|
|
14
|
+
* In the desktop app, ask KnightCode to show the counter: the tool's row draws the app. In the terminal, which draws
|
|
15
|
+
* no apps, the tool answers with its text.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { createInterface } from "node:readline";
|
|
19
|
+
|
|
20
|
+
const APP_URI = "ui://counter/app.html";
|
|
21
|
+
const APP_MIME = "text/html;profile=mcp-app";
|
|
22
|
+
let count = 0;
|
|
23
|
+
|
|
24
|
+
const APP_HTML = `<!doctype html>
|
|
25
|
+
<meta charset="utf-8">
|
|
26
|
+
<style>
|
|
27
|
+
body { margin: 0; padding: 12px 14px; font: 14px var(--font-sans, system-ui); color: var(--color-text-primary, #111);
|
|
28
|
+
background: var(--color-background-primary, transparent); }
|
|
29
|
+
.row { display: flex; align-items: center; gap: 10px; }
|
|
30
|
+
output { font: 600 22px var(--font-mono, monospace); min-width: 3ch; }
|
|
31
|
+
button { font: inherit; padding: 4px 12px; border-radius: var(--border-radius-md, 8px);
|
|
32
|
+
border: 1px solid var(--color-border-primary, #ccc); background: var(--color-background-secondary, #f4f4f4);
|
|
33
|
+
color: inherit; cursor: pointer; }
|
|
34
|
+
#status { margin-top: 8px; color: var(--color-text-secondary, #666); font-size: 12px; }
|
|
35
|
+
</style>
|
|
36
|
+
<div class="row">
|
|
37
|
+
<span>Count</span><output id="count">…</output>
|
|
38
|
+
<button id="add">Add one</button>
|
|
39
|
+
<button id="tell">Tell KnightCode</button>
|
|
40
|
+
</div>
|
|
41
|
+
<div id="status"></div>
|
|
42
|
+
<script>
|
|
43
|
+
const pending = new Map();
|
|
44
|
+
let next = 0;
|
|
45
|
+
const request = (method, params) =>
|
|
46
|
+
new Promise((resolve, reject) => {
|
|
47
|
+
const id = ++next;
|
|
48
|
+
pending.set(id, { resolve, reject });
|
|
49
|
+
parent.postMessage({ jsonrpc: "2.0", id, method, params }, "*");
|
|
50
|
+
});
|
|
51
|
+
const notify = (method, params) => parent.postMessage({ jsonrpc: "2.0", method, params }, "*");
|
|
52
|
+
const show = (n) => (document.getElementById("count").textContent = String(n));
|
|
53
|
+
const status = (text) => (document.getElementById("status").textContent = text);
|
|
54
|
+
const theme = (context) => {
|
|
55
|
+
for (const [name, value] of Object.entries(context?.styles?.variables ?? {}))
|
|
56
|
+
if (value) document.documentElement.style.setProperty(name, value);
|
|
57
|
+
};
|
|
58
|
+
window.addEventListener("message", (event) => {
|
|
59
|
+
const message = event.data;
|
|
60
|
+
if (!message || message.jsonrpc !== "2.0") return;
|
|
61
|
+
if (message.id !== undefined && !message.method) {
|
|
62
|
+
const waiter = pending.get(message.id);
|
|
63
|
+
pending.delete(message.id);
|
|
64
|
+
if (message.error) waiter?.reject(new Error(message.error.message));
|
|
65
|
+
else waiter?.resolve(message.result);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (message.method === "ui/notifications/tool-result") show(message.params?.structuredContent?.count ?? "?");
|
|
69
|
+
else if (message.method === "ui/notifications/tool-cancelled") status("The call was cancelled");
|
|
70
|
+
else if (message.method === "ui/notifications/host-context-changed") theme(message.params);
|
|
71
|
+
else if (message.method === "ui/resource-teardown") parent.postMessage({ jsonrpc: "2.0", id: message.id, result: {} }, "*");
|
|
72
|
+
else if (message.method === "ping") parent.postMessage({ jsonrpc: "2.0", id: message.id, result: {} }, "*");
|
|
73
|
+
});
|
|
74
|
+
document.getElementById("add").onclick = async () => {
|
|
75
|
+
try {
|
|
76
|
+
const result = await request("tools/call", { name: "increment", arguments: { by: 1 } });
|
|
77
|
+
show(result.structuredContent.count);
|
|
78
|
+
status("");
|
|
79
|
+
} catch (error) {
|
|
80
|
+
status(error.message);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
document.getElementById("tell").onclick = async () => {
|
|
84
|
+
const now = document.getElementById("count").textContent;
|
|
85
|
+
try {
|
|
86
|
+
await request("ui/message", { role: "user", content: [{ type: "text", text: "The counter app shows " + now + "." }] });
|
|
87
|
+
status("Sent");
|
|
88
|
+
} catch (error) {
|
|
89
|
+
status(error.message);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
(async () => {
|
|
93
|
+
const init = await request("ui/initialize", {
|
|
94
|
+
protocolVersion: "2026-01-26",
|
|
95
|
+
appInfo: { name: "counter", version: "1.0.0" },
|
|
96
|
+
appCapabilities: { availableDisplayModes: ["inline"] },
|
|
97
|
+
});
|
|
98
|
+
theme(init.hostContext);
|
|
99
|
+
notify("ui/notifications/initialized", {});
|
|
100
|
+
notify("ui/notifications/size-changed", { height: document.documentElement.scrollHeight });
|
|
101
|
+
})();
|
|
102
|
+
</script>`;
|
|
103
|
+
|
|
104
|
+
const tools = [
|
|
105
|
+
{
|
|
106
|
+
name: "show_counter",
|
|
107
|
+
description: "Show the counter app with the current count.",
|
|
108
|
+
inputSchema: { type: "object", properties: {} },
|
|
109
|
+
annotations: { readOnlyHint: true },
|
|
110
|
+
_meta: { ui: { resourceUri: APP_URI } },
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
name: "increment",
|
|
114
|
+
description: "Add to the counter.",
|
|
115
|
+
inputSchema: { type: "object", properties: { by: { type: "number" } } },
|
|
116
|
+
_meta: { ui: { visibility: ["app"] } },
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
name: "read_count",
|
|
120
|
+
description: "Read the counter.",
|
|
121
|
+
inputSchema: { type: "object", properties: {} },
|
|
122
|
+
annotations: { readOnlyHint: true },
|
|
123
|
+
},
|
|
124
|
+
];
|
|
125
|
+
|
|
126
|
+
const countResult = (text) => ({ content: [{ type: "text", text }], structuredContent: { count } });
|
|
127
|
+
|
|
128
|
+
function answer(method, params) {
|
|
129
|
+
switch (method) {
|
|
130
|
+
case "initialize":
|
|
131
|
+
return {
|
|
132
|
+
protocolVersion: params?.protocolVersion ?? "2025-11-25",
|
|
133
|
+
capabilities: { tools: {}, resources: {} },
|
|
134
|
+
serverInfo: { name: "counter-app", version: "1.0.0" },
|
|
135
|
+
};
|
|
136
|
+
case "ping":
|
|
137
|
+
return {};
|
|
138
|
+
case "tools/list":
|
|
139
|
+
return { tools };
|
|
140
|
+
case "tools/call":
|
|
141
|
+
if (params?.name === "show_counter") return countResult(`The counter is at ${count}.`);
|
|
142
|
+
if (params?.name === "increment") {
|
|
143
|
+
count += Number(params.arguments?.by ?? 1);
|
|
144
|
+
return countResult(`The counter is now ${count}.`);
|
|
145
|
+
}
|
|
146
|
+
if (params?.name === "read_count") return countResult(String(count));
|
|
147
|
+
throw Object.assign(new Error(`no tool ${params?.name}`), { code: -32602 });
|
|
148
|
+
case "resources/list":
|
|
149
|
+
return { resources: [{ uri: APP_URI, name: "Counter app", mimeType: APP_MIME }] };
|
|
150
|
+
case "resources/read":
|
|
151
|
+
if (params?.uri !== APP_URI) throw Object.assign(new Error(`no resource ${params?.uri}`), { code: -32002 });
|
|
152
|
+
return {
|
|
153
|
+
contents: [
|
|
154
|
+
{ uri: APP_URI, mimeType: APP_MIME, text: APP_HTML, _meta: { ui: { prefersBorder: true, csp: {} } } },
|
|
155
|
+
],
|
|
156
|
+
};
|
|
157
|
+
default:
|
|
158
|
+
throw Object.assign(new Error(`method not found: ${method}`), { code: -32601 });
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const write = (message) => process.stdout.write(`${JSON.stringify(message)}\n`);
|
|
163
|
+
createInterface({ input: process.stdin }).on("line", (line) => {
|
|
164
|
+
let message;
|
|
165
|
+
try {
|
|
166
|
+
message = JSON.parse(line);
|
|
167
|
+
} catch {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
// Notifications (no id) need no answer.
|
|
171
|
+
if (message.id === undefined || message.id === null) return;
|
|
172
|
+
try {
|
|
173
|
+
write({ jsonrpc: "2.0", id: message.id, result: answer(message.method, message.params) });
|
|
174
|
+
} catch (error) {
|
|
175
|
+
write({ jsonrpc: "2.0", id: message.id, error: { code: error.code ?? -32603, message: error.message } });
|
|
176
|
+
}
|
|
177
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { createRequire as __kcCreateRequire } from "node:module"; const require = __kcCreateRequire(import.meta.url);
|
|
2
|
-
import{buildCopilotDynamicHeaders,hasCopilotVisionInput}from"./chunk-HWXGL4YB.js";import{ANTHROPIC_FEDERATION_RULE_ID_ENV,ANTHROPIC_IDENTITY_TOKEN_FILE_ENV,ANTHROPIC_ORGANIZATION_ID_ENV,ANTHROPIC_SERVICE_ACCOUNT_ID_ENV,ANTHROPIC_WORKSPACE_ID_ENV}from"./chunk-HSL72VZI.js";import{Anthropic}from"./chunk-VJJ6J35N.js";import{retryProviderRequest}from"./chunk-57BPR4HF.js";import{MIN_ANSWER_TOKENS,adjustMaxTokensForThinking,buildBaseOptions,clampMaxTokensToContext,clampThinkingBudgetToAnswerRoom,getJsonSchemaToolParameters,resolveJsonSchemaStrictSampling,splitErrorToolResultImages,transformMessages}from"./chunk-GPHSXYPT.js";import{sanitizeSurrogates}from"./chunk-B2FT7RH5.js";import{headersToRecord}from"./chunk-DVFCXHT4.js";import{calculateCost,getCurrentTools,getInitialSystemMessage,getSystemMessageText,renderSystemMessageUpdate,resolveTranscript}from"./chunk-T47GKPON.js";import{getProviderEnvValue}from"./chunk-BRKUE2MD.js";import{parseJsonWithRepair,parseStreamingJson,parseToolCallArguments}from"./chunk-FA32X2UJ.js";import{AssistantMessageEventStream,appendAssistantMessageDiagnostic}from"./chunk-ETOMYYZC.js";import{getIdentityHeaders}from"./chunk-UU4A4NV5.js";import"./chunk-AHB7JV5B.js";function resolveCacheRetention(cacheRetention,env){return cacheRetention||(getProviderEnvValue("KNIGHTCODE_CACHE_RETENTION",env)==="long"?"long":"short")}function getCacheControl(model,cacheRetention,env){let retention=resolveCacheRetention(cacheRetention,env);if(retention==="none")return{retention};let ttl=retention==="long"&&getAnthropicCompat(model).supportsLongCacheRetention?"1h":void 0;return{retention,cacheControl:{type:"ephemeral",...ttl&&{ttl}}}}var claudeCodeVersion="2.1.280",claudeCodeTools=["Read","Write","Edit","Bash","Grep","Glob","AskUserQuestion","EnterPlanMode","ExitPlanMode","KillShell","NotebookEdit","Skill","Task","TaskOutput","TodoWrite","WebFetch","WebSearch"],ccToolLookup=new Map(claudeCodeTools.map(t=>[t.toLowerCase(),t])),toClaudeCodeName=name=>ccToolLookup.get(name.toLowerCase())??name,fromClaudeCodeName=(name,tools)=>{if(tools&&tools.length>0){let lowerName=name.toLowerCase(),matchedTool=tools.find(tool=>tool.name.toLowerCase()===lowerName);if(matchedTool)return matchedTool.name}return name};function convertImageBlock(image){return{type:"image",source:{type:"base64",media_type:image.mimeType,data:image.data}}}function convertContentBlocks(content){if(!content.some(c=>c.type==="image"))return sanitizeSurrogates(content.map(c=>c.text).join(`
|
|
3
|
-
`));let blocks=content.map(block=>block.type==="text"?{type:"text",text:sanitizeSurrogates(block.text)}:convertImageBlock(block));return blocks.some(b=>b.type==="text")||blocks.unshift({type:"text",text:"(see attached image)"}),blocks}var FINE_GRAINED_TOOL_STREAMING_BETA="fine-grained-tool-streaming-2025-05-14",INTERLEAVED_THINKING_BETA="interleaved-thinking-2025-05-14",SERVER_SIDE_FALLBACK_BETA="server-side-fallback-2026-07-01",MID_CONVERSATION_OUTPUT_CONFIG_BETA="mid-conversation-output-config-2026-07-01",THINKING_BINDING_CONTROLS_BETA="thinking-binding-controls-2026-08-01",INLINE_TOOLS_BETA="inline-tools-2026-09-15",DEFERRED_TOOL_PLACEHOLDER={name:"__knightcode_deferred_placeholder__",description:"Reserved placeholder. Never available. Never call this.",input_schema:{type:"object",properties:{},required:[]},defer_loading:!0};function shouldUseServerSideFallbackBeta(model){return(model.compat?.allowedFallbackModels?.length??0)>0}function getAnthropicCompat(model){let isOpenRouter=model.provider==="openrouter"||model.baseUrl.includes("openrouter.ai");return{supportsEagerToolInputStreaming:model.compat?.supportsEagerToolInputStreaming??!0,supportsLongCacheRetention:model.compat?.supportsLongCacheRetention??!0,sendSessionAffinityHeaders:model.compat?.sendSessionAffinityHeaders??isOpenRouter,sessionAffinityFormat:model.compat?.sessionAffinityFormat??(isOpenRouter?"openrouter":void 0),supportsCacheControlOnTools:model.compat?.supportsCacheControlOnTools??!0,supportsTemperature:model.compat?.supportsTemperature??!0,allowEmptySignature:model.compat?.allowEmptySignature??!1,supportsStrictTools:model.compat?.supportsStrictTools??!1,supportsMidConvoSystemMessages:model.compat?.supportsMidConvoSystemMessages??!1,supportsMidConvoToolChanges:model.compat?.supportsMidConvoToolChanges??!1}}function mergeHeaders(...headerSources){let merged={};for(let headers of headerSources)headers&&Object.assign(merged,headers);return merged}function hasHeader(headers,name){if(!headers)return!1;let expected=name.toLowerCase();for(let[key,value]of Object.entries(headers))if(key.toLowerCase()===expected&&value!==null&&value.trim().length>0)return!0;return!1}function hasRequestAuth(apiKey,headers){return!!apiKey||hasHeader(headers,"authorization")||hasHeader(headers,"x-api-key")||hasHeader(headers,"cf-aig-authorization")}function assertRequestAuth(provider,apiKey,headers){if(!hasRequestAuth(apiKey,headers))throw new Error(`No API key for provider: ${provider}`)}var KnightCodeAnthropic=class extends Anthropic{_shouldResolveDefaultCredentials(){return!1}};function getAnthropicFederation(model,apiKey,headers,env){if(model.provider!=="anthropic"||hasRequestAuth(apiKey,headers))return;let federationRuleId=getProviderEnvValue(ANTHROPIC_FEDERATION_RULE_ID_ENV,env),organizationId=getProviderEnvValue(ANTHROPIC_ORGANIZATION_ID_ENV,env),identityTokenFile=getProviderEnvValue(ANTHROPIC_IDENTITY_TOKEN_FILE_ENV,env);if(!(!federationRuleId||!organizationId||!identityTokenFile))return{organization_id:organizationId,workspace_id:getProviderEnvValue(ANTHROPIC_WORKSPACE_ID_ENV,env),authentication:{type:"oidc_federation",federation_rule_id:federationRuleId,service_account_id:getProviderEnvValue(ANTHROPIC_SERVICE_ACCOUNT_ID_ENV,env),identity_token:{source:"file",path:identityTokenFile}}}}var defaultFetchKey={},federationClients=new WeakMap,ANTHROPIC_MESSAGE_EVENTS=new Set(["message_start","message_delta","message_stop","content_block_start","content_block_delta","content_block_stop"]);function flushSseEvent(state){if(!state.event&&state.data.length===0)return null;let event={event:state.event,data:state.data.join(`
|
|
4
|
-
`),raw:[...state.raw]};return state.event=null,state.data=[],state.raw=[],event}function decodeSseLine(line,state){if(line==="")return flushSseEvent(state);if(state.raw.push(line),line.startsWith(":"))return null;let delimiterIndex=line.indexOf(":"),fieldName=delimiterIndex===-1?line:line.slice(0,delimiterIndex),value=delimiterIndex===-1?"":line.slice(delimiterIndex+1);return value.startsWith(" ")&&(value=value.slice(1)),fieldName==="event"?state.event=value:fieldName==="data"&&state.data.push(value),null}function nextLineBreakIndex(text){let carriageReturnIndex=text.indexOf("\r"),newlineIndex=text.indexOf(`
|
|
5
|
-
`);return carriageReturnIndex===-1?newlineIndex:newlineIndex===-1?carriageReturnIndex:Math.min(carriageReturnIndex,newlineIndex)}function consumeLine(text){let lineBreakIndex=nextLineBreakIndex(text);if(lineBreakIndex===-1)return null;let nextIndex=lineBreakIndex+1;return text[lineBreakIndex]==="\r"&&text[nextIndex]===`
|
|
6
|
-
`&&(nextIndex+=1),{line:text.slice(0,lineBreakIndex),rest:text.slice(nextIndex)}}async function*iterateSseMessages(body,signal){let reader=body.getReader(),decoder=new TextDecoder,state={event:null,data:[],raw:[]},buffer="";try{for(;;){if(signal?.aborted)throw new Error("Request was aborted");let{value,done}=await reader.read();if(done)break;buffer+=decoder.decode(value,{stream:!0});let consumed2=consumeLine(buffer);for(;consumed2;){buffer=consumed2.rest;let event=decodeSseLine(consumed2.line,state);event&&(yield event),consumed2=consumeLine(buffer)}}buffer+=decoder.decode();let consumed=consumeLine(buffer);for(;consumed;){buffer=consumed.rest;let event=decodeSseLine(consumed.line,state);event&&(yield event),consumed=consumeLine(buffer)}if(buffer.length>0){let event=decodeSseLine(buffer,state);event&&(yield event)}let trailingEvent=flushSseEvent(state);trailingEvent&&(yield trailingEvent)}finally{reader.releaseLock()}}async function*iterateAnthropicEvents(response,signal){if(!response.body)throw new Error("Attempted to iterate over an Anthropic response with no body");let sawMessageStart=!1,sawMessageEnd=!1;for await(let sse of iterateSseMessages(response.body,signal)){if(sse.event==="error")throw new Error(sse.data);if(ANTHROPIC_MESSAGE_EVENTS.has(sse.event??""))try{let event=parseJsonWithRepair(sse.data);event.type==="message_start"?sawMessageStart=!0:event.type==="message_stop"&&(sawMessageEnd=!0),yield event}catch(error){let message=error instanceof Error?error.message:String(error);throw new Error(`Could not parse Anthropic SSE event ${sse.event}: ${message}; data=${sse.data}; raw=${sse.raw.join("\\n")}`)}}if(sawMessageStart&&!sawMessageEnd)throw new Error("Anthropic stream ended before message_stop")}var stream=(model,context,options)=>{let stream2=new AssistantMessageEventStream,normalizedContext=resolveTranscript(context,getAnthropicCompat(model).supportsMidConvoSystemMessages),currentTools=getCurrentTools(normalizedContext.messages);return(async()=>{let output={role:"assistant",content:[],api:model.api,provider:model.provider,model:model.id,usage:{input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},stopReason:"pending",timestamp:Date.now()};try{let client,isOAuth,usageModel=model,inputTransformations;if(options?.client)client=options.client,isOAuth=!1;else{let apiKey=options?.apiKey,federation=getAnthropicFederation(model,apiKey,options?.headers,options?.env);federation||assertRequestAuth(model.provider,apiKey,options?.headers);let copilotDynamicHeaders;if(model.provider==="github-copilot"){let hasImages=hasCopilotVisionInput(normalizedContext.messages);copilotDynamicHeaders=buildCopilotDynamicHeaders({messages:normalizedContext.messages,hasImages})}let cacheSessionId=resolveCacheRetention(options?.cacheRetention,options?.env)==="none"?void 0:options?.sessionId,created=createClient(model,apiKey,options?.headers,options?.fetch,copilotDynamicHeaders,cacheSessionId,federation,options?.identity);client=created.client,isOAuth=created.isOAuthToken}let requestOptions={...options?.signal?{signal:options.signal}:{},...options?.timeoutMs!==void 0?{timeout:options.timeoutMs}:{},maxRetries:0},disablePreferredStrictTools=!1,response;for(;;){options?.signal?.throwIfAborted();let built=buildParams(model,normalizedContext,isOAuth,options,disablePreferredStrictTools);built.providerThinkingLevel&&(output.providerThinkingLevel=built.providerThinkingLevel);let params=built.params,nextParams=await options?.onPayload?.(params,model);nextParams!==void 0&&(params={...nextParams,stream:!0});try{response=await retryProviderRequest(()=>client.beta.messages.create(params,requestOptions).asResponse(),{maxRetries:options?.maxRetries,maxRetryDelayMs:options?.maxRetryDelayMs,signal:options?.signal});break}catch(error){if(options?.signal?.aborted||disablePreferredStrictTools||!built.hasPreferredStrictTools||!(error instanceof Anthropic.APIError)||error.status!==400||error.type!=="invalid_request_error"||!["The compiled grammar is too large","Too many strict tools (","Schemas contains too many parameters with union types ("].some(message=>error.message.includes(message)))throw error;disablePreferredStrictTools=!0,appendAssistantMessageDiagnostic(output,{type:"anthropic_strict_tools_fallback",timestamp:Date.now(),error:{message:error.message},details:{reason:"strict_tool_limits_exceeded"}})}}await options?.onResponse?.({status:response.status,headers:headersToRecord(response.headers)},model),stream2.push({type:"start",partial:output});let blocks=output.content;for await(let event of iterateAnthropicEvents(response,options?.signal))if(await options?.onProviderStreamEvent?.(event,model),event.type==="message_start"){output.responseId=event.message.id;let transformations=event.message.input_transformations;Array.isArray(transformations)&&(inputTransformations=transformations);let responseModel=event.message.model;responseModel!==model.id&&(output.responseModel=responseModel);let fallbackCost=responseModel===model.id?void 0:model.compat?.allowedFallbackModels?.find(fallback=>fallback.provider===model.provider&&fallback.model===responseModel)?.cost;usageModel=fallbackCost?{...model,id:responseModel,cost:fallbackCost}:model,output.usage.input=event.message.usage.input_tokens||0,output.usage.output=event.message.usage.output_tokens||0,output.usage.cacheRead=event.message.usage.cache_read_input_tokens||0,output.usage.cacheWrite=event.message.usage.cache_creation_input_tokens||0,output.usage.cacheWrite1h=event.message.usage.cache_creation?.ephemeral_1h_input_tokens||0,output.usage.totalTokens=output.usage.input+output.usage.output+output.usage.cacheRead+output.usage.cacheWrite,calculateCost(usageModel,output.usage)}else if(event.type==="content_block_start"){if(event.content_block.type==="fallback"){if(output.content.length>0)throw new Error("Anthropic performed an unsupported mid-output model fallback");continue}if(event.content_block.type==="text"){let block={type:"text",text:event.content_block.text??"",index:event.index};output.content.push(block),stream2.push({type:"text_start",contentIndex:output.content.length-1,partial:output})}else if(event.content_block.type==="thinking"){let block={type:"thinking",thinking:event.content_block.thinking??"",thinkingSignature:event.content_block.signature??"",index:event.index};output.content.push(block),stream2.push({type:"thinking_start",contentIndex:output.content.length-1,partial:output})}else if(event.content_block.type==="redacted_thinking"){let block={type:"thinking",thinking:"[Reasoning redacted]",thinkingSignature:event.content_block.data,redacted:!0,index:event.index};output.content.push(block),stream2.push({type:"thinking_start",contentIndex:output.content.length-1,partial:output})}else if(event.content_block.type==="tool_use"){let block={type:"toolCall",id:event.content_block.id,name:isOAuth?fromClaudeCodeName(event.content_block.name,currentTools):event.content_block.name,arguments:event.content_block.input??{},partialJson:"",index:event.index};output.content.push(block),stream2.push({type:"toolcall_start",contentIndex:output.content.length-1,partial:output})}}else if(event.type==="content_block_delta"){if(event.delta.type==="text_delta"){let index=blocks.findIndex(b=>b.index===event.index),block=blocks[index];block&&block.type==="text"&&(block.text+=event.delta.text,stream2.push({type:"text_delta",contentIndex:index,delta:event.delta.text,partial:output}))}else if(event.delta.type==="thinking_delta"){let index=blocks.findIndex(b=>b.index===event.index),block=blocks[index];block&&block.type==="thinking"&&(block.thinking+=event.delta.thinking,stream2.push({type:"thinking_delta",contentIndex:index,delta:event.delta.thinking,partial:output}))}else if(event.delta.type==="input_json_delta"){let index=blocks.findIndex(b=>b.index===event.index),block=blocks[index];block&&block.type==="toolCall"&&(block.partialJson+=event.delta.partial_json,block.arguments=parseStreamingJson(block.partialJson),stream2.push({type:"toolcall_delta",contentIndex:index,delta:event.delta.partial_json,partial:output}))}else if(event.delta.type==="signature_delta"){let index=blocks.findIndex(b=>b.index===event.index),block=blocks[index];block&&block.type==="thinking"&&(block.thinkingSignature=block.thinkingSignature||"",block.thinkingSignature+=event.delta.signature)}}else if(event.type==="content_block_stop"){let index=blocks.findIndex(b=>b.index===event.index),block=blocks[index];block&&(delete block.index,block.type==="text"?stream2.push({type:"text_end",contentIndex:index,content:block.text,partial:output}):block.type==="thinking"?stream2.push({type:"thinking_end",contentIndex:index,content:block.thinking,partial:output}):block.type==="toolCall"&&(Object.assign(block,parseToolCallArguments(block.partialJson)),delete block.partialJson,stream2.push({type:"toolcall_end",contentIndex:index,toolCall:block,partial:output})))}else if(event.type==="message_delta"){let transformations=event.input_transformations;if(Array.isArray(transformations)&&(inputTransformations=transformations),event.delta.stop_reason){output.rawStopReason=event.delta.stop_reason;let stopReasonResult=mapStopReason(event.delta.stop_reason,event.delta.stop_details);output.stopReason=stopReasonResult.stopReason,stopReasonResult.errorMessage&&(output.errorMessage=stopReasonResult.errorMessage)}if(event.usage){event.usage.input_tokens!=null&&(output.usage.input=event.usage.input_tokens),event.usage.output_tokens!=null&&(output.usage.output=event.usage.output_tokens),event.usage.cache_read_input_tokens!=null&&(output.usage.cacheRead=event.usage.cache_read_input_tokens),event.usage.cache_creation_input_tokens!=null&&(output.usage.cacheWrite=event.usage.cache_creation_input_tokens);let cacheCreation=event.usage.cache_creation;cacheCreation?.ephemeral_1h_input_tokens!=null&&(output.usage.cacheWrite1h=cacheCreation.ephemeral_1h_input_tokens);let thinkingTokens=event.usage.output_tokens_details?.thinking_tokens;thinkingTokens!=null&&(output.usage.reasoning=thinkingTokens)}output.usage.totalTokens=output.usage.input+output.usage.output+output.usage.cacheRead+output.usage.cacheWrite,calculateCost(usageModel,output.usage)}if(options?.signal?.aborted)throw new Error("Request was aborted");if(output.stopReason==="pending")throw new Error("Anthropic stream ended without a stop reason");if(output.stopReason==="aborted"||output.stopReason==="error")throw new Error(output.errorMessage||"An unknown error occurred");inputTransformations&&inputTransformations.length>0&&appendAssistantMessageDiagnostic(output,{type:"anthropic_input_transformations",timestamp:Date.now(),details:{transformations:inputTransformations.map(transformation=>({type:transformation.type??void 0,path:transformation.path??void 0,reason:transformation.reason??void 0}))}}),stream2.push({type:"done",reason:output.stopReason,message:output}),stream2.end()}catch(error){for(let block of output.content)delete block.index,delete block.partialJson;output.stopReason=options?.signal?.aborted?"aborted":"error",output.errorMessage=error instanceof Error?error.message:JSON.stringify(error),stream2.push({type:"error",reason:output.stopReason,error:output}),stream2.end()}})(),stream2};function mapThinkingLevelToEffort(model,level){let mapped=level?model.thinkingLevelMap?.[level]:void 0;if(typeof mapped=="string")return mapped;switch(level){case"minimal":case"low":return"low";case"medium":return"medium";case"high":return"high";default:return"high"}}var streamSimple=(model,context,options)=>{getAnthropicFederation(model,options?.apiKey,options?.headers,options?.env)||assertRequestAuth(model.provider,options?.apiKey,options?.headers);let base={...buildBaseOptions(model,context,options,options?.apiKey),toolChoice:options?.toolChoice};if(!options?.reasoning)return stream(model,context,{...base,thinkingEnabled:!1});if(model.compat?.forceAdaptiveThinking===!0){let effort=mapThinkingLevelToEffort(model,options.reasoning);return stream(model,context,{...base,thinkingEnabled:!0,effort})}let adjusted=adjustMaxTokensForThinking(base.maxTokens,model.maxTokens,options.reasoning,options.thinkingBudgets),maxTokens=clampMaxTokensToContext(model,context,adjusted.maxTokens),thinkingBudgetTokens=clampThinkingBudgetToAnswerRoom(adjusted.thinkingBudget,maxTokens);return thinkingBudgetTokens<MIN_ANSWER_TOKENS?stream(model,context,{...base,maxTokens,thinkingEnabled:!1}):stream(model,context,{...base,maxTokens,thinkingEnabled:!0,thinkingBudgetTokens})};function isOAuthToken(apiKey){return apiKey.includes("sk-ant-oat")}function createClient(model,apiKey,optionsHeaders,fetch,dynamicHeaders,sessionId,federation,identity){if(model.provider==="github-copilot")return{client:new KnightCodeAnthropic({apiKey:null,authToken:apiKey??null,baseURL:model.baseUrl,dangerouslyAllowBrowser:!0,fetch,defaultHeaders:mergeHeaders(getIdentityHeaders(model,identity),{accept:"application/json","anthropic-dangerous-direct-browser-access":"true"},model.headers,dynamicHeaders,optionsHeaders)}),isOAuthToken:!1};if(apiKey&&isOAuthToken(apiKey))return{client:new KnightCodeAnthropic({apiKey:null,authToken:apiKey,baseURL:model.baseUrl,dangerouslyAllowBrowser:!0,fetch,defaultHeaders:mergeHeaders({accept:"application/json","anthropic-dangerous-direct-browser-access":"true","user-agent":`claude-cli/${claudeCodeVersion}`,"x-app":"cli"},model.headers,optionsHeaders)}),isOAuthToken:!0};let compat=getAnthropicCompat(model),sessionAffinityHeaders={};if(sessionId&&compat.sendSessionAffinityHeaders){let header=compat.sessionAffinityFormat==="openrouter"?"x-session-id":"x-session-affinity";sessionAffinityHeaders[header]=sessionId}let defaultHeaders=mergeHeaders(getIdentityHeaders(model,identity),{accept:"application/json","anthropic-dangerous-direct-browser-access":"true"},sessionAffinityHeaders,model.headers,optionsHeaders);if(federation){let fetchKey=fetch??defaultFetchKey,clients=federationClients.get(fetchKey);clients||(clients=new Map,federationClients.set(fetchKey,clients));let key=JSON.stringify([model.baseUrl,federation]),client2=clients.get(key);return client2||(client2=new KnightCodeAnthropic({apiKey:null,authToken:null,config:federation,baseURL:model.baseUrl,dangerouslyAllowBrowser:!0,fetch}),clients.set(key,client2)),{client:client2.withOptions({defaultHeaders}),isOAuthToken:!1}}return{client:new KnightCodeAnthropic({apiKey:apiKey??null,authToken:null,baseURL:model.baseUrl,dangerouslyAllowBrowser:!0,fetch,defaultHeaders}),isOAuthToken:!1}}function getBetaFeatures(model,context,isOAuthToken2,nativeToolChanges,options){let configuredFeatures;for(let headers of[model.headers,options?.headers])for(let[name,value]of Object.entries(headers??{}))name.toLowerCase()==="anthropic-beta"&&(configuredFeatures=value);if(configuredFeatures===null)return[];if(configuredFeatures!==void 0)return[...new Set(configuredFeatures.split(",").map(feature=>feature.trim()).filter(feature=>feature.length>0))];let features=[];return isOAuthToken2&&features.push("claude-code-20250219","oauth-2025-04-20"),shouldUseFineGrainedToolStreamingBeta(model,context)&&features.push(FINE_GRAINED_TOOL_STREAMING_BETA),model.reasoning&&options?.thinkingEnabled===!0&&(options.interleavedThinking??!0)&&model.compat?.forceAdaptiveThinking!==!0&&features.push(INTERLEAVED_THINKING_BETA),shouldUseServerSideFallbackBeta(model)&&features.push(SERVER_SIDE_FALLBACK_BETA),model.compat?.supportsMidConvoEffort===!0&&features.push(MID_CONVERSATION_OUTPUT_CONFIG_BETA,THINKING_BINDING_CONTROLS_BETA),nativeToolChanges&&features.push(INLINE_TOOLS_BETA),[...new Set(features)]}function buildParams(model,context,isOAuthToken2,options,disablePreferredStrictTools=!1){let{cacheControl}=getCacheControl(model,options?.cacheRetention,options?.env),compat=getAnthropicCompat(model),initialSystemMessage=getInitialSystemMessage(context.messages),initialSystemText=initialSystemMessage?getSystemMessageText(initialSystemMessage):"",transformedMessages=transformMessages(context.messages,model,normalizeToolCallId),conversationMessages=initialSystemMessage?transformedMessages.slice(1):transformedMessages,hasPreferredStrictTools=!1,convertToolDefinitions=(tools,toolCacheControl2)=>{let definitions=convertTools(tools,isOAuthToken2,compat.supportsEagerToolInputStreaming,compat.supportsStrictTools,toolCacheControl2,disablePreferredStrictTools);return definitions.some((definition,index)=>{let config=tools[index].constrainedSampling;return definition.strict===!0&&config&&config.type==="json_schema"&&config.strict==="prefer"})&&(hasPreferredStrictTools=!0),definitions},initialTools=initialSystemMessage?.toolsAdded??[],nativeToolChanges=compat.supportsMidConvoSystemMessages&&compat.supportsMidConvoToolChanges&&initialTools.length>0,thinkingDisabled=model.reasoning&&options?.thinkingEnabled===!1&&model.thinkingLevelMap?.off!==null,effortMessages=model.compat?.supportsMidConvoEffort===!0&&!thinkingDisabled,converted=convertMessages(conversationMessages,isOAuthToken2,cacheControl,compat.allowEmptySignature,effortMessages?model.provider:void 0,nativeToolChanges?convertToolDefinitions:void 0),activeEffort=options?.effort??"high",betaFeatures=getBetaFeatures(model,context,isOAuthToken2,nativeToolChanges,options),params={model:model.id,messages:effortMessages?insertThinkingLevelMessages(converted,activeEffort):converted.messages,max_tokens:options?.maxTokens??model.maxTokens,stream:!0,...betaFeatures.length>0?{betas:betaFeatures}:{}};isOAuthToken2?(params.system=[{type:"text",text:"You are Claude Code, Anthropic's official CLI for Claude.",...cacheControl?{cache_control:cacheControl}:{}}],initialSystemText&¶ms.system.push({type:"text",text:sanitizeSurrogates(initialSystemText),...cacheControl?{cache_control:cacheControl}:{}})):initialSystemText&&(params.system=[{type:"text",text:sanitizeSurrogates(initialSystemText),...cacheControl?{cache_control:cacheControl}:{}}]),options?.temperature!==void 0&&!options?.thinkingEnabled&&model.compat?.supportsMidConvoEffort!==!0&&compat.supportsTemperature&&(params.temperature=options.temperature);let toolCacheControl=compat.supportsCacheControlOnTools?cacheControl:void 0;if(nativeToolChanges)params.tools=[...convertToolDefinitions(initialTools,toolCacheControl),DEFERRED_TOOL_PLACEHOLDER];else{let tools=getCurrentTools(context.messages);tools.length>0&&(params.tools=convertToolDefinitions(tools,toolCacheControl))}if(thinkingDisabled)params.thinking={type:"disabled"};else if(effortMessages)params.thinking={type:"adaptive",display:options?.thinkingDisplay??"summarized",block_binding:{prefix_mismatch_behavior:"drop_block"}},params.output_config={effort:"high"};else if(model.reasoning&&options?.thinkingEnabled){let display=options.thinkingDisplay??"summarized";model.compat?.forceAdaptiveThinking===!0?(params.thinking={type:"adaptive",display},options.effort&&(params.output_config={effort:options.effort})):params.thinking={type:"enabled",budget_tokens:options.thinkingBudgetTokens||1024,display}}if(options?.metadata){let userId=options.metadata.user_id;typeof userId=="string"&&(params.metadata={user_id:userId})}options?.toolChoice&&(typeof options.toolChoice=="string"?params.tool_choice={type:options.toolChoice}:params.tool_choice=options.toolChoice);let allowedFallbackModels=model.compat?.allowedFallbackModels;return allowedFallbackModels&&allowedFallbackModels.length>0&&(params.fallbacks=allowedFallbackModels.map(fallback=>({model:fallback.model}))),{params,hasPreferredStrictTools,providerThinkingLevel:effortMessages?activeEffort:void 0}}function normalizeToolCallId(id){return id.replace(/[^a-zA-Z0-9_-]/g,"_").slice(0,64)}function convertToolResult(msg,content=msg.content){return{type:"tool_result",tool_use_id:msg.toolCallId,content:convertContentBlocks(content),is_error:msg.isError}}function convertMessages(transformedMessages,isOAuthToken2,cacheControl,allowEmptySignature=!1,managedProvider,convertToolDefinitions){let params=[],assistantLevels=new Map,pendingSystemMessages=[],flushPendingSystemMessages=()=>{params.push(...pendingSystemMessages),pendingSystemMessages.length=0};for(let i=0;i<transformedMessages.length;i++){let msg=transformedMessages[i];if(msg.role==="system"){let text=renderSystemMessageUpdate(msg),blocks=[];if(text.length>0&&blocks.push({type:"text",text:sanitizeSurrogates(text)}),convertToolDefinitions){let added=msg.toolsAdded??[],redefined=new Set(added.map(tool=>tool.name));for(let tool of msg.toolsRemoved??[])redefined.has(tool.name)||blocks.push({type:"tool_removal",tool:{type:"tool_reference",name:isOAuthToken2?toClaudeCodeName(tool.name):tool.name}});for(let definition of convertToolDefinitions(added))blocks.push({type:"tool_addition",tool:{type:"tool_definition",definition}})}blocks.length>0&&pendingSystemMessages.push({role:"system",content:blocks})}else if(msg.role==="user")if(typeof msg.content=="string")msg.content.trim().length>0&¶ms.push({role:"user",content:sanitizeSurrogates(msg.content)});else{let filteredBlocks=msg.content.map(item=>item.type==="text"?{type:"text",text:sanitizeSurrogates(item.text)}:convertImageBlock(item)).filter(b=>b.type==="text"?b.text.trim().length>0:!0);if(filteredBlocks.length===0)continue;params.push({role:"user",content:filteredBlocks})}else if(msg.role==="assistant"){flushPendingSystemMessages();let blocks=[];for(let block of msg.content)if(block.type==="text"){if(block.text.trim().length===0)continue;blocks.push({type:"text",text:sanitizeSurrogates(block.text)})}else if(block.type==="thinking"){if(block.redacted){blocks.push({type:"redacted_thinking",data:block.thinkingSignature});continue}let thinkingSignature=block.thinkingSignature,hasThinkingSignature=!!thinkingSignature&&thinkingSignature.trim().length>0;if(block.thinking.trim().length===0&&!hasThinkingSignature)continue;hasThinkingSignature?blocks.push({type:"thinking",thinking:sanitizeSurrogates(block.thinking),signature:thinkingSignature}):blocks.push(allowEmptySignature?{type:"thinking",thinking:sanitizeSurrogates(block.thinking),signature:""}:{type:"text",text:sanitizeSurrogates(block.thinking)})}else block.type==="toolCall"&&blocks.push({type:"tool_use",id:block.id,name:isOAuthToken2?toClaudeCodeName(block.name):block.name,input:block.arguments??{}});if(blocks.length===0)continue;let messageIndex=params.length;params.push({role:"assistant",content:blocks}),managedProvider!==void 0&&msg.api==="anthropic-messages"&&msg.provider===managedProvider&&isAnthropicEffort(msg.providerThinkingLevel)&&assistantLevels.set(messageIndex,msg.providerThinkingLevel)}else if(msg.role==="toolResult"){let toolResults=[],errorImages=[],j=i;for(;j<transformedMessages.length&&transformedMessages[j].role==="toolResult";){let toolMsg=transformedMessages[j],split=splitErrorToolResultImages(toolMsg);toolResults.push(convertToolResult(toolMsg,split?.content)),split&&errorImages.push({type:"text",text:split.caption},...split.images.map(convertImageBlock)),j++}i=j-1,params.push({role:"user",content:[...toolResults,...errorImages]})}}if(flushPendingSystemMessages(),cacheControl&¶ms.length>0){let lastMessage=params[params.length-1];if(lastMessage.role==="user"||lastMessage.role==="system")if(Array.isArray(lastMessage.content)){let lastBlock=lastMessage.content[lastMessage.content.length-1];lastBlock&&(lastBlock.type==="text"||lastBlock.type==="image"||lastBlock.type==="tool_result"||lastBlock.type==="tool_addition"||lastBlock.type==="tool_removal")&&(lastBlock.cache_control=cacheControl)}else typeof lastMessage.content=="string"&&(lastMessage.content=[{type:"text",text:lastMessage.content,cache_control:cacheControl}])}return{messages:params,assistantLevels}}function isAnthropicEffort(value){return value==="low"||value==="medium"||value==="high"||value==="xhigh"||value==="max"}function insertThinkingLevelMessages(converted,activeEffort){let messages=[];for(let index=0;index<converted.messages.length;index++){let historicalEffort=converted.assistantLevels.get(index);historicalEffort!==void 0&&messages.push({role:"system",content:[],output_config:{effort:historicalEffort}}),messages.push(converted.messages[index])}return messages.push({role:"system",content:[],output_config:{effort:activeEffort}}),messages}function shouldUseFineGrainedToolStreamingBeta(model,context){return getCurrentTools(context.messages).length>0&&!getAnthropicCompat(model).supportsEagerToolInputStreaming}var ANTHROPIC_STRICT_UNSUPPORTED_KEYWORDS=new Set(["minimum","maximum","exclusiveMinimum","exclusiveMaximum","multipleOf","maxItems","uniqueItems","minContains","maxContains","minProperties","maxProperties"]),ANTHROPIC_STRICT_STRING_FORMATS=new Set(["date-time","time","date","duration","email","hostname","uri","ipv4","ipv6","uuid"]),isAnthropicStrictUnsupportedKeyword=(key,value)=>ANTHROPIC_STRICT_UNSUPPORTED_KEYWORDS.has(key)?!0:key==="minItems"?value!==0&&value!==1:key==="format"?typeof value!="string"||!ANTHROPIC_STRICT_STRING_FORMATS.has(value):!1;function convertTools(tools,isOAuthToken2,supportsEagerToolInputStreaming,supportsStrictTools,cacheControl,disablePreferredStrictTools=!1){return tools?tools.map((tool,index)=>{let config=tool.constrainedSampling,strict=disablePreferredStrictTools&&config&&config.type==="json_schema"&&config.strict==="prefer"?void 0:resolveJsonSchemaStrictSampling(tool,supportsStrictTools,isAnthropicStrictUnsupportedKeyword),parameters=getJsonSchemaToolParameters(tool,strict),schema=parameters,legacyInputSchema={type:"object",properties:schema.properties??{},required:schema.required??[]},inputSchema=strict===!0?{...parameters,...legacyInputSchema}:legacyInputSchema;return{name:isOAuthToken2?toClaudeCodeName(tool.name):tool.name,description:tool.description,...supportsEagerToolInputStreaming?{eager_input_streaming:!0}:{},...strict===!0?{strict:!0}:{},input_schema:inputSchema,...cacheControl&&index===tools.length-1?{cache_control:cacheControl}:{}}}):[]}function mapStopReason(reason,stopDetails){switch(reason){case"end_turn":return{stopReason:"stop"};case"max_tokens":return{stopReason:"length"};case"tool_use":return{stopReason:"toolUse"};case"refusal":return{stopReason:"error",errorMessage:stopDetails?.explanation||"The model refused to complete the request"};case"pause_turn":return{stopReason:"stop"};case"stop_sequence":return{stopReason:"stop"};case"sensitive":return{stopReason:"error",errorMessage:"Provider stopped with: sensitive"};default:throw new Error(`Unhandled stop reason: ${reason}`)}}export{stream,streamSimple};
|