@knightcodeai/cli 0.18.2 → 0.18.4
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 +38 -0
- package/dist/bundle/chunks/{anthropic-messages-QIZAJBTA.js → anthropic-messages-VD2GN7C4.js} +1 -1
- package/dist/bundle/chunks/azure-openai-responses-6IJ5JZ3Y.js +2 -0
- package/dist/bundle/chunks/{chunk-IGNYWP4P.js → chunk-3PSTVJEH.js} +1 -1
- package/dist/bundle/chunks/chunk-3VVG5HD5.js +11 -0
- package/dist/bundle/chunks/{chunk-XZJICKQ6.js → chunk-4DOSUUX3.js} +2 -2
- package/dist/bundle/chunks/{chunk-YQ26QP2R.js → chunk-CRLO4X52.js} +1 -1
- package/dist/bundle/chunks/{chunk-7CWBI3GL.js → chunk-FG6M5B3F.js} +10 -10
- package/dist/bundle/chunks/{chunk-LA7DDYYM.js → chunk-GCXF7ZNR.js} +7 -6
- package/dist/bundle/chunks/{chunk-ZB5LGRB5.js → chunk-HRZGVTRM.js} +1 -1
- package/dist/bundle/chunks/{chunk-HNZSETB2.js → chunk-L2XRQUGK.js} +2 -2
- package/dist/bundle/chunks/chunk-SLWTIEJK.js +16 -0
- package/dist/bundle/chunks/{chunk-R2XYMDTS.js → chunk-T6M3FJYR.js} +1 -1
- package/dist/bundle/chunks/{chunk-55AAX2FB.js → chunk-XILUO467.js} +1 -1
- package/dist/bundle/chunks/{cli-66ZLURJW.js → cli-AMSWLH7A.js} +1 -1
- package/dist/bundle/chunks/{cloudflare-workers-ai-system-one-LA7TF5LV.js → cloudflare-workers-ai-system-one-JBMTTHVI.js} +1 -1
- package/dist/bundle/chunks/{easter-egg-3d-DQYQIGP2.js → easter-egg-3d-VH6SGOZS.js} +1 -1
- package/dist/bundle/chunks/{execute-KJDH5JWX.js → execute-4UQWU4SD.js} +9 -3
- package/dist/bundle/chunks/{google-generative-ai-GEBPSQBJ.js → google-generative-ai-QBWYWMCA.js} +1 -1
- package/dist/bundle/chunks/{google-vertex-BRMU44TN.js → google-vertex-4KVZWEAI.js} +1 -1
- package/dist/bundle/chunks/{mistral-conversations-FKYKJV7R.js → mistral-conversations-NUSSE6NX.js} +1 -1
- package/dist/bundle/chunks/openai-codex-responses-66UQNGWB.js +10 -0
- package/dist/bundle/chunks/{openai-completions-A6RD26ED.js → openai-completions-QTYKORY2.js} +2 -2
- package/dist/bundle/chunks/{openai-decisions-OBTJNBTE.js → openai-decisions-ENPSYANO.js} +1 -1
- package/dist/bundle/chunks/openai-responses-JSX72BKV.js +3 -0
- package/dist/bundle/chunks/{typesafe-system-one-FZHRNG67.js → typesafe-system-one-ETHWOYKC.js} +1 -1
- package/dist/bundle/chunks/virtual-modules-AK4BYDR6.js +2 -0
- package/dist/bundle/cli-runtime.js +1 -1
- package/dist/core/export-html/template.html +1 -0
- package/dist/core/export-html/template.js +2 -1
- package/dist/core/export-html/vendor/marked-cjk-friendly.min.js +6 -0
- package/dist/core/export-html/vendor/marked.min.js +30 -29
- package/docs/codemode.md +2 -2
- package/docs/environment-variables.md +1 -0
- package/docs/extensions.md +38 -21
- package/package.json +1 -1
- package/dist/bundle/chunks/azure-openai-responses-7R44RRTC.js +0 -2
- package/dist/bundle/chunks/chunk-76TARFPL.js +0 -11
- package/dist/bundle/chunks/chunk-T7XWBYOA.js +0 -11
- package/dist/bundle/chunks/openai-codex-responses-DAZKF6IV.js +0 -10
- package/dist/bundle/chunks/openai-responses-L3QPK3MQ.js +0 -3
- package/dist/bundle/chunks/virtual-modules-IKIDAUHO.js +0 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,43 @@
|
|
|
1
1
|
# @knightcodeai/cli
|
|
2
2
|
|
|
3
|
+
## 0.18.4
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- Fixed Ctrl+Z on macOS and Linux suspending a clipboard helper along with KnightCode. The helper now leaves KnightCode's process group, so a suspend signal sent to the group does not stop it.
|
|
8
|
+
|
|
9
|
+
- Fixed codemode scripts failing as soon as both workers were busy. A script waits in arrival order for a free worker, the wait counts toward `timeout_ms` and abort, and the wait stops after 60 seconds. `KNIGHTCODE_CODEMODE_MAX_WORKERS` raises the process-wide limit of two.
|
|
10
|
+
|
|
11
|
+
- Fixed extensions failing to import `@knightcode/ai/models`. The extension loader and the embedded module map now include that subpath, so `clampThinkingLevel` and the other model helpers resolve.
|
|
12
|
+
|
|
13
|
+
- Fixed a second extension dialog replacing the one on screen and leaving the first dialog's promise pending. Select, confirm, input, editor, and inline custom dialogs now stack, and closing the visible dialog shows the previous one again.
|
|
14
|
+
|
|
15
|
+
- Fixed the terminal staying in mouse, focus, bracketed-paste, Kitty-keyboard, and alternate-screen modes when the process exits without stopping the UI. A process exit handler writes those resets when `stop()` did not run.
|
|
16
|
+
|
|
17
|
+
- Fixed Markdown tables disappearing after an unclosed display-math opener. An unclosed `$$` or `\[` no longer pairs across a table or stays pending over it, so the table renders.
|
|
18
|
+
|
|
19
|
+
## 0.18.3
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- Added inline images in Rex. Rex already had hyperlinks and true color, and it now sends images with the Kitty graphics protocol. Unicode placeholders stay unsupported.
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- Changed the extensions guide so a prompt's run and its turns are two diagrams, with the model-request and tool-execution hooks listed beside them.
|
|
28
|
+
|
|
29
|
+
### Removed
|
|
30
|
+
|
|
31
|
+
- Removed GPT-5.5 and GPT-5.3 Codex Spark from the Codex model list. A ChatGPT account cannot use them, so the model picker was offering models that always fail.
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
|
|
35
|
+
- Fixed bold and italic markdown next to CJK punctuation in the terminal and in exported HTML. The same punctuation next to Latin text still follows CommonMark flanking rules.
|
|
36
|
+
|
|
37
|
+
- Fixed managed self-update rejecting a managed-install.json file that Windows PowerShell 5.1 saved with a UTF-8 BOM.
|
|
38
|
+
|
|
39
|
+
- Fixed Responses requests that resent the tool list after a tool change and dropped the prompt cache. Models that accept additional tools now declare every tool in place, and a removal is announced in text so a later update can restate which tools are still unavailable.
|
|
40
|
+
|
|
3
41
|
## 0.18.2
|
|
4
42
|
|
|
5
43
|
### Added
|
package/dist/bundle/chunks/{anthropic-messages-QIZAJBTA.js → anthropic-messages-VD2GN7C4.js}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createRequire as __kcCreateRequire } from "node:module"; const require = __kcCreateRequire(import.meta.url);
|
|
2
|
-
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{buildCopilotDynamicHeaders,hasCopilotVisionInput}from"./chunk-HWXGL4YB.js";import{MIN_ANSWER_TOKENS,adjustMaxTokensForThinking,buildBaseOptions,clampMaxTokensToContext,clampThinkingBudgetToAnswerRoom,getJsonSchemaToolParameters,resolveJsonSchemaStrictSampling,splitErrorToolResultImages,transformMessages}from"./chunk-
|
|
2
|
+
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{buildCopilotDynamicHeaders,hasCopilotVisionInput}from"./chunk-HWXGL4YB.js";import{MIN_ANSWER_TOKENS,adjustMaxTokensForThinking,buildBaseOptions,clampMaxTokensToContext,clampThinkingBudgetToAnswerRoom,getJsonSchemaToolParameters,resolveJsonSchemaStrictSampling,splitErrorToolResultImages,transformMessages}from"./chunk-XILUO467.js";import{sanitizeSurrogates}from"./chunk-B2FT7RH5.js";import{getProviderEnvValue}from"./chunk-BRKUE2MD.js";import{parseJsonWithRepair,parseStreamingJson,parseToolCallArguments}from"./chunk-FA32X2UJ.js";import{getKnightcodeUserAgent}from"./chunk-HHWP56PR.js";import{retryProviderRequest}from"./chunk-57BPR4HF.js";import{headersToRecord}from"./chunk-DVFCXHT4.js";import{calculateCost,getCurrentTools,getInitialSystemMessage,getSystemMessageText,renderSystemMessageUpdate,resolveTranscript}from"./chunk-3VVG5HD5.js";import{AssistantMessageEventStream,appendAssistantMessageDiagnostic}from"./chunk-ETOMYYZC.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
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 mergeClientHeaders(...headerSources){return mergeHeaders({"User-Agent":getKnightcodeUserAgent()},...headerSources)}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
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
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]===`
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { createRequire as __kcCreateRequire } from "node:module"; const require = __kcCreateRequire(import.meta.url);
|
|
2
|
+
import{resolveAzureConfig,resolveDeploymentName}from"./chunk-AANBXVWQ.js";import{convertResponsesMessages,convertResponsesTools,getResponsesToolSupport,processResponsesStream}from"./chunk-SLWTIEJK.js";import{AzureOpenAI}from"./chunk-ZW7FVRHT.js";import{clampOpenAIPromptCacheKey}from"./chunk-N6VDWLND.js";import"./chunk-HUQB436V.js";import{buildBaseOptions,createGrammarToolInputProperties,resolveSamplingParams}from"./chunk-XILUO467.js";import"./chunk-B2FT7RH5.js";import"./chunk-BRKUE2MD.js";import"./chunk-FA32X2UJ.js";import{getKnightcodeUserAgent}from"./chunk-HHWP56PR.js";import{formatProviderError,normalizeProviderError}from"./chunk-4CRI7BMY.js";import{retryProviderRequest}from"./chunk-57BPR4HF.js";import{headersToRecord}from"./chunk-DVFCXHT4.js";import{clampThinkingLevel,getDeclaredTools,resolveTranscript,resolveTranscriptTools}from"./chunk-3VVG5HD5.js";import{AssistantMessageEventStream}from"./chunk-ETOMYYZC.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){for(let block of output.content)delete block.index,delete block.partialJson,delete block.customInput;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={"User-Agent":getKnightcodeUserAgent(),...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};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire as __kcCreateRequire } from "node:module"; const require = __kcCreateRequire(import.meta.url);
|
|
2
|
-
import{isRecord,parseClassifierUsage,postClassifierRequest,requiredNumber}from"./chunk-
|
|
2
|
+
import{isRecord,parseClassifierUsage,postClassifierRequest,requiredNumber}from"./chunk-CRLO4X52.js";import{formatProviderError,normalizeProviderError}from"./chunk-4CRI7BMY.js";function probabilities(label,value,id){if(!isRecord(value))throw new Error(`${label} returned invalid probabilities for ${id}`);return Object.fromEntries(Object.entries(value).map(([key,probability])=>[key,requiredNumber(label,probability,`probability for ${id}.${key}`)]))}function parseAnswers(label,value,context){if(!isRecord(value))throw new Error(`${label} returned an unexpected response`);let answers=[];for(let[id,question]of Object.entries(context.questions)){let answer=value[id];if(!isRecord(answer))throw new Error(`${label} did not return an answer for ${id}`);if(question.type==="choice"){if(answer.type!=="choice"||typeof answer.choice!="string")throw new Error(`${label} did not return a choice answer for ${id}`);answers.push([id,{type:"choice",choice:answer.choice,probabilities:probabilities(label,answer.probabilities,id),confidence:requiredNumber(label,answer.confidence,`confidence for ${id}`)}])}else if(question.type==="score"){if(answer.type!=="score")throw new Error(`${label} did not return a score answer for ${id}`);answers.push([id,{type:"score",score:requiredNumber(label,answer.score,`score for ${id}`),confidence:requiredNumber(label,answer.confidence,`confidence for ${id}`)}])}else{if(answer.type!=="noul")throw new Error(`${label} did not return a bool answer for ${id}`);answers.push([id,{type:"bool",probability:requiredNumber(label,answer.noul,`probability for ${id}`)}])}}return Object.fromEntries(answers)}function wireRequest(context){return{state:context.state,questions:Object.fromEntries(Object.entries(context.questions).map(([id,question])=>[id,question.type==="bool"?{...question,type:"noul"}:question]))}}async function classifySystemOne(transport,model,context,options){let output={api:model.api,provider:model.provider,model:model.id,answers:{},stopReason:"stop",timestamp:Date.now()};try{if(model.api!==transport.api)throw new Error(`Unsupported classifier API: ${model.api}`);if(context.images?.length)throw new Error(`${transport.label} does not support image input`);let body=await postClassifierRequest(transport.label,transport.url(model),model,transport.payload(model,wireRequest(context)),options),result=transport.output(body),usage=parseClassifierUsage(result.usage,model);return usage&&(output.usage=usage),output.answers=parseAnswers(transport.label,result.answers,context),output}catch(error){return output.stopReason=options?.signal?.aborted?"aborted":"error",output.errorMessage=formatProviderError(normalizeProviderError(error),`${transport.label} error`),output}}export{classifySystemOne};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createRequire as __kcCreateRequire } from "node:module"; const require = __kcCreateRequire(import.meta.url);
|
|
2
|
+
import{AssistantMessageEventStream,formatThrownValue}from"./chunk-ETOMYYZC.js";import{__export}from"./chunk-AHB7JV5B.js";function contentText(content,separator=`
|
|
3
|
+
`){return typeof content=="string"?content:content.filter(block=>block.type==="text").map(block=>block.text).join(separator)}function getSystemMessageText(message){let parts=[contentText(message.content)];for(let text of Object.values(message.sections??{}))text!==null&&parts.push(text);return parts.filter(part=>part.length>0).join(`
|
|
4
|
+
|
|
5
|
+
`)}function renderSystemMessageUpdate(message){let parts=[],text=contentText(message.content);text.length>0&&parts.push(text);for(let[name,value]of Object.entries(message.sections??{}))parts.push(value===null?`Removed system prompt section "${name}".`:`Updated system prompt section "${name}":
|
|
6
|
+
|
|
7
|
+
${value}`);return parts.join(`
|
|
8
|
+
|
|
9
|
+
`)}function createInitialSystemMessage(systemPrompt,tools){let hasSystemPrompt=systemPrompt!==void 0&&systemPrompt.length>0,hasTools=tools!==void 0&&tools.length>0;if(!(!hasSystemPrompt&&!hasTools))return{role:"system",content:systemPrompt??"",...hasTools?{toolsAdded:tools}:{},timestamp:0}}function normalizeContext(context){let initialMessage=createInitialSystemMessage(context.systemPrompt,context.tools);return{messages:initialMessage?[initialMessage,...context.messages]:context.messages}}function isSystemMessage(message){return message.role==="system"}function getInitialSystemMessage(messages){let first=messages[0];return first&&isSystemMessage(first)?first:void 0}function withoutInitialSystemMessage(messages){return getInitialSystemMessage(messages)?messages.slice(1):messages}function getCurrentTools(messages){let tools=new Map;for(let message of messages)if(isSystemMessage(message)){for(let tool of message.toolsRemoved??[])tools.delete(tool.name);for(let tool of message.toolsAdded??[])tools.set(tool.name,tool)}return[...tools.values()]}function getCurrentSystemMessage(messages){let content=[],sections=new Map,timestamp;for(let message of messages){if(!isSystemMessage(message))continue;timestamp??=message.timestamp;let text=contentText(message.content);text.length>0&&content.push(text);for(let[name,value]of Object.entries(message.sections??{}))value===null?sections.delete(name):sections.set(name,value)}let tools=getCurrentTools(messages);if(!(timestamp===void 0&&tools.length===0))return{role:"system",content:content.join(`
|
|
10
|
+
|
|
11
|
+
`),...sections.size>0?{sections:Object.fromEntries(sections)}:{},...tools.length>0?{toolsAdded:tools}:{},timestamp:timestamp??0}}function getCurrentSystemPrompt(messages){let message=getCurrentSystemMessage(messages);return message?getSystemMessageText(message):""}function collapseSystemMessages(context){let head=getCurrentSystemMessage(context.messages),messages=context.messages.filter(message=>message.role!=="system");return{messages:head?[head,...messages]:messages}}function resolveTranscript(context,supportsMidConvoSystemMessages){return supportsMidConvoSystemMessages?context:collapseSystemMessages(context)}function toToolDeclaration(tool){return{name:tool.name,description:tool.description,parameters:JSON.parse(JSON.stringify(tool.parameters)),...tool.constrainedSampling===void 0?{}:{constrainedSampling:tool.constrainedSampling}}}function declarationsEqual(left,right){return JSON.stringify(toToolDeclaration(left))===JSON.stringify(toToolDeclaration(right))}function getToolStateChanges(previous,current){let previousTools=new Map(previous.map(tool=>[tool.name,tool])),currentTools=new Map(current.map(tool=>[tool.name,tool]));return{toolsAdded:current.filter(tool=>{let previousTool=previousTools.get(tool.name);return previousTool===void 0||!declarationsEqual(previousTool,tool)}).map(toToolDeclaration),toolsRemoved:previous.filter(tool=>{let currentTool=currentTools.get(tool.name);return currentTool===void 0||!declarationsEqual(tool,currentTool)}).map(tool=>({name:tool.name}))}}function getDeclaredTools(messages){let definitions=new Map;for(let message of messages)if(isSystemMessage(message))for(let tool of message.toolsAdded??[])definitions.set(tool.name,tool);return[...definitions.values()]}function hasToolRedefinitions(messages){let declared=new Map;for(let message of messages)if(isSystemMessage(message))for(let tool of message.toolsAdded??[]){let previous=declared.get(tool.name);if(previous!==void 0&&!declarationsEqual(previous,tool))return!0;declared.set(tool.name,tool)}return!1}function hasNonAdditiveToolChanges(messages){return findLastNonAdditiveToolChange(messages.filter(isSystemMessage))>=0}function findLastNonAdditiveToolChange(systemMessages){let declared=new Set,last=-1;for(let index=0;index<systemMessages.length;index++){let message=systemMessages[index];(message.toolsRemoved?.length??0)>0&&(last=index);for(let tool of message.toolsAdded??[])declared.has(tool.name)&&(last=index),declared.add(tool.name)}return last}function resolveTranscriptTools(messages,support){let systemMessages=messages.filter(isSystemMessage);if(support==="none")return{requestTools:getCurrentTools(systemMessages),foldedSystemMessages:systemMessages.length};if(support==="changes")return{requestTools:[],foldedSystemMessages:0};let folded=Math.max(getInitialSystemMessage(messages)?1:0,findLastNonAdditiveToolChange(systemMessages)+1);return{requestTools:getCurrentTools(systemMessages.slice(0,folded)),foldedSystemMessages:folded}}var models_exports={};__export(models_exports,{AI_TELEMETRY_SCHEMA:()=>AI_TELEMETRY_SCHEMA,ModelsError:()=>ModelsError,calculateCost:()=>calculateCost,clampThinkingLevel:()=>clampThinkingLevel,createModels:()=>createModels,createProvider:()=>createProvider,getModelType:()=>getModelType,getSupportedThinkingLevels:()=>getSupportedThinkingLevels,hasApi:()=>hasApi,isModelType:()=>isModelType,modelsAreEqual:()=>modelsAreEqual});function createSetupErrorMessage(model2,error,timestamp){return{role:"assistant",content:[],api:model2.api,provider:model2.provider,model:model2.id,usage:{input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},stopReason:"error",errorMessage:error instanceof Error?error.message:String(error),timestamp}}function hasResult(source){return typeof source.result=="function"}async function forwardStream(target,source,observer,observeResult){let result;for await(let event of source)target.push(event),observer?.onEvent?.(event),event.type==="done"?result=event.message:event.type==="error"&&(result=event.error);hasResult(source)&&(result=await source.result()),target.end(result),observeResult(result)}function lazyStream(model2,setup,observer){let startedAt=Date.now(),outer=new AssistantMessageEventStream,observedResult=!1,observeResult=result=>{observedResult||(observedResult=!0,observer?.onResult?.(result))};return Promise.resolve().then(setup).then(inner=>forwardStream(outer,inner,observer,observeResult)).catch(error=>{let message=createSetupErrorMessage(model2,error,startedAt),event={type:"error",reason:"error",error:message};outer.push(event),observer?.onEvent?.(event),outer.end(message),observeResult(message)}),outer}function lazyApi(load,capabilities){let api={stream:(model2,context,options)=>lazyStream(model2,async()=>(await load()).stream(model2,context,options)),streamSimple:(model2,context,options)=>lazyStream(model2,async()=>(await load()).streamSimple(model2,context,options))};return capabilities?.fetchDeferred&&(api.fetchDeferred=(model2,handle,options)=>lazyStream(model2,async()=>{let implementation=await load();if(!implementation.fetchDeferred)throw new Error("API does not support deferred responses");return implementation.fetchDeferred(model2,handle,options)})),capabilities?.cancelDeferred&&(api.cancelDeferred=async(model2,handle,options)=>{let implementation=await load();if(!implementation.cancelDeferred)throw new Error("API cannot cancel deferred responses");await implementation.cancelDeferred(model2,handle,options)}),api}var importNodeModule=specifier=>import(specifier);function getProcessEnv(){return globalThis.process?.env}function defaultProviderAuthContext(){return{async env(name){let value=getProcessEnv()?.[name];return typeof value=="string"&&value.trim().length>0?value:void 0},async fileExists(path){try{let fs=await importNodeModule("node:fs/promises"),resolved=path;return resolved.startsWith("~")&&(resolved=(await importNodeModule("node:os")).homedir()+resolved.slice(1)),await fs.access(resolved),!0}catch{return!1}}}}function abortReason(signal){if(signal.reason!==void 0)return signal.reason;let error=new Error("The operation was aborted");return error.name="AbortError",error}function operationSignal(signal){return signal??new AbortController().signal}function raceWithAbortSignal(operation,signal){return signal.aborted?(operation.catch(()=>{}),Promise.reject(abortReason(signal))):new Promise((resolve,reject)=>{let settled=!1,cleanup=()=>signal.removeEventListener("abort",onAbort),onAbort=()=>{settled||(settled=!0,cleanup(),reject(abortReason(signal)))};signal.addEventListener("abort",onAbort,{once:!0}),operation.then(value=>{settled||(settled=!0,cleanup(),resolve(value))},error=>{settled||(settled=!0,cleanup(),reject(error))}),signal.aborted&&onAbort()})}var InMemoryCredentialStore=class{credentials=new Map;chains=new Map;enqueue(providerId,task,options){let signal=operationSignal(options?.signal),previous=this.chains.get(providerId)??Promise.resolve(),queued=(async()=>(await previous.catch(()=>{}),signal.throwIfAborted(),task()))(),tail=queued.catch(()=>{});return this.chains.set(providerId,tail),tail.then(()=>{this.chains.get(providerId)===tail&&this.chains.delete(providerId)}),raceWithAbortSignal(queued,signal)}async read(providerId,options){return options?.signal?.throwIfAborted(),this.credentials.get(providerId)}async list(options){return options?.signal?.throwIfAborted(),[...this.credentials].map(([providerId,credential])=>({providerId,type:credential.type}))}modify(providerId,fn,options){return this.enqueue(providerId,async()=>{let current=this.credentials.get(providerId),next=await fn(current);return options?.signal?.throwIfAborted(),next!==void 0&&this.credentials.set(providerId,next),next??current},options)}delete(providerId,options){return this.enqueue(providerId,async()=>{this.credentials.delete(providerId)},options)}};var ModelsError=class extends Error{code;constructor(code,message,options){super(withCauseDetail(message,options?.cause),options),this.name="ModelsError",this.code=code}};function withCauseDetail(message,cause){if(cause==null)return message;let detail=formatThrownValue(cause).trim();return!detail||message.includes(detail)?message:`${message}: ${detail}`}function resolveProviderAuth(provider2,credentials,authContext,overrides){let signal=operationSignal(overrides?.signal);return raceWithAbortSignal(resolveProviderAuthWithSignal(provider2,credentials,authContext,overrides,signal),signal)}async function resolveProviderAuthWithSignal(provider2,credentials,authContext,overrides,signal){signal.throwIfAborted();let requestAuthContext=overrides?.env?overlayEnvAuthContext(authContext,overrides.env):authContext;if(overrides?.apiKey!==void 0&&provider2.auth.apiKey)return resolveApiKey(requestAuthContext,provider2.auth.apiKey,provider2.id,{type:"api_key",key:overrides.apiKey,env:overrides.env},signal);let stored=await readCredential(credentials,provider2.id,signal);if(stored){if(stored.type==="oauth"&&provider2.auth.oauth)return resolveStoredOAuth(credentials,provider2.id,provider2.auth.oauth,stored,signal,overrides?.minOAuthValidityMs);if(stored.type==="api_key"&&provider2.auth.apiKey){let credential=overrides?.env?{...stored,env:{...stored.env,...overrides.env}}:stored;return resolveApiKey(requestAuthContext,provider2.auth.apiKey,provider2.id,credential,signal)}return}return provider2.auth.apiKey?resolveApiKey(requestAuthContext,provider2.auth.apiKey,provider2.id,void 0,signal):void 0}function overlayEnvAuthContext(base,env){return{env:async name=>env[name]||await base.env(name),fileExists:path=>base.fileExists(path)}}var DEFAULT_OAUTH_MINIMUM_VALIDITY_MS=300*1e3,DEFAULT_OAUTH_REFRESH_TIMEOUT_MS=15e3;async function refreshStoredOAuthCredential(credentials,providerId,oauth,needsRefresh,signal){let post,lockWait=new AbortController,cancelLockWait=()=>lockWait.abort(signal.reason);signal.addEventListener("abort",cancelLockWait,{once:!0}),signal.aborted&&cancelLockWait();try{post=await credentials.modify(providerId,async current=>{if(signal.removeEventListener("abort",cancelLockWait),signal.throwIfAborted(),current?.type==="oauth"&&needsRefresh(current))try{return await oauth.refresh(current,AbortSignal.timeout(DEFAULT_OAUTH_REFRESH_TIMEOUT_MS))}catch(error){throw new ModelsError("oauth",`OAuth refresh failed for ${providerId}`,{cause:error})}},{signal:lockWait.signal})}catch(error){throw error instanceof ModelsError?error:(signal.throwIfAborted(),new ModelsError("auth",`Credential store modify failed for ${providerId}`,{cause:error}))}finally{signal.removeEventListener("abort",cancelLockWait)}return post?.type==="oauth"?post:void 0}async function resolveStoredOAuth(credentials,providerId,oauth,stored,signal,minOAuthValidityMs){let minimumValidityMs=Math.max(DEFAULT_OAUTH_MINIMUM_VALIDITY_MS,minOAuthValidityMs??0),expiresSoon=credential2=>Date.now()+minimumValidityMs>=credential2.expires,credential=stored;if(expiresSoon(credential)){let post=await refreshStoredOAuthCredential(credentials,providerId,oauth,expiresSoon,signal);if(!post)return;if(credential=post,minOAuthValidityMs!==void 0&&expiresSoon(credential))throw new ModelsError("oauth",`OAuth refresh returned a token that expires too soon for ${providerId}`)}try{return{auth:await oauth.toAuth(credential),source:"OAuth"}}catch(error){throw new ModelsError("oauth",`OAuth auth derivation failed for ${providerId}`,{cause:error})}}async function resolveApiKey(authContext,apiKey,providerId,credential,signal){try{return await apiKey.resolve({ctx:authContext,credential,signal})}catch(error){throw new ModelsError("auth",`API key auth failed for provider ${providerId}`,{cause:error})}}async function readCredential(credentials,providerId,signal){try{return await credentials.read(providerId,{signal})}catch(error){throw new ModelsError("auth",`Credential store read failed for ${providerId}`,{cause:error})}}var InMemoryModelsStore=class{entries=new Map;async read(providerId,options){options?.signal?.throwIfAborted();let entry=this.entries.get(providerId);return entry?structuredClone(entry):void 0}async write(providerId,entry,options){options?.signal?.throwIfAborted(),this.entries.set(providerId,structuredClone(entry))}async delete(providerId,options){options?.signal?.throwIfAborted(),this.entries.delete(providerId)}};function createTypedMetrics(metrics,schemas){let definitions=new Map;for(let schema of schemas)for(let[name,definition]of Object.entries(schema.metrics??{}))definitions.set(name,definition);return{counter:name=>metrics.counter(name,definitions.get(name)),upDownCounter:name=>metrics.upDownCounter(name,definitions.get(name)),histogram:name=>metrics.histogram(name,definitions.get(name))}}async function startNoopSpan(_options,callback){return callback(noopTelemetrySpan)}var noopCounter=Object.freeze({add:()=>{}}),noopUpDownCounter=Object.freeze({add:()=>{}}),noopHistogram=Object.freeze({record:()=>{}}),NOOP_TELEMETRY_METRICS=Object.freeze({counter:()=>noopCounter,upDownCounter:()=>noopUpDownCounter,histogram:()=>noopHistogram}),NOOP_TELEMETRY_PROPAGATION=Object.freeze({inject:()=>{},extract:()=>NOOP_TELEMETRY_CONTEXT}),noopTelemetrySpan={metrics:NOOP_TELEMETRY_METRICS,propagation:NOOP_TELEMETRY_PROPAGATION,startSpan:startNoopSpan,addLink:()=>{},addEvent:()=>{},setAttributes:()=>{},setStatus:()=>{}};Object.freeze(noopTelemetrySpan);var NOOP_TELEMETRY_CONTEXT=noopTelemetrySpan;function bindTypedSpanStarter(telemetryContext){return(name,attributes,callback)=>telemetryContext.startSpan({name,attributes},span=>callback(span,bindTypedSpanStarter(span)))}function createTypedSpanStarter(telemetryContext,_schemas){return bindTypedSpanStarter(telemetryContext)}var provider={type:"string",description:"Provider identifier.",required:!0},model={type:"string",description:"Requested model identifier.",required:!0},stop={type:"string",description:"Normalized stop reason.",values:["pending","stop","length","toolUse","error","aborted","deferred"]},request={description:"One logical model request, including authentication and provider setup.",parents:{kind:"any"},startAttributes:{provider,api:{type:"string",description:"API identifier.",required:!0},model,reasoning:{type:"string",description:"Scalar requested reasoning level.",required:!1}},endAttributes:{stop,"usage.input":{type:"number",description:"Uncached input tokens."},"usage.output":{type:"number",description:"Output tokens."},"usage.cache_read":{type:"number",description:"Cache-read tokens."},"usage.cache_write":{type:"number",description:"Cache-write tokens."},"cost.total":{type:"number",description:"Total request cost in USD."},"response.id":{type:"string",description:"Provider response identifier.",cardinality:"high"}},events:{"knightcode.ai.first_chunk":{description:"First normalized stream event delivered.",attributes:{}},"knightcode.ai.block":{description:"A completed content block; content is never recorded.",attributes:{type:{type:"string",description:"Block kind.",values:["text","thinking","tool_call"],required:!0},index:{type:"number",description:"Content block index.",required:!0},chars:{type:"number",description:"UTF-16 character count.",required:!0},tool:{type:"string",description:"Tool name, for tool-call blocks only.",required:!1}}}},status:{default:"ok",errorWhen:"Stop reason is error: provider_error with at most 500 error-message characters. Aborted stays ok."}},AI_TELEMETRY_SCHEMA={version:1,spans:{"knightcode.ai.request":request,"knightcode.ai.poll":{...request,description:"One deferred-response poll, not the deferred request's lifetime."}},metrics:{"knightcode.ai.request.duration":{kind:"histogram",description:"Logical request or poll duration.",unit:"ms",attributes:{provider,model,stop:{...stop,required:!0}}},"knightcode.ai.first_chunk.duration":{kind:"histogram",description:"Time to the first normalized stream event.",unit:"ms",attributes:{provider,model}},"knightcode.ai.tokens":{kind:"counter",description:"Reported model token usage; pending and deferred polls are excluded.",unit:"token",attributes:{provider,model,kind:{type:"string",description:"Token usage category.",values:["input","output","cache_read","cache_write"],required:!0}}},"knightcode.ai.cost":{kind:"counter",description:"Reported model cost; pending and deferred polls are excluded.",unit:"USD",attributes:{provider,model}}}};function createInstruments(adapter){let metrics=createTypedMetrics(adapter,[AI_TELEMETRY_SCHEMA]);return{requestDuration:metrics.histogram("knightcode.ai.request.duration"),firstChunkDuration:metrics.histogram("knightcode.ai.first_chunk.duration"),tokens:metrics.counter("knightcode.ai.tokens"),cost:metrics.counter("knightcode.ai.cost")}}var instrumentCache=new WeakMap;function observeModelRequest(requestedModel,options,poll){let started=performance.now(),attributes={provider:requestedModel.provider,model:requestedModel.id},adapter=options?.telemetry?.metrics??NOOP_TELEMETRY_METRICS,instruments=instrumentCache.get(adapter);instruments||(instruments=createInstruments(adapter),instrumentCache.set(adapter,instruments));let{requestDuration,firstChunkDuration,tokens,cost}=instruments,span,finish,first=!0,toolChars=new Map,finished=new Promise(resolve=>{finish=resolve}),run=activeSpan=>(span=activeSpan,finished),startAttributes={...attributes,api:requestedModel.api,...typeof options?.reasoning=="string"?{reasoning:options.reasoning}:{}},start=createTypedSpanStarter(options?.telemetry??NOOP_TELEMETRY_CONTEXT,[AI_TELEMETRY_SCHEMA]);return start(poll?"knightcode.ai.poll":"knightcode.ai.request",startAttributes,run),{onEvent(event){if(first&&(first=!1,span.addEvent("knightcode.ai.first_chunk"),firstChunkDuration.record(performance.now()-started,attributes,span)),event.type==="toolcall_delta")toolChars.set(event.contentIndex,(toolChars.get(event.contentIndex)??0)+event.delta.length);else if(event.type==="text_end"||event.type==="thinking_end")span.addEvent("knightcode.ai.block",{type:event.type==="text_end"?"text":"thinking",index:event.contentIndex,chars:event.content.length});else if(event.type==="toolcall_end"){let chars=toolChars.get(event.contentIndex)??0;toolChars.delete(event.contentIndex),span.addEvent("knightcode.ai.block",{type:"tool_call",index:event.contentIndex,chars,tool:event.toolCall.name})}},onResult(message){message&&(span.setAttributes({stop:message.stopReason,"usage.input":message.usage.input,"usage.output":message.usage.output,"usage.cache_read":message.usage.cacheRead,"usage.cache_write":message.usage.cacheWrite,"cost.total":message.usage.cost.total,"response.id":message.responseId}),message.stopReason==="error"&&span.setStatus({status:"error",error:{name:"provider_error",message:message.errorMessage?.slice(0,500)??""}}),requestDuration.record(performance.now()-started,{...attributes,stop:message.stopReason},span),(!poll||message.stopReason!=="pending"&&message.stopReason!=="deferred")&&(tokens.add(message.usage.input,{...attributes,kind:"input"}),tokens.add(message.usage.output,{...attributes,kind:"output"}),tokens.add(message.usage.cacheRead,{...attributes,kind:"cache_read"}),tokens.add(message.usage.cacheWrite,{...attributes,kind:"cache_write"}),cost.add(message.usage.cost.total,attributes))),finish()}}}function getModelType(model2){return model2.type??"chat"}function isModelType(model2,type){return getModelType(model2)===type}function assertChatModel(model2){if(!isModelType(model2,"chat"))throw new ModelsError("provider",`Model ${model2.provider}/${model2.id} is not a chat model`)}function assertImageModel(model2){if(!isModelType(model2,"image"))throw new ModelsError("provider",`Model ${model2.provider}/${model2.id} is not an image model`)}function assertClassifierModel(model2){if(!isModelType(model2,"classifier"))throw new ModelsError("provider",`Model ${model2.provider}/${model2.id} is not a classifier model`)}function assertClassifierInputSupported(model2,context){if(context.images?.length&&!model2.input.includes("image"))throw new ModelsError("provider",`Model ${model2.provider}/${model2.id} does not accept image input`)}function imageErrorResult(model2,error,aborted=!1){return{api:model2.api,provider:model2.provider,model:model2.id,output:[],stopReason:aborted?"aborted":"error",errorMessage:error instanceof Error?error.message:String(error),timestamp:Date.now()}}function classifierErrorResult(model2,error,aborted=!1){return{api:model2.api,provider:model2.provider,model:model2.id,answers:{},stopReason:aborted?"aborted":"error",errorMessage:error instanceof Error?error.message:String(error),timestamp:Date.now()}}var KNOWN_MODEL_TYPES={chat:!0,image:!0,classifier:!0};function hasKnownModelType(model2){return Object.hasOwn(KNOWN_MODEL_TYPES,getModelType(model2))}function withKnownModelTypes(entry){return{...entry,models:entry.models.filter(hasKnownModelType)}}function mergeHeaders(base,override){if(!base&&!override)return;let merged={...base};for(let[name,value]of Object.entries(override??{})){let lowerName=name.toLowerCase();for(let existingName of Object.keys(merged))existingName.toLowerCase()===lowerName&&delete merged[existingName];merged[name]=value}return merged}var ModelsImpl=class{providers=new Map;credentials;modelsStore;authContext;refreshGenerations=new Map;refreshControllers=new Map;publicationChains=new Map;constructor(options){this.credentials=options?.credentials??new InMemoryCredentialStore,this.modelsStore=options?.modelsStore??new InMemoryModelsStore,this.authContext=options?.authContext??defaultProviderAuthContext()}setProvider(provider2){this.supersedeProviderRefresh(provider2.id),this.providers.set(provider2.id,provider2)}deleteProvider(id){this.supersedeProviderRefresh(id),this.providers.delete(id)}clearProviders(){for(let id of new Set([...this.providers.keys(),...this.refreshControllers.keys()]))this.supersedeProviderRefresh(id);this.providers.clear()}getProviders(){return Array.from(this.providers.values())}getProvider(id){return this.providers.get(id)}getModels(provider2){if(provider2!==void 0){let entry=this.providers.get(provider2);if(!entry)return[];try{return entry.getModels()}catch{return[]}}let models=[];for(let entry of this.providers.values())try{models.push(...entry.getModels())}catch{}return models}getAllModels(provider2){if(provider2!==void 0){let entry=this.providers.get(provider2);if(!entry)return[];try{return entry.getAllModels?.()??entry.getModels()}catch{return[]}}let models=[];for(let entry of this.providers.values())try{models.push(...entry.getAllModels?.()??entry.getModels())}catch{}return models}getModelsOfType(type,provider2){return this.getAllModels(provider2).filter(model2=>isModelType(model2,type))}getModel(provider2,id){return this.getModels(provider2).find(model2=>model2.id===id)}getModelOfType(type,provider2,id){return this.getModelsOfType(type,provider2).find(model2=>model2.id===id)}supersedeProviderRefresh(providerId){let generation=(this.refreshGenerations.get(providerId)??0)+1;this.refreshGenerations.set(providerId,generation);let previous=this.refreshControllers.get(providerId);return previous&&(this.refreshControllers.delete(providerId),previous.abort()),generation}beginProviderRefresh(providerId){let generation=this.supersedeProviderRefresh(providerId),controller=new AbortController;return this.refreshControllers.set(providerId,controller),{generation,controller}}publishProviderModels(providerId,generation,signal,publication){let previous=this.publicationChains.get(providerId)??Promise.resolve(),queued=(async()=>(await previous.catch(()=>{}),signal.aborted||this.refreshGenerations.get(providerId)!==generation||(publication.persist===null?await this.modelsStore.delete(providerId,{signal}):publication.persist!==void 0&&await this.modelsStore.write(providerId,structuredClone(publication.persist),{signal}),signal.aborted||this.refreshGenerations.get(providerId)!==generation)?!1:(publication.update?.(),!0)))(),tail=queued.catch(()=>{});return this.publicationChains.set(providerId,tail),tail.then(()=>{this.publicationChains.get(providerId)===tail&&this.publicationChains.delete(providerId)}),raceWithAbortSignal(queued,signal)}async runProviderRefreshPhase(provider2,credential,allowNetwork,force,generation,signal){let stored=await this.modelsStore.read(provider2.id,{signal});await provider2.refreshModels({credential,stored:stored?withKnownModelTypes(structuredClone(stored)):void 0,publish:publication=>this.publishProviderModels(provider2.id,generation,signal,publication),allowNetwork,force:allowNetwork?force:void 0,signal,baseUrl:provider2.baseUrl})}async refresh(options={}){let allowNetwork=options.allowNetwork??!0,callerSignal=operationSignal(options.signal),errors=new Map;if(callerSignal.aborted)return{aborted:!0,errors};let selected=options.providers?new Set(options.providers):void 0,refreshable=Array.from(this.providers.values()).filter(provider2=>provider2.refreshModels!==void 0&&(!selected||selected.has(provider2.id))),refresh=Promise.all(refreshable.map(async provider2=>{let{generation,controller}=this.beginProviderRefresh(provider2.id),signal=AbortSignal.any([callerSignal,controller.signal]),operation=(async()=>{let storedCredential,credentialError;try{storedCredential=await this.readCredential(provider2.id,signal)}catch(error){credentialError=error}if(await this.runProviderRefreshPhase(provider2,storedCredential,!1,void 0,generation,signal),credentialError!==void 0)throw credentialError;if(!allowNetwork||signal.aborted)return;let credential=await this.resolveRefreshCredential(provider2,storedCredential,signal);credential&&await this.runProviderRefreshPhase(provider2,credential,!0,options.force,generation,signal)})();try{await raceWithAbortSignal(operation,signal)}catch(error){signal.aborted||errors.set(provider2.id,error instanceof Error?error:new ModelsError("model_source",`Model refresh failed for ${provider2.id}`,{cause:error}))}finally{this.refreshControllers.get(provider2.id)===controller&&this.refreshControllers.delete(provider2.id)}}));try{await raceWithAbortSignal(refresh,callerSignal)}catch(error){if(!callerSignal.aborted)throw error}return{aborted:callerSignal.aborted,errors:new Map(errors)}}async resolveRefreshCredential(provider2,stored,signal){if(stored?.type==="oauth"){let oauth=provider2.auth.oauth;return oauth?Date.now()<stored.expires?stored:signal.aborted?void 0:refreshStoredOAuthCredential(this.credentials,provider2.id,oauth,current=>Date.now()>=current.expires,signal):void 0}let apiKey=provider2.auth.apiKey;if(!apiKey)return;let credential=stored?.type==="api_key"?stored:void 0,result=await apiKey.resolve({ctx:this.authContext,credential,signal});if(result)return{type:"api_key",key:result.auth.apiKey,env:result.env}}async readCredential(providerId,signal){try{return await this.credentials.read(providerId,{signal})}catch(error){throw new ModelsError("auth",`Credential store read failed for ${providerId}`,{cause:error})}}async checkProviderAuth(provider2,credential,signal){if(credential?.type==="oauth")return provider2.auth.oauth?{source:"OAuth",type:"oauth"}:void 0;let apiKey=provider2.auth.apiKey;if(!apiKey)return;if(apiKey.check)try{return await apiKey.check({ctx:this.authContext,credential:credential?.type==="api_key"?credential:void 0,signal})}catch(error){throw new ModelsError("auth",`API key auth check failed for provider ${provider2.id}`,{cause:error})}let resolution=await resolveProviderAuth(provider2,this.credentials,this.authContext,{signal});return resolution?{source:resolution.source,type:"api_key"}:void 0}checkAuth(providerId,options){let signal=operationSignal(options?.signal),check=(async()=>{signal.throwIfAborted();let provider2=this.providers.get(providerId);if(provider2)return this.checkProviderAuth(provider2,await this.readCredential(providerId,signal),signal)})();return raceWithAbortSignal(check,signal)}async getAuthenticatedProviders(providerId,signal){signal.throwIfAborted();let providers=providerId?[this.providers.get(providerId)].filter(entry=>entry!==void 0):this.getProviders();return(await Promise.all(providers.map(async provider2=>{let credential=await this.readCredential(provider2.id,signal);return{provider:provider2,credential,auth:await this.checkProviderAuth(provider2,credential,signal)}}))).filter(entry=>entry.auth!==void 0)}getAvailable(providerId,options){let signal=operationSignal(options?.signal),available=(async()=>(await this.getAuthenticatedProviders(providerId,signal)).flatMap(({provider:provider2,credential})=>{let models=provider2.getModels();return provider2.filterModels?.(models,credential)??models}))();return raceWithAbortSignal(available,signal)}async getAvailableOfType(type,providerId,options){return(await this.getAllAvailable(providerId,options)).filter(model2=>isModelType(model2,type))}getAllAvailable(providerId,options){let signal=operationSignal(options?.signal),available=(async()=>(await this.getAuthenticatedProviders(providerId,signal)).flatMap(({provider:provider2,credential})=>{let models=provider2.getAllModels?.()??provider2.getModels();if(provider2.filterAllModels)return provider2.filterAllModels(models,credential);if(!provider2.filterModels)return models;let availableChatIds=new Set(provider2.filterModels(provider2.getModels(),credential).map(model2=>model2.id));return models.filter(model2=>!isModelType(model2,"chat")||availableChatIds.has(model2.id))}))();return raceWithAbortSignal(available,signal)}async getAuth(providerOrModel,overrides){let signal=operationSignal(overrides?.signal),providerId=typeof providerOrModel=="string"?providerOrModel:providerOrModel.provider,provider2=this.providers.get(providerId);if(!provider2)return;let result=await resolveProviderAuth(provider2,this.credentials,this.authContext,{...overrides,signal});return!result||typeof providerOrModel=="string"||!providerOrModel.headers?result:{...result,auth:{...result.auth,headers:mergeHeaders(result.auth.headers,providerOrModel.headers)}}}async login(providerId,type,interaction,options){let signal=operationSignal(interaction.signal);signal.throwIfAborted();let provider2=this.providers.get(providerId);if(!provider2)throw new ModelsError("provider",`Unknown provider: ${providerId}`);let method=type==="oauth"?provider2.auth.oauth:provider2.auth.apiKey;if(!method?.login)throw new ModelsError("auth",`${provider2.name} does not support ${type} login`);let loginOperation=method.login({...interaction,signal},options),credential=await raceWithAbortSignal(loginOperation,signal),mutationStarted=!1,markMutationStarted,started=new Promise(resolve=>{markMutationStarted=resolve}),mutation=this.credentials.modify(providerId,async()=>(mutationStarted=!0,markMutationStarted?.(),credential),{signal});mutation.catch(()=>{});try{await new Promise((resolve,reject)=>{let onAbort=()=>{mutationStarted||reject(signal.reason)};signal.addEventListener("abort",onAbort,{once:!0}),Promise.race([started,mutation]).then(()=>{signal.removeEventListener("abort",onAbort),resolve()},error=>{signal.removeEventListener("abort",onAbort),reject(error)}),signal.aborted&&onAbort()}),await mutation}catch(error){throw signal.throwIfAborted(),new ModelsError("auth",`Credential store modify failed for ${providerId}`,{cause:error})}return credential}async logout(providerId,options){let signal=operationSignal(options?.signal);signal.throwIfAborted();try{await this.credentials.delete(providerId,{signal})}catch(error){throw signal.throwIfAborted(),new ModelsError("auth",`Credential store delete failed for ${providerId}`,{cause:error})}}requireProvider(model2){let provider2=this.providers.get(model2.provider);if(!provider2)throw new ModelsError("provider",`Unknown provider: ${model2.provider}`);return provider2}requireChatProvider(model2){return assertChatModel(model2),this.requireProvider(model2)}async applyAuth(model2,options){this.requireProvider(model2);let resolution=await this.getAuth(model2,{apiKey:options?.apiKey,env:options?.env,signal:options?.signal});if(!resolution)throw new ModelsError("auth",`Provider is not configured: ${model2.provider}`);let auth=resolution.auth,apiKey=options?.apiKey??auth.apiKey,headers=mergeHeaders(auth.headers,options?.headers);options?.transformHeaders&&(headers=await options.transformHeaders(headers??{}));let env=resolution.env||options?.env?{...resolution.env??{},...options?.env??{}}:void 0,requestModel=auth.baseUrl?{...model2,baseUrl:auth.baseUrl}:model2,{transformHeaders:_transformHeaders,...providerOptions}=options??{},requestOptions={...providerOptions,apiKey,headers,env};return{requestModel,requestOptions}}stream(model2,context,options){let transcript=normalizeContext(context);return lazyStream(model2,async()=>{let provider2=this.requireChatProvider(model2),{requestModel,requestOptions}=await this.applyAuth(model2,options);return provider2.stream(requestModel,transcript,requestOptions)},observeModelRequest(model2,options,!1))}async complete(model2,context,options){return this.stream(model2,context,options).result()}streamSimple(model2,context,options){let transcript=normalizeContext(context);return lazyStream(model2,async()=>{let provider2=this.requireChatProvider(model2),{requestModel,requestOptions}=await this.applyAuth(model2,options);return provider2.streamSimple(requestModel,transcript,requestOptions)},observeModelRequest(model2,options,!1))}async completeSimple(model2,context,options){return this.streamSimple(model2,context,options).result()}streamDeferred(model2,handle,options){return lazyStream(model2,async()=>{let provider2=this.requireChatProvider(model2);if(!provider2.fetchDeferred)throw new ModelsError("provider",`Provider ${model2.provider} does not support deferred responses`);let{requestModel,requestOptions}=await this.applyAuth(model2,options);return provider2.fetchDeferred(requestModel,handle,requestOptions)},observeModelRequest(model2,options,!0))}async fetchDeferred(model2,handle,options){return this.streamDeferred(model2,handle,options).result()}async cancelDeferred(model2,handle,options){let provider2=this.requireChatProvider(model2);if(!provider2.cancelDeferred)throw new ModelsError("provider",`Provider ${model2.provider} does not support deferred responses`);let{requestModel,requestOptions}=await this.applyAuth(model2,options);await provider2.cancelDeferred(requestModel,handle,requestOptions)}async generateImages(model2,context,options){try{assertImageModel(model2);let provider2=this.requireProvider(model2);if(!provider2.generateImages)throw new ModelsError("provider",`Provider ${model2.provider} does not support image generation`);let{requestModel,requestOptions}=await this.applyAuth(model2,options);return await provider2.generateImages(requestModel,context,requestOptions)}catch(error){return imageErrorResult(model2,error,options?.signal?.aborted)}}async classify(model2,context,options){try{assertClassifierModel(model2),assertClassifierInputSupported(model2,context);let provider2=this.requireProvider(model2);if(!provider2.classify)throw new ModelsError("provider",`Provider ${model2.provider} does not support classification`);let{requestModel,requestOptions}=await this.applyAuth(model2,options);return await provider2.classify(requestModel,context,requestOptions)}catch(error){return classifierErrorResult(model2,error,options?.signal?.aborted)}}};function createModels(options){return new ModelsImpl(options)}function createProvider(input){let single=input.api&&typeof input.api.stream=="function"?input.api:void 0,byApi=single||!input.api?void 0:input.api,images=input.images,classifiers=input.classifiers,streams=single?[single]:Object.values(byApi??{}).filter(entry=>entry!==void 0),imageImplementations=Object.values(images??{}).filter(entry=>entry!==void 0),classifierImplementations=Object.values(classifiers??{}).filter(entry=>entry!==void 0);if(streams.length===0&&imageImplementations.length===0&&classifierImplementations.length===0)throw new Error(`Provider ${input.id}: at least one of "api", "images", or "classifiers" is required.`);let baselineModels=input.models,dynamicModels=[],fetchModels=input.fetchModels,currentModels=()=>{let merged=[...baselineModels];for(let model2 of dynamicModels){let index=merged.findIndex(entry=>getModelType(entry)===getModelType(model2)&&entry.id===model2.id);index>=0?merged[index]=model2:merged.push(model2)}return merged},apiFor=model2=>single??byApi?.[model2.api],dispatch=(model2,run)=>{let streams2=apiFor(model2);return streams2?run(streams2):lazyStream(model2,async()=>{throw new ModelsError("stream",`Provider ${input.id} has no API implementation for "${model2.api}"`)})},provider2={id:input.id,name:input.name??input.id,baseUrl:input.baseUrl,headers:input.headers,auth:input.auth,getModels:()=>currentModels().filter(model2=>isModelType(model2,"chat")),getAllModels:currentModels,refreshModels:fetchModels?async context=>{if(context.stored){let restored=context.stored.models.filter(model2=>model2.provider===input.id).map(model2=>model2);if(!await context.publish({update:()=>{dynamicModels=restored}}))return}if(!context.allowNetwork||context.signal.aborted)return;let fetched=await fetchModels(context);if(context.signal.aborted)return;let refreshed=fetched.filter(hasKnownModelType);await context.publish({persist:{models:refreshed,checkedAt:Date.now()},update:()=>{dynamicModels=refreshed}})}:void 0,filterModels:input.filterModels,filterAllModels:input.filterAllModels,stream:(model2,context,options)=>dispatch(model2,streams2=>streams2.stream(model2,context,options)),streamSimple:(model2,context,options)=>dispatch(model2,streams2=>streams2.streamSimple(model2,context,options))};return streams.some(entry=>entry.fetchDeferred!==void 0)&&(provider2.fetchDeferred=(model2,handle,options)=>lazyStream(model2,async()=>{let implementation=apiFor(model2);if(!implementation?.fetchDeferred)throw new ModelsError("provider",`Provider ${input.id} does not support deferred responses for "${model2.api}"`);return implementation.fetchDeferred(model2,handle,options)})),streams.some(entry=>entry.cancelDeferred!==void 0)&&(provider2.cancelDeferred=async(model2,handle,options)=>{let implementation=apiFor(model2);if(!implementation?.cancelDeferred)throw new ModelsError("provider",`Provider ${input.id} cannot cancel deferred responses for "${model2.api}"`);await implementation.cancelDeferred(model2,handle,options)}),images&&imageImplementations.length>0&&(provider2.generateImages=async(model2,context,options)=>{let implementation=images[model2.api];return implementation?implementation.generateImages(model2,context,options):imageErrorResult(model2,new ModelsError("provider",`Provider ${input.id} has no image generation implementation for "${model2.api}"`))}),classifiers&&classifierImplementations.length>0&&(provider2.classify=async(model2,context,options)=>{let implementation=classifiers[model2.api];return implementation?implementation.classify(model2,context,options):classifierErrorResult(model2,new ModelsError("provider",`Provider ${input.id} has no classifier implementation for "${model2.api}"`))}),provider2}function hasApi(model2,api){return isModelType(model2,"chat")&&model2.api===api}function calculateCost(model2,usage){let inputTokens=usage.input+usage.cacheRead+usage.cacheWrite,rates=model2.cost,matchedThreshold=-1;for(let tier of model2.cost.tiers??[])inputTokens>tier.inputTokensAbove&&tier.inputTokensAbove>matchedThreshold&&(rates=tier,matchedThreshold=tier.inputTokensAbove);let longWrite=usage.cacheWrite1h??0,shortWrite=usage.cacheWrite-longWrite;return usage.cost.input=rates.input/1e6*usage.input,usage.cost.output=rates.output/1e6*usage.output,usage.cost.cacheRead=rates.cacheRead/1e6*usage.cacheRead,usage.cost.cacheWrite=(rates.cacheWrite*shortWrite+rates.input*2*longWrite)/1e6,usage.cost.total=usage.cost.input+usage.cost.output+usage.cost.cacheRead+usage.cost.cacheWrite,usage.cost}var EXTENDED_THINKING_LEVELS=["off","minimal","low","medium","high","xhigh","max"];function getSupportedThinkingLevels(model2){return model2.reasoning?EXTENDED_THINKING_LEVELS.filter(level=>{let mapped=model2.thinkingLevelMap?.[level];return mapped===null?!1:level==="xhigh"||level==="max"?mapped!==void 0:!0}):["off"]}function clampThinkingLevel(model2,level){let availableLevels=getSupportedThinkingLevels(model2);if(availableLevels.includes(level))return level;let requestedIndex=EXTENDED_THINKING_LEVELS.indexOf(level);if(requestedIndex===-1)return availableLevels[0]??"off";for(let i=requestedIndex;i<EXTENDED_THINKING_LEVELS.length;i++){let candidate=EXTENDED_THINKING_LEVELS[i];if(availableLevels.includes(candidate))return candidate}for(let i=requestedIndex-1;i>=0;i--){let candidate=EXTENDED_THINKING_LEVELS[i];if(availableLevels.includes(candidate))return candidate}return availableLevels[0]??"off"}function modelsAreEqual(a,b){return!a||!b?!1:getModelType(a)===getModelType(b)&&a.id===b.id&&a.provider===b.provider}export{lazyStream,lazyApi,defaultProviderAuthContext,InMemoryCredentialStore,ModelsError,InMemoryModelsStore,AI_TELEMETRY_SCHEMA,getModelType,isModelType,assertChatModel,assertImageModel,assertClassifierModel,assertClassifierInputSupported,imageErrorResult,classifierErrorResult,contentText,getSystemMessageText,renderSystemMessageUpdate,createInitialSystemMessage,normalizeContext,getInitialSystemMessage,withoutInitialSystemMessage,getCurrentTools,getCurrentSystemMessage,getCurrentSystemPrompt,collapseSystemMessages,resolveTranscript,toToolDeclaration,declarationsEqual,getToolStateChanges,getDeclaredTools,hasToolRedefinitions,hasNonAdditiveToolChanges,resolveTranscriptTools,createModels,createProvider,hasApi,calculateCost,getSupportedThinkingLevels,clampThinkingLevel,modelsAreEqual,models_exports};
|