@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
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,111 @@
|
|
|
1
1
|
# @knightcodeai/cli
|
|
2
2
|
|
|
3
|
+
## 0.21.1
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- Changed model selector rows to show a model's display name when that name has words the id does not.
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- Fixed Gemini tool calls whose JSON Schema used const, by sending a single-value enum and leaving literal schema keys intact.
|
|
12
|
+
|
|
13
|
+
- Fixed Kimi K3.1 Pro models using Kimi K2 request settings. Point releases now share K3's request format, subscription costs, and output limit.
|
|
14
|
+
|
|
15
|
+
- Fixed streamed tool-call arguments being parsed and redrawn once per fragment. A call now renders once per frame, and the parser keeps only the text it still needs.
|
|
16
|
+
|
|
17
|
+
- Fixed images inside padded or colored boxes disappearing once their first row scrolls above the viewport.
|
|
18
|
+
|
|
19
|
+
## 0.21.0
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- Added background terminals. The `bash` and `powershell` tools take `run_in_background`, so the agent can start a dev server, watcher, or long build and keep working; it is told how the command ended, with the end of its output, and continues from there. Press Ctrl+B to move a running command to the background without restarting it, see running commands in a row above the footer, and run `/tasks` to watch their output or stop them. The new `task_stop` tool is on whenever a shell tool is. Background commands end with the session; print and JSON modes wait for them before exiting.
|
|
24
|
+
|
|
25
|
+
- Added `file/list` and `file/write` to the app server, and `mtimeMs` to `file/read`: a client can list a folder of the thread's cwd one level at a time for a file tree, and write a file it showed, refused with `fileChanged` when the file has changed since it was read.
|
|
26
|
+
|
|
27
|
+
- Added `file/read`, `thread/diff/file` and `git/origin` to the app server, and a dry run for `thread/handoff`: a client can show a file read-only, expand the unchanged lines between a diff's hunks from the two trees `thread/diff/read` now names, link a file to its GitHub page from the checkout's origin and branch, and check a handoff before the user confirms it.
|
|
28
|
+
|
|
29
|
+
- Added plan review to the desktop app: a submitted plan asks "Implement this plan?" by itself, offering to implement it in the thread, in a new thread with only the plan, or to exit planning.
|
|
30
|
+
|
|
31
|
+
- Added MCP Apps: a tool that declares an app (`_meta.ui.resourceUri`) shows it in the desktop app, which reads and calls its server through the new `mcp/app/readResource` and `mcp/app/callTool` app server methods, asking first before a call that may change things.
|
|
32
|
+
|
|
33
|
+
- Added a confirmation step to device-code sign-in. The dialog shows the code and waits for Enter before opening the browser and copying the code to the clipboard, so a code already on the clipboard is not replaced silently. Providers can turn either action off with `openBrowserOnConfirm` and `copyCodeOnConfirm` on the device-code event.
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
|
|
37
|
+
- Changed a session that implements a plan in a new thread to be named after the plan's first line instead of the handoff text, and the app server now tells clients the name a new session's setup gives it.
|
|
38
|
+
|
|
39
|
+
### Fixed
|
|
40
|
+
|
|
41
|
+
- Fixed KnightCode Messages replies dropping the concrete model a provider reports.
|
|
42
|
+
|
|
43
|
+
- Fixed Anthropic requests rejected when an organization caps effort below the cached top-level level.
|
|
44
|
+
|
|
45
|
+
- Fixed the command reference, settings, and MCP pages so they match the current flags, anchors, and timeout values.
|
|
46
|
+
|
|
47
|
+
- Fixed command output corrupted when a multi-byte character is split across two chunks.
|
|
48
|
+
|
|
49
|
+
- Fixed fd and rg setup on unsupported CPU architectures, so KnightCode warns instead of downloading an x86-64 binary.
|
|
50
|
+
|
|
51
|
+
- Fixed the todo example crashing the terminal when a tool call fails validation.
|
|
52
|
+
|
|
53
|
+
- Fixed startup when a configured package cannot be installed, so KnightCode skips that package, warns, and continues.
|
|
54
|
+
|
|
55
|
+
- Fixed `exec` from extensions swallowing the reason a command could not start. A missing binary or a bad working directory used to return an empty `stderr` with exit code 1; the spawn error message is now in `stderr`.
|
|
56
|
+
|
|
57
|
+
- Fixed fuzzy search ranking scattered matches above exact ones. Typing `opus` in the model selector now lists Claude Opus models before names that merely contain those letters, and the session search ranks name and text hits above scattered characters, ignores where a match sits in long message text, and no longer matches scattered characters in session ids.
|
|
58
|
+
|
|
59
|
+
- Fixed plan mode's instructions showing in the desktop app's transcript: an extension message sent with `display: false` is no longer an app server item, live or read back.
|
|
60
|
+
|
|
61
|
+
- Fixed standalone binaries built with a Bun release that broke abort, HTTPS, file tools, image resize, and session resume.
|
|
62
|
+
|
|
63
|
+
- Fixed fullscreen double-click selection so +, \, ~, _, and . stay part of the word.
|
|
64
|
+
|
|
65
|
+
- Fixed deeply nested blockquotes growing without bound and crashing the terminal.
|
|
66
|
+
|
|
67
|
+
- Fixed a turn's changes going unrecorded in a checkout with more than 500 untracked files: a file the agent created there never reached `turn/diff/updated`, so the desktop app's Last Turn was empty and offered no Undo. Past 500, turn snapshots now leave out only untracked folders holding 200 or more files, and fall back to tracked files only when more than 500 remain.
|
|
68
|
+
|
|
69
|
+
### Security
|
|
70
|
+
|
|
71
|
+
- Security Rejected MCP authorization endpoints that are not http or https before sign-in opens them.
|
|
72
|
+
|
|
73
|
+
## 0.20.0
|
|
74
|
+
|
|
75
|
+
### Added
|
|
76
|
+
|
|
77
|
+
- Added image input for classifier models on TypeSafe, Cloudflare Workers AI and OpenRouter, with Clef Omni and Jev 1.14 on Workers AI. A classifier model that lists image input now judges `images`, and a provider-level `compat` in `models.json` (`imageInput`, `sendImageOptInHeader`) tells a custom provider which request format its classifiers expect.
|
|
78
|
+
|
|
79
|
+
- Added declarative views for extensions: `ctx.ui.setWidget(key, view)` and `details.view` on tool results and extension messages, drawn in the terminal and by app server clients, which also receive extension status, titles, working messages and widgets, and send widget button and field events back through `ctx.ui.onViewEvent`.
|
|
80
|
+
|
|
81
|
+
- Added `messageId` and `timestamp` to the context a Markdown transformer receives, set to the session entry's id and ISO timestamp when a user or assistant message is rendered from the saved session. Messages rendered live leave both undefined.
|
|
82
|
+
|
|
83
|
+
- Added a `totalFromProvider` flag to usage cost that records whether the total is the cost billed by the provider or an estimate from catalog rates, so session totals can tell the two apart.
|
|
84
|
+
|
|
85
|
+
### Fixed
|
|
86
|
+
|
|
87
|
+
- Fixed Claude rejecting a request with a 400 when a system prompt update was followed by an assistant reply that sends no content, such as another model's empty or reasoning-only reply. The update now waits for the next assistant message that is actually sent.
|
|
88
|
+
|
|
89
|
+
- Fixed a resumed session failing every request after a response was cut off mid tool call: recovery dropped the truncated tool call but kept its tool result, and providers reject a tool result without its call. Both are now omitted together.
|
|
90
|
+
|
|
91
|
+
- Fixed the grep tool honouring `RIPGREP_CONFIG_PATH`: a user ripgrep config such as `--fixed-strings` silently turned regex searches literal and returned incomplete results. The tool now runs ripgrep with `--no-config`.
|
|
92
|
+
|
|
93
|
+
- Fixed the HTML export header's total cost to add up each message's recorded total, so a total billed by the provider is shown rather than a sum of catalog estimates. Sessions recorded before totals were stored still fall back to the sum of the parts.
|
|
94
|
+
|
|
95
|
+
- Fixed the HTML export of a very long session failing with "Maximum call stack size exceeded". The session tree is now walked iteratively, so its depth no longer depends on the JavaScript call stack.
|
|
96
|
+
|
|
97
|
+
- Fixed the HTML export ignoring the system messages stored in a session. The first system message on a branch now renders as the system prompt and tool list, and later ones as updates that name the changed prompt sections and the tools added or removed. `knightcode --export` now shows the prompt and tools as well; sessions without system messages still fall back to the exporting agent's current prompt and tools.
|
|
98
|
+
|
|
99
|
+
- Fixed the Gondolin example's grep tool reporting a wrong match count when context lines were requested. It now returns the number of matches it found, as the built-in grep does, so the tool row no longer counts context lines, or the "No matches found" line, as matches.
|
|
100
|
+
|
|
101
|
+
- Fixed the Gondolin example extension depending on a package name that does not exist on npm, so `npm install` in its directory failed. It now depends on the published Gondolin package, version 0.14.0, which drops node-forge and moves to a patched undici, clearing the advisories both had. The containerization docs link the Gondolin project and state its new Node.js 22.19 minimum.
|
|
102
|
+
|
|
103
|
+
- Fixed cancelling a shell command on macOS sometimes letting the next command in a sequence such as `a; b` start. The process group is now stopped before it is killed, which narrows the window in which a killed child can wake its shell.
|
|
104
|
+
|
|
105
|
+
- Fixed updates of installer-managed installs being stopped by security scanners that block npm's `--min-release-age=0` flag. The managed update runs `npm ci` against a release lockfile that pins every package, so the flag never had an effect and is no longer passed. Global npm, pnpm and bun self-updates keep their age-gate overrides.
|
|
106
|
+
|
|
107
|
+
- Fixed OpenRouter session costs to use the total OpenRouter bills, including upstream inference for bring-your-own-key requests, instead of an estimate from catalog rates. When OpenRouter reports no valid accounting, the catalog estimate is still used.
|
|
108
|
+
|
|
3
109
|
## 0.19.0
|
|
4
110
|
|
|
5
111
|
### Added
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { createRequire as __kcCreateRequire } from "node:module"; const require = __kcCreateRequire(import.meta.url);
|
|
2
|
+
import{applyOpenRouterReportedCost,isOpenRouterModel}from"./chunk-5ZES34QN.js";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-QEVQ7EIS.js";import{sanitizeSurrogates}from"./chunk-B2FT7RH5.js";import{headersToRecord}from"./chunk-DVFCXHT4.js";import{calculateCost,getCurrentTools,getInitialSystemMessage,resolveTranscript}from"./chunk-RRNUW65U.js";import{getProviderEnvValue}from"./chunk-BRKUE2MD.js";import{ToolCallArgumentsStream,parseJsonWithRepair}from"./chunk-424HQSAU.js";import{AssistantMessageEventStream,appendAssistantMessageDiagnostic}from"./chunk-ETOMYYZC.js";import{getIdentityHeaders,getSystemMessageText,renderSystemMessageUpdate}from"./chunk-BLHRVYHG.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 openBlocks=new Map,openBlock=anthropicIndex=>{let open=openBlocks.get(anthropicIndex);return open===void 0?void 0:{...open,block:output.content[open.contentIndex]}};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}event.content_block.type==="text"?(output.content.push({type:"text",text:event.content_block.text??""}),openBlocks.set(event.index,{contentIndex:output.content.length-1}),stream2.push({type:"text_start",contentIndex:output.content.length-1,partial:output})):event.content_block.type==="thinking"?(output.content.push({type:"thinking",thinking:event.content_block.thinking??"",thinkingSignature:event.content_block.signature??""}),openBlocks.set(event.index,{contentIndex:output.content.length-1}),stream2.push({type:"thinking_start",contentIndex:output.content.length-1,partial:output})):event.content_block.type==="redacted_thinking"?(output.content.push({type:"thinking",thinking:"[Reasoning redacted]",thinkingSignature:event.content_block.data,redacted:!0}),openBlocks.set(event.index,{contentIndex:output.content.length-1}),stream2.push({type:"thinking_start",contentIndex:output.content.length-1,partial:output})):event.content_block.type==="tool_use"&&(output.content.push({type:"toolCall",id:event.content_block.id,name:isOAuth?fromClaudeCodeName(event.content_block.name,currentTools):event.content_block.name,arguments:event.content_block.input??{}}),openBlocks.set(event.index,{contentIndex:output.content.length-1,arguments:new ToolCallArgumentsStream}),stream2.push({type:"toolcall_start",contentIndex:output.content.length-1,partial:output}))}else if(event.type==="content_block_delta"){let open=openBlock(event.index);event.delta.type==="text_delta"?open?.block.type==="text"&&(open.block.text+=event.delta.text,stream2.push({type:"text_delta",contentIndex:open.contentIndex,delta:event.delta.text,partial:output})):event.delta.type==="thinking_delta"?open?.block.type==="thinking"&&(open.block.thinking+=event.delta.thinking,stream2.push({type:"thinking_delta",contentIndex:open.contentIndex,delta:event.delta.thinking,partial:output})):event.delta.type==="input_json_delta"?open?.block.type==="toolCall"&&open.arguments!==void 0&&(open.block.arguments=open.arguments.append(event.delta.partial_json),stream2.push({type:"toolcall_delta",contentIndex:open.contentIndex,delta:event.delta.partial_json,partial:output})):event.delta.type==="signature_delta"&&open?.block.type==="thinking"&&(open.block.thinkingSignature=open.block.thinkingSignature||"",open.block.thinkingSignature+=event.delta.signature)}else if(event.type==="content_block_stop"){let open=openBlock(event.index);if(openBlocks.delete(event.index),open){let{block,contentIndex:index}=open;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"&&open.arguments!==void 0&&(Object.assign(block,open.arguments.finish()),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),isOpenRouterModel(model)&&event.usage&&applyOpenRouterReportedCost(output.usage,event.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){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:"low"};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"){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;flushPendingSystemMessages();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};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { createRequire as __kcCreateRequire } from "node:module"; const require = __kcCreateRequire(import.meta.url);
|
|
2
|
+
import{convertResponsesMessages,convertResponsesTools,getResponsesToolSupport,processResponsesStream}from"./chunk-O2HKRIDR.js";import{AzureOpenAI}from"./chunk-ZW7FVRHT.js";import{clampOpenAIPromptCacheKey}from"./chunk-N6VDWLND.js";import"./chunk-HUQB436V.js";import{formatProviderError,normalizeProviderError}from"./chunk-YDO6TXKD.js";import{resolveAzureConfig,resolveDeploymentName}from"./chunk-AANBXVWQ.js";import{retryProviderRequest}from"./chunk-57BPR4HF.js";import{buildBaseOptions,createGrammarToolInputProperties,resolveSamplingParams}from"./chunk-QEVQ7EIS.js";import"./chunk-B2FT7RH5.js";import{headersToRecord}from"./chunk-DVFCXHT4.js";import{clampThinkingLevel,getDeclaredTools,resolveTranscript,resolveTranscriptTools}from"./chunk-RRNUW65U.js";import"./chunk-BRKUE2MD.js";import"./chunk-424HQSAU.js";import{AssistantMessageEventStream}from"./chunk-ETOMYYZC.js";import{getIdentityHeaders}from"./chunk-BLHRVYHG.js";import"./chunk-AHB7JV5B.js";var AZURE_TOOL_CALL_PROVIDERS=new Set(["openai","openai-codex","opencode","azure"]),OPENAI_RESPONSES_MIN_OUTPUT_TOKENS=16;function formatAzureOpenAIError(error){return formatProviderError(normalizeProviderError(error),"Azure OpenAI API error")}var stream=(model,context,options)=>{let stream2=new AssistantMessageEventStream,normalizedContext=resolveTranscript(context,model.compat?.supportsMidConvoSystemMessages);return(async()=>{let deploymentName=resolveDeploymentName(model,options),output={role:"assistant",content:[],api:"azure-openai-responses",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 apiKey=options?.apiKey;if(!apiKey)throw new Error(`No API key for provider: ${model.provider}`);let client=createClient(model,apiKey,options),grammarToolInputProperties=createGrammarToolInputProperties(getDeclaredTools(normalizedContext.messages),model.compat?.supportsOpenAIGrammarTools??!1),params=buildParams(model,normalizedContext,options,deploymentName,grammarToolInputProperties),nextParams=await options?.onPayload?.(params,model);nextParams!==void 0&&(params=nextParams);let requestOptions={...options?.signal?{signal:options.signal}:{},...options?.timeoutMs!==void 0?{timeout:options.timeoutMs}:{},maxRetries:0},{data:openaiStream,response}=await retryProviderRequest(()=>client.responses.create(params,requestOptions).withResponse(),{maxRetries:options?.maxRetries,maxRetryDelayMs:options?.maxRetryDelayMs,signal:options?.signal});if(await options?.onResponse?.({status:response.status,headers:headersToRecord(response.headers)},model),stream2.push({type:"start",partial:output}),await processResponsesStream(openaiStream,output,stream2,model,{onProviderStreamEvent:options?.onProviderStreamEvent,grammarToolInputProperties}),options?.signal?.aborted)throw new Error("Request was aborted");if(output.stopReason==="pending")throw new Error("Azure OpenAI Responses stream ended without a stop reason");if(output.stopReason==="aborted"||output.stopReason==="error")throw new Error(output.errorMessage||"An unknown error occurred");stream2.push({type:"done",reason:output.stopReason,message:output}),stream2.end()}catch(error){output.stopReason=options?.signal?.aborted?"aborted":"error",output.errorMessage=formatAzureOpenAIError(error),stream2.push({type:"error",reason:output.stopReason,error:output}),stream2.end()}})(),stream2},streamSimple=(model,context,options)=>{let apiKey=options?.apiKey;if(!apiKey)throw new Error(`No API key for provider: ${model.provider}`);let base={...buildBaseOptions(model,context,options,apiKey),toolChoice:options?.toolChoice},clampedReasoning=options?.reasoning?clampThinkingLevel(model,options.reasoning):void 0;return stream(model,context,{...base,reasoningEffort:clampedReasoning==="off"?void 0:clampedReasoning})};function createClient(model,apiKey,options){let headers={...getIdentityHeaders(model,options?.identity),...model.headers};options?.headers&&Object.assign(headers,options.headers);let{baseUrl,apiVersion}=resolveAzureConfig(model,options);return new AzureOpenAI({apiKey,apiVersion,dangerouslyAllowBrowser:!0,fetch:options?.fetch,defaultHeaders:headers,baseURL:baseUrl})}function buildParams(model,context,options,deploymentName,grammarToolInputProperties=createGrammarToolInputProperties(getDeclaredTools(context.messages),model.compat?.supportsOpenAIGrammarTools??!1)){let supportsAdditionalTools=model.compat?.supportsAdditionalTools??!1,supportsToolSearch=model.compat?.supportsToolSearch??!1,transcriptTools=resolveTranscriptTools(context.messages,getResponsesToolSupport({supportsMidConvoSystemMessages:model.compat?.supportsMidConvoSystemMessages??!1,supportsAdditionalTools,supportsToolSearch})),messages=convertResponsesMessages(model,context,AZURE_TOOL_CALL_PROVIDERS,{grammarToolInputProperties,supportsMidConvoSystemMessages:model.compat?.supportsMidConvoSystemMessages??!1,supportsAdditionalTools,supportsToolSearch,toolOptions:{supportsStrictMode:model.compat?.supportsStrictMode??!0,supportsOpenAIGrammarTools:model.compat?.supportsOpenAIGrammarTools??!1}}),params={model:deploymentName,input:messages,stream:!0,prompt_cache_key:clampOpenAIPromptCacheKey(options?.sessionId),store:!1};options?.maxTokens&&(params.max_output_tokens=Math.max(options.maxTokens,OPENAI_RESPONSES_MIN_OUTPUT_TOKENS)),options?.temperature!==void 0&&(params.temperature=options?.temperature),transcriptTools.requestTools.length>0&&(params.tools=convertResponsesTools(transcriptTools.requestTools,{supportsStrictMode:model.compat?.supportsStrictMode??!0,supportsOpenAIGrammarTools:model.compat?.supportsOpenAIGrammarTools??!1})),options?.toolChoice!==void 0&&(params.tool_choice=options.toolChoice);let reasoningEffort=options?.reasoningEffort??(options?.reasoningSummary?"medium":void 0);if(model.reasoning)if(reasoningEffort){let effort=options?.reasoningEffort?model.thinkingLevelMap?.[options.reasoningEffort]??options.reasoningEffort:reasoningEffort;params.reasoning={effort,summary:options?.reasoningSummary||"auto"},params.include=["reasoning.encrypted_content"]}else model.thinkingLevelMap?.off!==null&&(params.reasoning={effort:model.thinkingLevelMap?.off??"none"});let samplingParams=resolveSamplingParams(model,reasoningEffort??"off",options?.samplingParams);return samplingParams&&Object.assign(params,samplingParams),params}export{stream,streamSimple};
|