@openadapter/koda-ai 1.0.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/README.md +1385 -0
  2. package/dist/api-registry.d.ts +19 -0
  3. package/dist/api-registry.js +1 -0
  4. package/dist/bedrock-provider.d.ts +4 -0
  5. package/dist/bedrock-provider.js +1 -0
  6. package/dist/cli.d.ts +2 -0
  7. package/dist/cli.js +24 -0
  8. package/dist/env-api-keys.d.ts +17 -0
  9. package/dist/env-api-keys.js +1 -0
  10. package/dist/image-models.d.ts +9 -0
  11. package/dist/image-models.generated.d.ts +454 -0
  12. package/dist/image-models.generated.js +1 -0
  13. package/dist/image-models.js +1 -0
  14. package/dist/images-api-registry.d.ts +13 -0
  15. package/dist/images-api-registry.js +1 -0
  16. package/dist/images.d.ts +3 -0
  17. package/dist/images.js +1 -0
  18. package/dist/index.d.ts +31 -0
  19. package/dist/index.js +1 -0
  20. package/dist/models.d.ts +17 -0
  21. package/dist/models.generated.d.ts +18136 -0
  22. package/dist/models.generated.js +1 -0
  23. package/dist/models.js +1 -0
  24. package/dist/oauth.d.ts +1 -0
  25. package/dist/oauth.js +1 -0
  26. package/dist/providers/amazon-bedrock.d.ts +37 -0
  27. package/dist/providers/amazon-bedrock.js +1 -0
  28. package/dist/providers/anthropic.d.ts +70 -0
  29. package/dist/providers/anthropic.js +5 -0
  30. package/dist/providers/azure-openai-responses.d.ts +14 -0
  31. package/dist/providers/azure-openai-responses.js +1 -0
  32. package/dist/providers/cloudflare.d.ts +12 -0
  33. package/dist/providers/cloudflare.js +1 -0
  34. package/dist/providers/faux.d.ts +55 -0
  35. package/dist/providers/faux.js +6 -0
  36. package/dist/providers/github-copilot-headers.d.ts +7 -0
  37. package/dist/providers/github-copilot-headers.js +1 -0
  38. package/dist/providers/google-shared.d.ts +69 -0
  39. package/dist/providers/google-shared.js +2 -0
  40. package/dist/providers/google-vertex.d.ts +14 -0
  41. package/dist/providers/google-vertex.js +1 -0
  42. package/dist/providers/google.d.ts +12 -0
  43. package/dist/providers/google.js +1 -0
  44. package/dist/providers/images/openrouter.d.ts +2 -0
  45. package/dist/providers/images/openrouter.js +1 -0
  46. package/dist/providers/images/register-builtins.d.ts +3 -0
  47. package/dist/providers/images/register-builtins.js +1 -0
  48. package/dist/providers/mistral.d.ts +24 -0
  49. package/dist/providers/mistral.js +3 -0
  50. package/dist/providers/openai-codex-responses.d.ts +29 -0
  51. package/dist/providers/openai-codex-responses.js +7 -0
  52. package/dist/providers/openai-completions.d.ts +18 -0
  53. package/dist/providers/openai-completions.js +6 -0
  54. package/dist/providers/openai-prompt-cache.d.ts +2 -0
  55. package/dist/providers/openai-prompt-cache.js +1 -0
  56. package/dist/providers/openai-responses-shared.d.ts +17 -0
  57. package/dist/providers/openai-responses-shared.js +12 -0
  58. package/dist/providers/openai-responses.d.ts +12 -0
  59. package/dist/providers/openai-responses.js +1 -0
  60. package/dist/providers/register-builtins.d.ts +34 -0
  61. package/dist/providers/register-builtins.js +1 -0
  62. package/dist/providers/simple-options.d.ts +7 -0
  63. package/dist/providers/simple-options.js +1 -0
  64. package/dist/providers/transform-messages.d.ts +7 -0
  65. package/dist/providers/transform-messages.js +1 -0
  66. package/dist/session-resources.d.ts +3 -0
  67. package/dist/session-resources.js +1 -0
  68. package/dist/stream.d.ts +7 -0
  69. package/dist/stream.js +1 -0
  70. package/dist/types.d.ts +513 -0
  71. package/dist/types.js +0 -0
  72. package/dist/utils/abort-signals.d.ts +5 -0
  73. package/dist/utils/abort-signals.js +1 -0
  74. package/dist/utils/diagnostics.d.ts +18 -0
  75. package/dist/utils/diagnostics.js +1 -0
  76. package/dist/utils/event-stream.d.ts +20 -0
  77. package/dist/utils/event-stream.js +1 -0
  78. package/dist/utils/hash.d.ts +2 -0
  79. package/dist/utils/hash.js +1 -0
  80. package/dist/utils/headers.d.ts +1 -0
  81. package/dist/utils/headers.js +1 -0
  82. package/dist/utils/json-parse.d.ts +15 -0
  83. package/dist/utils/json-parse.js +2 -0
  84. package/dist/utils/node-http-proxy.d.ts +9 -0
  85. package/dist/utils/node-http-proxy.js +1 -0
  86. package/dist/utils/oauth/anthropic.d.ts +24 -0
  87. package/dist/utils/oauth/anthropic.js +1 -0
  88. package/dist/utils/oauth/device-code.d.ts +20 -0
  89. package/dist/utils/oauth/device-code.js +1 -0
  90. package/dist/utils/oauth/github-copilot.d.ts +29 -0
  91. package/dist/utils/oauth/github-copilot.js +1 -0
  92. package/dist/utils/oauth/index.d.ts +57 -0
  93. package/dist/utils/oauth/index.js +1 -0
  94. package/dist/utils/oauth/oauth-page.d.ts +2 -0
  95. package/dist/utils/oauth/oauth-page.js +74 -0
  96. package/dist/utils/oauth/openai-codex.d.ts +42 -0
  97. package/dist/utils/oauth/openai-codex.js +1 -0
  98. package/dist/utils/oauth/pkce.d.ts +12 -0
  99. package/dist/utils/oauth/pkce.js +1 -0
  100. package/dist/utils/oauth/types.d.ts +63 -0
  101. package/dist/utils/oauth/types.js +0 -0
  102. package/dist/utils/overflow.d.ts +56 -0
  103. package/dist/utils/overflow.js +1 -0
  104. package/dist/utils/sanitize-unicode.d.ts +21 -0
  105. package/dist/utils/sanitize-unicode.js +1 -0
  106. package/dist/utils/typebox-helpers.d.ts +16 -0
  107. package/dist/utils/typebox-helpers.js +1 -0
  108. package/dist/utils/validation.d.ts +17 -0
  109. package/dist/utils/validation.js +6 -0
  110. package/package.json +114 -0
package/dist/models.js ADDED
@@ -0,0 +1 @@
1
+ var d=Object.defineProperty;var n=(e,t)=>d(e,"name",{value:t,configurable:!0});import{MODELS as u}from"./models.generated.js";const f=new Map;for(const[e,t]of Object.entries(u)){const r=new Map;for(const[i,o]of Object.entries(t))r.set(i,o);f.set(e,r)}function h(e,t){return f.get(e)?.get(t)}n(h,"getModel");function m(){return Array.from(f.keys())}n(m,"getProviders");function x(e){const t=f.get(e);return t?Array.from(t.values()):[]}n(x,"getModels");function v(e,t){return t.cost.input=e.cost.input/1e6*t.input,t.cost.output=e.cost.output/1e6*t.output,t.cost.cacheRead=e.cost.cacheRead/1e6*t.cacheRead,t.cost.cacheWrite=e.cost.cacheWrite/1e6*t.cacheWrite,t.cost.total=t.cost.input+t.cost.output+t.cost.cacheRead+t.cost.cacheWrite,t.cost}n(v,"calculateCost");const s=["off","minimal","low","medium","high","xhigh"];function p(e){return e.reasoning?s.filter(t=>{const r=e.thinkingLevelMap?.[t];return r===null?!1:t==="xhigh"?r!==void 0:!0}):["off"]}n(p,"getSupportedThinkingLevels");function M(e,t){const r=p(e);if(r.includes(t))return t;const i=s.indexOf(t);if(i===-1)return r[0]??"off";for(let o=i;o<s.length;o++){const c=s[o];if(r.includes(c))return c}for(let o=i-1;o>=0;o--){const c=s[o];if(r.includes(c))return c}return r[0]??"off"}n(M,"clampThinkingLevel");function E(e,t){return!e||!t?!1:e.id===t.id&&e.provider===t.provider}n(E,"modelsAreEqual");export{v as calculateCost,M as clampThinkingLevel,h as getModel,x as getModels,m as getProviders,p as getSupportedThinkingLevels,E as modelsAreEqual};
@@ -0,0 +1 @@
1
+ export * from "./utils/oauth/index.ts";
package/dist/oauth.js ADDED
@@ -0,0 +1 @@
1
+ export*from"./utils/oauth/index.js";
@@ -0,0 +1,37 @@
1
+ import type { SimpleStreamOptions, StreamFunction, StreamOptions, ThinkingBudgets, ThinkingLevel } from "../types.ts";
2
+ export type BedrockThinkingDisplay = "summarized" | "omitted";
3
+ export interface BedrockOptions extends StreamOptions {
4
+ region?: string;
5
+ profile?: string;
6
+ toolChoice?: "auto" | "any" | "none" | {
7
+ type: "tool";
8
+ name: string;
9
+ };
10
+ reasoning?: ThinkingLevel;
11
+ thinkingBudgets?: ThinkingBudgets;
12
+ interleavedThinking?: boolean;
13
+ /**
14
+ * Controls how Claude's thinking content is returned in responses.
15
+ * - "summarized": Thinking blocks contain summarized thinking text (default here).
16
+ * - "omitted": Thinking content is redacted but the signature still travels back
17
+ * for multi-turn continuity, reducing time-to-first-text-token.
18
+ *
19
+ * Note: Anthropic's API default for Claude Opus 4.8 and Mythos Preview is
20
+ * "omitted". We default to "summarized" here to keep behavior consistent with
21
+ * older Claude 4 models. Only applies to Claude models on Bedrock.
22
+ */
23
+ thinkingDisplay?: BedrockThinkingDisplay;
24
+ /** Key-value pairs attached to the inference request for cost allocation tagging.
25
+ * Keys: max 64 chars, no `aws:` prefix. Values: max 256 chars. Max 50 pairs.
26
+ * Tags appear in AWS Cost Explorer split cost allocation data.
27
+ * @see https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_ConverseStream.html */
28
+ requestMetadata?: Record<string, string>;
29
+ /** Bearer token for Bedrock API key authentication.
30
+ * When set, bypasses SigV4 signing and sends Authorization: Bearer <token> instead.
31
+ * Requires `bedrock:CallWithBearerToken` IAM permission on the token's identity.
32
+ * Set via AWS_BEARER_TOKEN_BEDROCK env var or pass directly.
33
+ * @see https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonbedrock.html */
34
+ bearerToken?: string;
35
+ }
36
+ export declare const streamBedrock: StreamFunction<"bedrock-converse-stream", BedrockOptions>;
37
+ export declare const streamSimpleBedrock: StreamFunction<"bedrock-converse-stream", SimpleStreamOptions>;
@@ -0,0 +1 @@
1
+ var F=Object.defineProperty;var u=(e,n)=>F(e,"name",{value:n,configurable:!0});import{BedrockRuntimeClient as K,BedrockRuntimeServiceException as z,StopReason as m,CachePointType as U,CacheTTL as A,ConversationRole as k,ConverseStreamCommand as J,ImageFormat as x,ToolResultStatus as E}from"@aws-sdk/client-bedrock-runtime";import{NodeHttpHandler as O}from"@smithy/node-http-handler";import{calculateCost as j}from"../models.js";import{AssistantMessageEventStream as $}from"../utils/event-stream.js";import{parseStreamingJson as M}from"../utils/json-parse.js";import{createHttpProxyAgentsForTarget as X}from"../utils/node-http-proxy.js";import{sanitizeSurrogates as y}from"../utils/sanitize-unicode.js";import{adjustMaxTokensForThinking as G,buildBaseOptions as V,clampReasoning as Q}from"./simple-options.js";import{transformMessages as Y}from"./transform-messages.js";const w="<empty>",S=u((e,n,t={})=>{const s=new $;return(async()=>{const r={role:"assistant",content:[],api:"bedrock-converse-stream",provider:e.provider,model:e.id,usage:{input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},stopReason:"stop",timestamp:Date.now()},o=r.content,i={profile:t.profile},a=L(t),c=xe(),l=N(e.baseUrl),f=Ee(e.baseUrl,a,c);f&&(i.endpoint=e.baseUrl);const _=t.bearerToken||process.env.AWS_BEARER_TOKEN_BEDROCK||void 0,H=_!==void 0&&process.env.AWS_BEDROCK_SKIP_AUTH!=="1";if(typeof process<"u"&&(process.versions?.node||process.versions?.bun)){a?i.region=a:l&&f?i.region=l:c||(i.region="us-east-1"),process.env.AWS_BEDROCK_SKIP_AUTH==="1"&&(i.credentials={accessKeyId:"dummy-access-key",secretAccessKey:"dummy-secret-key"});const g=X(e.baseUrl);g?i.requestHandler=new O(g):process.env.AWS_BEDROCK_FORCE_HTTP1==="1"&&(i.requestHandler=new O)}else i.region=a||(l&&f?l:void 0)||"us-east-1";H&&(i.token={token:_},i.authSchemePreference=["httpBearerAuth"]);try{const g=new K(i);t.headers&&Object.keys(t.headers).length>0&&se(g,t.headers);const p=de(t.cacheRetention),I=t.maxTokens??(R(e)?e.maxTokens:void 0);let T={modelId:e.id,messages:he(n,e,p),system:ge(n.systemPrompt,e,p),inferenceConfig:{...I!==void 0&&{maxTokens:I},...t.temperature!==void 0&&{temperature:t.temperature}},toolConfig:me(n.tools,t.toolChoice),additionalModelRequestFields:Re(e,t),...t.requestMetadata!==void 0&&{requestMetadata:t.requestMetadata}};const v=await t?.onPayload?.(T,e);v!==void 0&&(T=v);const q=new J(T),h=await g.send(q,{abortSignal:t.signal});if(h.$metadata.httpStatusCode!==void 0){const d={};h.$metadata.requestId&&(d["x-amzn-requestid"]=h.$metadata.requestId),await t?.onResponse?.({status:h.$metadata.httpStatusCode,headers:d},e)}for await(const d of h.stream)if(d.messageStart){if(d.messageStart.role!==k.ASSISTANT)throw new Error("Unexpected assistant message start but got user message start instead");s.push({type:"start",partial:r})}else if(d.contentBlockStart)oe(d.contentBlockStart,o,r,s);else if(d.contentBlockDelta)re(d.contentBlockDelta,o,r,s);else if(d.contentBlockStop)ie(d.contentBlockStop,o,r,s);else if(d.messageStop)r.stopReason=ke(d.messageStop.stopReason);else if(d.metadata)ae(d.metadata,e,r);else{if(d.internalServerException)throw d.internalServerException;if(d.modelStreamErrorException)throw d.modelStreamErrorException;if(d.validationException)throw d.validationException;if(d.throttlingException)throw d.throttlingException;if(d.serviceUnavailableException)throw d.serviceUnavailableException}if(t.signal?.aborted)throw new Error("Request was aborted");if(r.stopReason==="error"||r.stopReason==="aborted")throw new Error("An unknown error occurred");s.push({type:"done",reason:r.stopReason,message:r}),s.end()}catch(g){for(const p of r.content)delete p.index,delete p.partialJson;r.stopReason=t.signal?.aborted?"aborted":"error",r.errorMessage=ee(g),s.push({type:"error",reason:r.stopReason,error:r}),s.end()}})(),s},"streamBedrock"),Z={InternalServerException:"Internal server error",ModelStreamErrorException:"Model stream error",ValidationException:"Validation error",ThrottlingException:"Throttling error",ServiceUnavailableException:"Service unavailable"};function ee(e){const n=e instanceof Error?e.message:JSON.stringify(e);return e instanceof z?`${Z[e.name]??e.name}: ${n}`:n}u(ee,"formatBedrockError");const te=new Set(["authorization","host"]);function ne(e){const n=e.toLowerCase();return n.startsWith("x-amz-")||te.has(n)}u(ne,"isReservedHeader");function se(e,n){const t=u(s=>async r=>{const o=r.request;if(o&&typeof o=="object"&&"headers"in o){const i=o.headers;for(const[a,c]of Object.entries(n))ne(a)||(i[a]=c)}return s(r)},"middleware");e.middlewareStack.add(t,{step:"build",name:"pi-ai-custom-headers",priority:"low"})}u(se,"addCustomHeadersMiddleware");const Ae=u((e,n,t)=>{const s=V(e,t,void 0);if(!t?.reasoning)return S(e,n,{...s,reasoning:void 0});if(R(e)){if(b(e.id,e.name))return S(e,n,{...s,reasoning:t.reasoning,thinkingBudgets:t.thinkingBudgets});const r=G(s.maxTokens,e.maxTokens,t.reasoning,t.thinkingBudgets);return S(e,n,{...s,maxTokens:r.maxTokens,reasoning:t.reasoning,thinkingBudgets:{...t.thinkingBudgets||{},[Q(t.reasoning)]:r.thinkingBudget}})}return S(e,n,{...s,reasoning:t.reasoning,thinkingBudgets:t.thinkingBudgets})},"streamSimpleBedrock");function oe(e,n,t,s){const r=e.contentBlockIndex,o=e.start;if(o?.toolUse){const i={type:"toolCall",id:o.toolUse.toolUseId||"",name:o.toolUse.name||"",arguments:{},partialJson:"",index:r};t.content.push(i),s.push({type:"toolcall_start",contentIndex:n.length-1,partial:t})}}u(oe,"handleContentBlockStart");function re(e,n,t,s){const r=e.contentBlockIndex,o=e.delta;let i=n.findIndex(c=>c.index===r),a=n[i];if(o?.text!==void 0){if(!a){const c={type:"text",text:"",index:r};t.content.push(c),i=n.length-1,a=n[i],s.push({type:"text_start",contentIndex:i,partial:t})}a.type==="text"&&(a.text+=o.text,s.push({type:"text_delta",contentIndex:i,delta:o.text,partial:t}))}else if(o?.toolUse&&a?.type==="toolCall")a.partialJson=(a.partialJson||"")+(o.toolUse.input||""),a.arguments=M(a.partialJson),s.push({type:"toolcall_delta",contentIndex:i,delta:o.toolUse.input||"",partial:t});else if(o?.reasoningContent){let c=a,l=i;if(!c){const f={type:"thinking",thinking:"",thinkingSignature:"",index:r};t.content.push(f),l=n.length-1,c=n[l],s.push({type:"thinking_start",contentIndex:l,partial:t})}c?.type==="thinking"&&(o.reasoningContent.text&&(c.thinking+=o.reasoningContent.text,s.push({type:"thinking_delta",contentIndex:l,delta:o.reasoningContent.text,partial:t})),o.reasoningContent.signature&&(c.thinkingSignature=(c.thinkingSignature||"")+o.reasoningContent.signature))}}u(re,"handleContentBlockDelta");function ae(e,n,t){e.usage&&(t.usage.input=e.usage.inputTokens||0,t.usage.output=e.usage.outputTokens||0,t.usage.cacheRead=e.usage.cacheReadInputTokens||0,t.usage.cacheWrite=e.usage.cacheWriteInputTokens||0,t.usage.totalTokens=e.usage.totalTokens||t.usage.input+t.usage.output,j(n,t.usage))}u(ae,"handleMetadata");function ie(e,n,t,s){const r=n.findIndex(i=>i.index===e.contentBlockIndex),o=n[r];if(o)switch(delete o.index,o.type){case"text":s.push({type:"text_end",contentIndex:r,content:o.text,partial:t});break;case"thinking":s.push({type:"thinking_end",contentIndex:r,content:o.thinking,partial:t});break;case"toolCall":o.arguments=M(o.partialJson),delete o.partialJson,s.push({type:"toolcall_end",contentIndex:r,toolCall:o,partial:t});break}}u(ie,"handleContentBlockStop");function B(e,n){return(n?[e,n]:[e]).flatMap(s=>{const r=s.toLowerCase();return[r,r.replace(/[\s_.:]+/g,"-")]})}u(B,"getModelMatchCandidates");function b(e,n){return B(e,n).some(s=>s.includes("opus-4-6")||s.includes("opus-4-7")||s.includes("opus-4-8")||s.includes("sonnet-4-6"))}u(b,"supportsAdaptiveThinking");function ce(e){return B(e.id,e.name).some(t=>t.includes("opus-4-7")||t.includes("opus-4-8"))}u(ce,"supportsNativeXhighEffort");function ue(e,n){if(n==="xhigh"&&ce(e))return"xhigh";const t=n?e.thinkingLevelMap?.[n]:void 0;if(typeof t=="string")return t;switch(n){case"minimal":case"low":return"low";case"medium":return"medium";case"high":return"high";default:return"high"}}u(ue,"mapThinkingLevelToEffort");function de(e){return e||(typeof process<"u"&&process.env.KODA_CACHE_RETENTION==="long"?"long":"short")}u(de,"resolveCacheRetention");function R(e){const n=e.id.toLowerCase(),t=e.name?.toLowerCase()??"";return n.includes("anthropic.claude")||n.includes("anthropic/claude")||t.includes("anthropic.claude")||t.includes("anthropic/claude")||t.includes("claude")}u(R,"isAnthropicClaudeModel");function D(e){const n=B(e.id,e.name);return n.some(s=>s.includes("claude"))?!!(n.some(s=>s.includes("-4-"))||n.some(s=>s.includes("claude-3-7-sonnet"))||n.some(s=>s.includes("claude-3-5-haiku"))):typeof process<"u"&&process.env.AWS_BEDROCK_FORCE_CACHE==="1"}u(D,"supportsPromptCaching");function le(e){return R(e)}u(le,"supportsThinkingSignature");function ge(e,n,t){if(!e)return;const s=[{text:y(e)}];return t!=="none"&&D(n)&&s.push({cachePoint:{type:U.DEFAULT,...t==="long"?{ttl:A.ONE_HOUR}:{}}}),s}u(ge,"buildSystemPrompt");function fe(e){const n=e.replace(/[^a-zA-Z0-9_-]/g,"_");return n.length>64?n.slice(0,64):n}u(fe,"normalizeToolCallId");function C(e){const n=y(e);return n.trim().length===0?void 0:{text:n}}u(C,"createNonBlankTextBlock");function pe(e){return C(e)??{text:w}}u(pe,"createRequiredTextBlock");function P(e){const n=[];for(const t of e)if(t.type==="image")n.push({image:W(t.mimeType,t.data)});else{const s=C(t.text);s&&n.push(s)}return n.length===0&&n.push({text:w}),n}u(P,"convertToolResultContent");function he(e,n,t){const s=[],r=Y(e.messages,n,fe);for(let o=0;o<r.length;o++){const i=r[o];switch(i.role){case"user":{const a=[];if(typeof i.content=="string")a.push(pe(i.content));else{for(const c of i.content)switch(c.type){case"text":{const l=C(c.text);l&&a.push(l);break}case"image":a.push({image:W(c.mimeType,c.data)});break;default:continue}a.length===0&&a.push({text:w})}s.push({role:k.USER,content:a});break}case"assistant":{if(i.content.length===0)continue;const a=[];for(const c of i.content)switch(c.type){case"text":{const l=C(c.text);if(!l)continue;a.push(l);break}case"toolCall":a.push({toolUse:{toolUseId:c.id,name:c.name,input:c.arguments}});break;case"thinking":{const l=y(c.thinking);if(l.trim().length===0)continue;le(n)?!c.thinkingSignature||c.thinkingSignature.trim().length===0?a.push({text:l}):a.push({reasoningContent:{reasoningText:{text:l,signature:c.thinkingSignature}}}):a.push({reasoningContent:{reasoningText:{text:l}}});break}default:continue}if(a.length===0)continue;s.push({role:k.ASSISTANT,content:a});break}case"toolResult":{const a=[];a.push({toolResult:{toolUseId:i.toolCallId,content:P(i.content),status:i.isError?E.ERROR:E.SUCCESS}});let c=o+1;for(;c<r.length&&r[c].role==="toolResult";){const l=r[c];a.push({toolResult:{toolUseId:l.toolCallId,content:P(l.content),status:l.isError?E.ERROR:E.SUCCESS}}),c++}o=c-1,s.push({role:k.USER,content:a});break}default:continue}}if(t!=="none"&&D(n)&&s.length>0){const o=s[s.length-1];o.role===k.USER&&o.content&&o.content.push({cachePoint:{type:U.DEFAULT,...t==="long"?{ttl:A.ONE_HOUR}:{}}})}return s}u(he,"convertMessages");function me(e,n){if(!e?.length||n==="none")return;const t=e.map(r=>({toolSpec:{name:r.name,description:r.description,inputSchema:{json:r.parameters}}}));let s;switch(n){case"auto":s={auto:{}};break;case"any":s={any:{}};break;default:n?.type==="tool"&&(s={tool:{name:n.name}})}return{tools:t,toolChoice:s}}u(me,"convertToolConfig");function ke(e){switch(e){case m.END_TURN:case m.STOP_SEQUENCE:return"stop";case m.MAX_TOKENS:case m.MODEL_CONTEXT_WINDOW_EXCEEDED:return"length";case m.TOOL_USE:return"toolUse";default:return"error"}}u(ke,"mapStopReason");function L(e){return typeof process>"u"?e.region:e.region||process.env.AWS_REGION||process.env.AWS_DEFAULT_REGION||void 0}u(L,"getConfiguredBedrockRegion");function xe(){return typeof process>"u"?!1:!!process.env.AWS_PROFILE}u(xe,"hasConfiguredBedrockProfile");function N(e){if(e)try{const{hostname:n}=new URL(e);return n.toLowerCase().match(/^bedrock-runtime(?:-fips)?\.([a-z0-9-]+)\.amazonaws\.com(?:\.cn)?$/)?.[1]}catch{return}}u(N,"getStandardBedrockEndpointRegion");function Ee(e,n,t){return N(e)?!n&&!t:!0}u(Ee,"shouldUseExplicitBedrockEndpoint");function Se(e,n){if(L(n)?.toLowerCase().startsWith("us-gov-"))return!0;const s=e.id.toLowerCase();return s.startsWith("us-gov.")||s.startsWith("arn:aws-us-gov:")}u(Se,"isGovCloudBedrockTarget");function Re(e,n){if(!(!n.reasoning||!e.reasoning)&&R(e)){const t=Se(e,n)?void 0:n.thinkingDisplay??"summarized",s=b(e.id,e.name)?{thinking:{type:"adaptive",...t!==void 0?{display:t}:{}},output_config:{effort:ue(e,n.reasoning)}}:(()=>{const r={minimal:1024,low:2048,medium:8192,high:16384,xhigh:16384},o=n.reasoning==="xhigh"?"high":n.reasoning;return{thinking:{type:"enabled",budget_tokens:n.thinkingBudgets?.[o]??r[n.reasoning],...t!==void 0?{display:t}:{}}}})();return!b(e.id,e.name)&&(n.interleavedThinking??!0)&&(s.anthropic_beta=["interleaved-thinking-2025-05-14"]),s}}u(Re,"buildAdditionalModelRequestFields");function W(e,n){let t;switch(e){case"image/jpeg":case"image/jpg":t=x.JPEG;break;case"image/png":t=x.PNG;break;case"image/gif":t=x.GIF;break;case"image/webp":t=x.WEBP;break;default:throw new Error(`Unknown image type: ${e}`)}const s=atob(n),r=new Uint8Array(s.length);for(let o=0;o<s.length;o++)r[o]=s.charCodeAt(o);return{source:{bytes:r},format:t}}u(W,"createImageBlock");export{S as streamBedrock,Ae as streamSimpleBedrock};
@@ -0,0 +1,70 @@
1
+ import Anthropic from "@anthropic-ai/sdk";
2
+ import type { SimpleStreamOptions, StreamFunction, StreamOptions } from "../types.ts";
3
+ export type AnthropicEffort = "low" | "medium" | "high" | "xhigh" | "max";
4
+ export type AnthropicThinkingDisplay = "summarized" | "omitted";
5
+ export interface AnthropicOptions extends StreamOptions {
6
+ /**
7
+ * Enable extended thinking.
8
+ * For adaptive thinking models: the model decides when/how much to think.
9
+ * For older models: uses budget-based thinking with thinkingBudgetTokens.
10
+ * Default: undefined (thinking is omitted unless `streamSimpleAnthropic()` maps
11
+ * a simple reasoning level to this option, or callers set it explicitly).
12
+ */
13
+ thinkingEnabled?: boolean;
14
+ /**
15
+ * Token budget for extended thinking (older models only).
16
+ * Ignored for adaptive thinking models.
17
+ * Default: 1024 when `thinkingEnabled` is true and no budget is provided.
18
+ */
19
+ thinkingBudgetTokens?: number;
20
+ /**
21
+ * Effort level for adaptive thinking models.
22
+ * Controls how much thinking Claude allocates:
23
+ * - "max": Always thinks with no constraints (Opus 4.6 only)
24
+ * - "xhigh": Highest reasoning level (Opus 4.7)
25
+ * - "high": Always thinks, deep reasoning
26
+ * - "medium": Moderate thinking, may skip for simple queries
27
+ * - "low": Minimal thinking, skips for simple tasks
28
+ * Ignored for older models.
29
+ * Default: omitted unless `streamSimpleAnthropic()` maps a simple reasoning
30
+ * level to this option.
31
+ */
32
+ effort?: AnthropicEffort;
33
+ /**
34
+ * Controls how thinking content is returned in API responses.
35
+ * - "summarized": Thinking blocks contain summarized thinking text.
36
+ * - "omitted": Thinking blocks return an empty thinking field; the encrypted
37
+ * signature still travels back for multi-turn continuity. Use for faster
38
+ * time-to-first-text-token when your UI does not surface thinking.
39
+ *
40
+ * Note: Anthropic's API default for Claude Opus 4.7 and Claude Mythos Preview
41
+ * is "omitted". We default to "summarized" here to keep behavior consistent
42
+ * with older Claude 4 models. Set this explicitly to "omitted" to opt in.
43
+ * Default: "summarized" when thinking is enabled.
44
+ */
45
+ thinkingDisplay?: AnthropicThinkingDisplay;
46
+ /**
47
+ * Whether to request the interleaved thinking beta header for non-adaptive
48
+ * thinking models. Adaptive thinking models have interleaved thinking built in,
49
+ * so the header is skipped for them regardless of this setting.
50
+ * Default: true.
51
+ */
52
+ interleavedThinking?: boolean;
53
+ /**
54
+ * Anthropic tool choice behavior. String values map to Anthropic's built-in
55
+ * choices; `{ type: "tool", name }` forces a specific tool.
56
+ * Default: omitted (Anthropic default behavior, currently equivalent to auto).
57
+ */
58
+ toolChoice?: "auto" | "any" | "none" | {
59
+ type: "tool";
60
+ name: string;
61
+ };
62
+ /**
63
+ * Pre-built Anthropic client instance. When provided, skips internal client
64
+ * construction entirely. Use this to inject alternative SDK clients such as
65
+ * `AnthropicVertex` that shares the same messaging API.
66
+ */
67
+ client?: Anthropic;
68
+ }
69
+ export declare const streamAnthropic: StreamFunction<"anthropic-messages", AnthropicOptions>;
70
+ export declare const streamSimpleAnthropic: StreamFunction<"anthropic-messages", SimpleStreamOptions>;
@@ -0,0 +1,5 @@
1
+ var L=Object.defineProperty;var g=(e,r)=>L(e,"name",{value:r,configurable:!0});import y from"@anthropic-ai/sdk";import{calculateCost as v}from"../models.js";import{AssistantMessageEventStream as O}from"../utils/event-stream.js";import{headersToRecord as M}from"../utils/headers.js";import{parseJsonWithRepair as j,parseStreamingJson as C}from"../utils/json-parse.js";import{sanitizeSurrogates as k}from"../utils/sanitize-unicode.js";import{resolveCloudflareBaseUrl as N}from"./cloudflare.js";import{buildCopilotDynamicHeaders as U,hasCopilotVisionInput as W}from"./github-copilot-headers.js";import{adjustMaxTokensForThinking as P,buildBaseOptions as H}from"./simple-options.js";import{transformMessages as J}from"./transform-messages.js";function I(e){return e||(typeof process<"u"&&process.env.KODA_CACHE_RETENTION==="long"?"long":"short")}g(I,"resolveCacheRetention");function $(e,r){const n=I(r);if(n==="none")return{retention:n};const a=n==="long"&&_(e).supportsLongCacheRetention?"1h":void 0;return{retention:n,cacheControl:{type:"ephemeral",...a&&{ttl:a}}}}g($,"getCacheControl");const D="2.1.75",G=["Read","Write","Edit","Bash","Grep","Glob","AskUserQuestion","EnterPlanMode","ExitPlanMode","KillShell","NotebookEdit","Skill","Task","TaskOutput","TodoWrite","WebFetch","WebSearch"],q=new Map(G.map(e=>[e.toLowerCase(),e])),A=g(e=>q.get(e.toLowerCase())??e,"toClaudeCodeName"),z=g((e,r)=>{if(r&&r.length>0){const n=e.toLowerCase(),a=r.find(t=>t.name.toLowerCase()===n);if(a)return a.name}return e},"fromClaudeCodeName");function R(e){if(!e.some(t=>t.type==="image"))return k(e.map(t=>t.text).join(`
2
+ `));const n=e.map(t=>t.type==="text"?{type:"text",text:k(t.text)}:{type:"image",source:{type:"base64",media_type:t.mimeType,data:t.data}});return n.some(t=>t.type==="text")||n.unshift({type:"text",text:"(see attached image)"}),n}g(R,"convertContentBlocks");const F="fine-grained-tool-streaming-2025-05-14",K="interleaved-thinking-2025-05-14";function _(e){const r=e.provider==="fireworks",n=e.provider==="cloudflare-ai-gateway"&&e.baseUrl.includes("anthropic");return{supportsEagerToolInputStreaming:e.compat?.supportsEagerToolInputStreaming??!r,supportsLongCacheRetention:e.compat?.supportsLongCacheRetention??!r,sendSessionAffinityHeaders:e.compat?.sendSessionAffinityHeaders??!!(r||n),supportsCacheControlOnTools:e.compat?.supportsCacheControlOnTools??!r,supportsTemperature:e.compat?.supportsTemperature??!0,allowEmptySignature:e.compat?.allowEmptySignature??!1}}g(_,"getAnthropicCompat");function x(...e){const r={};for(const n of e)n&&Object.assign(r,n);return r}g(x,"mergeHeaders");const V=new Set(["message_start","message_delta","message_stop","content_block_start","content_block_delta","content_block_stop"]);function S(e){if(!e.event&&e.data.length===0)return null;const r={event:e.event,data:e.data.join(`
3
+ `),raw:[...e.raw]};return e.event=null,e.data=[],e.raw=[],r}g(S,"flushSseEvent");function b(e,r){if(e==="")return S(r);if(r.raw.push(e),e.startsWith(":"))return null;const n=e.indexOf(":"),a=n===-1?e:e.slice(0,n);let t=n===-1?"":e.slice(n+1);return t.startsWith(" ")&&(t=t.slice(1)),a==="event"?r.event=t:a==="data"&&r.data.push(t),null}g(b,"decodeSseLine");function Q(e){const r=e.indexOf("\r"),n=e.indexOf(`
4
+ `);return r===-1?n:n===-1?r:Math.min(r,n)}g(Q,"nextLineBreakIndex");function w(e){const r=Q(e);if(r===-1)return null;let n=r+1;return e[r]==="\r"&&e[n]===`
5
+ `&&(n+=1),{line:e.slice(0,r),rest:e.slice(n)}}g(w,"consumeLine");async function*Y(e,r){const n=e.getReader(),a=new TextDecoder,t={event:null,data:[],raw:[]};let o="";try{for(;;){if(r?.aborted)throw new Error("Request was aborted");const{value:c,done:f}=await n.read();if(f)break;o+=a.decode(c,{stream:!0});let u=w(o);for(;u;){o=u.rest;const d=b(u.line,t);d&&(yield d),u=w(o)}}o+=a.decode();let i=w(o);for(;i;){o=i.rest;const c=b(i.line,t);c&&(yield c),i=w(o)}if(o.length>0){const c=b(o,t);c&&(yield c)}const p=S(t);p&&(yield p)}finally{n.releaseLock()}}g(Y,"iterateSseMessages");async function*Z(e,r){if(!e.body)throw new Error("Attempted to iterate over an Anthropic response with no body");let n=!1,a=!1;for await(const t of Y(e.body,r)){if(t.event==="error")throw new Error(t.data);if(V.has(t.event??""))try{const o=j(t.data);o.type==="message_start"?n=!0:o.type==="message_stop"&&(a=!0),yield o}catch(o){const i=o instanceof Error?o.message:String(o);throw new Error(`Could not parse Anthropic SSE event ${t.event}: ${i}; data=${t.data}; raw=${t.raw.join("\\n")}`)}}if(n&&!a)throw new Error("Anthropic stream ended before message_stop")}g(Z,"iterateAnthropicEvents");const T=g((e,r,n)=>{const a=new O;return(async()=>{const t={role:"assistant",content:[],api:e.api,provider:e.provider,model:e.id,usage:{input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},stopReason:"stop",timestamp:Date.now()};try{let o,i;if(n?.client)o=n.client,i=!1;else{const s=n?.apiKey;if(!s)throw new Error(`No API key for provider: ${e.provider}`);let h;if(e.provider==="github-copilot"){const B=W(r.messages);h=U({messages:r.messages,hasImages:B})}const m=(n?.cacheRetention??I())==="none"?void 0:n?.sessionId,E=te(e,s,n?.interleavedThinking??!0,se(e,r),n?.headers,h,m);o=E.client,i=E.isOAuthToken}let p=ne(e,r,i,n);const c=await n?.onPayload?.(p,e);c!==void 0&&(p=c);const f={...n?.signal?{signal:n.signal}:{},...n?.timeoutMs!==void 0?{timeout:n.timeoutMs}:{},maxRetries:n?.maxRetries??0},u=await o.messages.create({...p,stream:!0},f).asResponse();await n?.onResponse?.({status:u.status,headers:M(u.headers)},e),a.push({type:"start",partial:t});const d=t.content;for await(const s of Z(u,n?.signal))if(s.type==="message_start")t.responseId=s.message.id,t.usage.input=s.message.usage.input_tokens||0,t.usage.output=s.message.usage.output_tokens||0,t.usage.cacheRead=s.message.usage.cache_read_input_tokens||0,t.usage.cacheWrite=s.message.usage.cache_creation_input_tokens||0,t.usage.totalTokens=t.usage.input+t.usage.output+t.usage.cacheRead+t.usage.cacheWrite,v(e,t.usage);else if(s.type==="content_block_start"){if(s.content_block.type==="text"){const h={type:"text",text:"",index:s.index};t.content.push(h),a.push({type:"text_start",contentIndex:t.content.length-1,partial:t})}else if(s.content_block.type==="thinking"){const h={type:"thinking",thinking:"",thinkingSignature:"",index:s.index};t.content.push(h),a.push({type:"thinking_start",contentIndex:t.content.length-1,partial:t})}else if(s.content_block.type==="redacted_thinking"){const h={type:"thinking",thinking:"[Reasoning redacted]",thinkingSignature:s.content_block.data,redacted:!0,index:s.index};t.content.push(h),a.push({type:"thinking_start",contentIndex:t.content.length-1,partial:t})}else if(s.content_block.type==="tool_use"){const h={type:"toolCall",id:s.content_block.id,name:i?z(s.content_block.name,r.tools):s.content_block.name,arguments:s.content_block.input??{},partialJson:"",index:s.index};t.content.push(h),a.push({type:"toolcall_start",contentIndex:t.content.length-1,partial:t})}}else if(s.type==="content_block_delta"){if(s.delta.type==="text_delta"){const h=d.findIndex(m=>m.index===s.index),l=d[h];l&&l.type==="text"&&(l.text+=s.delta.text,a.push({type:"text_delta",contentIndex:h,delta:s.delta.text,partial:t}))}else if(s.delta.type==="thinking_delta"){const h=d.findIndex(m=>m.index===s.index),l=d[h];l&&l.type==="thinking"&&(l.thinking+=s.delta.thinking,a.push({type:"thinking_delta",contentIndex:h,delta:s.delta.thinking,partial:t}))}else if(s.delta.type==="input_json_delta"){const h=d.findIndex(m=>m.index===s.index),l=d[h];l&&l.type==="toolCall"&&(l.partialJson+=s.delta.partial_json,l.arguments=C(l.partialJson),a.push({type:"toolcall_delta",contentIndex:h,delta:s.delta.partial_json,partial:t}))}else if(s.delta.type==="signature_delta"){const h=d.findIndex(m=>m.index===s.index),l=d[h];l&&l.type==="thinking"&&(l.thinkingSignature=l.thinkingSignature||"",l.thinkingSignature+=s.delta.signature)}}else if(s.type==="content_block_stop"){const h=d.findIndex(m=>m.index===s.index),l=d[h];l&&(delete l.index,l.type==="text"?a.push({type:"text_end",contentIndex:h,content:l.text,partial:t}):l.type==="thinking"?a.push({type:"thinking_end",contentIndex:h,content:l.thinking,partial:t}):l.type==="toolCall"&&(l.arguments=C(l.partialJson),delete l.partialJson,a.push({type:"toolcall_end",contentIndex:h,toolCall:l,partial:t})))}else s.type==="message_delta"&&(s.delta.stop_reason&&(t.stopReason=ie(s.delta.stop_reason)),s.usage.input_tokens!=null&&(t.usage.input=s.usage.input_tokens),s.usage.output_tokens!=null&&(t.usage.output=s.usage.output_tokens),s.usage.cache_read_input_tokens!=null&&(t.usage.cacheRead=s.usage.cache_read_input_tokens),s.usage.cache_creation_input_tokens!=null&&(t.usage.cacheWrite=s.usage.cache_creation_input_tokens),t.usage.totalTokens=t.usage.input+t.usage.output+t.usage.cacheRead+t.usage.cacheWrite,v(e,t.usage));if(n?.signal?.aborted)throw new Error("Request was aborted");if(t.stopReason==="aborted"||t.stopReason==="error")throw new Error("An unknown error occurred");a.push({type:"done",reason:t.stopReason,message:t}),a.end()}catch(o){for(const i of t.content)delete i.index,delete i.partialJson;t.stopReason=n?.signal?.aborted?"aborted":"error",t.errorMessage=o instanceof Error?o.message:JSON.stringify(o),a.push({type:"error",reason:t.stopReason,error:t}),a.end()}})(),a},"streamAnthropic");function X(e,r){const n=r?e.thinkingLevelMap?.[r]:void 0;if(typeof n=="string")return n;switch(r){case"minimal":case"low":return"low";case"medium":return"medium";case"high":return"high";default:return"high"}}g(X,"mapThinkingLevelToEffort");const _e=g((e,r,n)=>{const a=n?.apiKey;if(!a)throw new Error(`No API key for provider: ${e.provider}`);const t=H(e,n,a);if(!n?.reasoning)return T(e,r,{...t,thinkingEnabled:!1});if(e.compat?.forceAdaptiveThinking===!0){const i=X(e,n.reasoning);return T(e,r,{...t,thinkingEnabled:!0,effort:i})}const o=P(t.maxTokens,e.maxTokens,n.reasoning,n.thinkingBudgets);return T(e,r,{...t,maxTokens:o.maxTokens,thinkingEnabled:!0,thinkingBudgetTokens:o.thinkingBudget})},"streamSimpleAnthropic");function ee(e){return e.includes("sk-ant-oat")}g(ee,"isOAuthToken");function te(e,r,n,a,t,o,i){const p=n&&e.compat?.forceAdaptiveThinking!==!0,c=[];if(a&&c.push(F),p&&c.push(K),e.provider==="cloudflare-ai-gateway")return{client:new y({apiKey:null,authToken:null,baseURL:N(e),dangerouslyAllowBrowser:!0,defaultHeaders:x({accept:"application/json","anthropic-dangerous-direct-browser-access":"true","cf-aig-authorization":`Bearer ${r}`,"x-api-key":null,Authorization:null,...c.length>0?{"anthropic-beta":c.join(",")}:{}},e.headers,t)}),isOAuthToken:!1};if(e.provider==="github-copilot")return{client:new y({apiKey:null,authToken:r,baseURL:e.baseUrl,dangerouslyAllowBrowser:!0,defaultHeaders:x({accept:"application/json","anthropic-dangerous-direct-browser-access":"true",...c.length>0?{"anthropic-beta":c.join(",")}:{}},e.headers,o,t)}),isOAuthToken:!1};if(ee(r))return{client:new y({apiKey:null,authToken:r,baseURL:e.baseUrl,dangerouslyAllowBrowser:!0,defaultHeaders:x({accept:"application/json","anthropic-dangerous-direct-browser-access":"true","anthropic-beta":["claude-code-20250219","oauth-2025-04-20",...c].join(","),"user-agent":`claude-cli/${D}`,"x-app":"cli"},e.headers,t)}),isOAuthToken:!0};const f=i&&_(e).sendSessionAffinityHeaders?{"x-session-affinity":i}:{};return{client:new y({apiKey:r,authToken:null,baseURL:e.baseUrl,dangerouslyAllowBrowser:!0,defaultHeaders:x({accept:"application/json","anthropic-dangerous-direct-browser-access":"true",...c.length>0?{"anthropic-beta":c.join(",")}:{}},f,e.headers,t)}),isOAuthToken:!1}}g(te,"createClient");function ne(e,r,n,a){const{cacheControl:t}=$(e,a?.cacheRetention),o=_(e),i={model:e.id,messages:ae(r.messages,e,n,t,o.allowEmptySignature),max_tokens:a?.maxTokens??e.maxTokens,stream:!0};if(n?(i.system=[{type:"text",text:"You are Claude Code, Anthropic's official CLI for Claude.",...t?{cache_control:t}:{}}],r.systemPrompt&&i.system.push({type:"text",text:k(r.systemPrompt),...t?{cache_control:t}:{}})):r.systemPrompt&&(i.system=[{type:"text",text:k(r.systemPrompt),...t?{cache_control:t}:{}}]),a?.temperature!==void 0&&!a?.thinkingEnabled&&o.supportsTemperature&&(i.temperature=a.temperature),r.tools&&r.tools.length>0&&(i.tools=oe(r.tools,n,o.supportsEagerToolInputStreaming,o.supportsCacheControlOnTools?t:void 0)),e.reasoning)if(a?.thinkingEnabled){const p=a.thinkingDisplay??"summarized";e.compat?.forceAdaptiveThinking===!0?(i.thinking={type:"adaptive",display:p},a.effort&&(i.output_config=a.effort==="xhigh"?{effort:a.effort}:{effort:a.effort})):i.thinking={type:"enabled",budget_tokens:a.thinkingBudgetTokens||1024,display:p}}else a?.thinkingEnabled===!1&&(i.thinking={type:"disabled"});if(a?.metadata){const p=a.metadata.user_id;typeof p=="string"&&(i.metadata={user_id:p})}return a?.toolChoice&&(typeof a.toolChoice=="string"?i.tool_choice={type:a.toolChoice}:i.tool_choice=a.toolChoice),i}g(ne,"buildParams");function re(e){return e.replace(/[^a-zA-Z0-9_-]/g,"_").slice(0,64)}g(re,"normalizeToolCallId");function ae(e,r,n,a,t=!1){const o=[],i=J(e,r,re);for(let p=0;p<i.length;p++){const c=i[p];if(c.role==="user")if(typeof c.content=="string")c.content.trim().length>0&&o.push({role:"user",content:k(c.content)});else{const u=c.content.map(d=>d.type==="text"?{type:"text",text:k(d.text)}:{type:"image",source:{type:"base64",media_type:d.mimeType,data:d.data}}).filter(d=>d.type==="text"?d.text.trim().length>0:!0);if(u.length===0)continue;o.push({role:"user",content:u})}else if(c.role==="assistant"){const f=[];for(const u of c.content)if(u.type==="text"){if(u.text.trim().length===0)continue;f.push({type:"text",text:k(u.text)})}else if(u.type==="thinking"){if(u.redacted){f.push({type:"redacted_thinking",data:u.thinkingSignature});continue}if(u.thinking.trim().length===0)continue;!u.thinkingSignature||u.thinkingSignature.trim().length===0?f.push(t?{type:"thinking",thinking:k(u.thinking),signature:""}:{type:"text",text:k(u.thinking)}):f.push({type:"thinking",thinking:k(u.thinking),signature:u.thinkingSignature})}else u.type==="toolCall"&&f.push({type:"tool_use",id:u.id,name:n?A(u.name):u.name,input:u.arguments??{}});if(f.length===0)continue;o.push({role:"assistant",content:f})}else if(c.role==="toolResult"){const f=[];f.push({type:"tool_result",tool_use_id:c.toolCallId,content:R(c.content),is_error:c.isError});let u=p+1;for(;u<i.length&&i[u].role==="toolResult";){const d=i[u];f.push({type:"tool_result",tool_use_id:d.toolCallId,content:R(d.content),is_error:d.isError}),u++}p=u-1,o.push({role:"user",content:f})}}if(a&&o.length>0){const p=o[o.length-1];if(p.role==="user")if(Array.isArray(p.content)){const c=p.content[p.content.length-1];c&&(c.type==="text"||c.type==="image"||c.type==="tool_result")&&(c.cache_control=a)}else typeof p.content=="string"&&(p.content=[{type:"text",text:p.content,cache_control:a}])}return o}g(ae,"convertMessages");function se(e,r){return!!r.tools?.length&&!_(e).supportsEagerToolInputStreaming}g(se,"shouldUseFineGrainedToolStreamingBeta");function oe(e,r,n,a){return e?e.map((t,o)=>{const i=t.parameters;return{name:r?A(t.name):t.name,description:t.description,...n?{eager_input_streaming:!0}:{},input_schema:{type:"object",properties:i.properties??{},required:i.required??[]},...a&&o===e.length-1?{cache_control:a}:{}}}):[]}g(oe,"convertTools");function ie(e){switch(e){case"end_turn":return"stop";case"max_tokens":return"length";case"tool_use":return"toolUse";case"refusal":return"error";case"pause_turn":return"stop";case"stop_sequence":return"stop";case"sensitive":return"error";default:throw new Error(`Unhandled stop reason: ${e}`)}}g(ie,"mapStopReason");export{T as streamAnthropic,_e as streamSimpleAnthropic};
@@ -0,0 +1,14 @@
1
+ import type { SimpleStreamOptions, StreamFunction, StreamOptions } from "../types.ts";
2
+ export interface AzureOpenAIResponsesOptions extends StreamOptions {
3
+ reasoningEffort?: "minimal" | "low" | "medium" | "high" | "xhigh";
4
+ reasoningSummary?: "auto" | "detailed" | "concise" | null;
5
+ azureApiVersion?: string;
6
+ azureResourceName?: string;
7
+ azureBaseUrl?: string;
8
+ azureDeploymentName?: string;
9
+ }
10
+ /**
11
+ * Generate function for Azure OpenAI Responses API
12
+ */
13
+ export declare const streamAzureOpenAIResponses: StreamFunction<"azure-openai-responses", AzureOpenAIResponsesOptions>;
14
+ export declare const streamSimpleAzureOpenAIResponses: StreamFunction<"azure-openai-responses", SimpleStreamOptions>;
@@ -0,0 +1 @@
1
+ var l=Object.defineProperty;var o=(r,t)=>l(r,"name",{value:t,configurable:!0});import{AzureOpenAI as A}from"openai";import{clampThinkingLevel as E}from"../models.js";import{AssistantMessageEventStream as R}from"../utils/event-stream.js";import{headersToRecord as g}from"../utils/headers.js";import{clampOpenAIPromptCacheKey as h}from"./openai-prompt-cache.js";import{convertResponsesMessages as y,convertResponsesTools as _,processResponsesStream as w}from"./openai-responses-shared.js";import{buildBaseOptions as U}from"./simple-options.js";const O="v1",v=new Set(["openai","openai-codex","opencode","azure-openai-responses"]);function I(r){const t=new Map;if(!r)return t;for(const e of r.split(",")){const s=e.trim();if(!s)continue;const[a,n]=s.split("=",2);!a||!n||t.set(a.trim(),n.trim())}return t}o(I,"parseDeploymentNameMap");function z(r,t){return t?.azureDeploymentName?t.azureDeploymentName:I(process.env.AZURE_OPENAI_DEPLOYMENT_NAME_MAP).get(r.id)||r.id}o(z,"resolveDeploymentName");function N(r){if(r instanceof Error){const t=r.status,e=typeof t=="number"?t:void 0;return e!==void 0?`Azure OpenAI API error (${e}): ${r.message}`:r.message}try{return JSON.stringify(r)}catch{return String(r)}}o(N,"formatAzureOpenAIError");const b=o((r,t,e)=>{const s=new R;return(async()=>{const a=z(r,e),n={role:"assistant",content:[],api:"azure-openai-responses",provider:r.provider,model:r.id,usage:{input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},stopReason:"stop",timestamp:Date.now()};try{const i=e?.apiKey;if(!i)throw new Error(`No API key for provider: ${r.provider}`);const u=M(r,i,e);let c=k(r,t,e,a);const p=await e?.onPayload?.(c,r);p!==void 0&&(c=p);const f={...e?.signal?{signal:e.signal}:{},...e?.timeoutMs!==void 0?{timeout:e.timeoutMs}:{},maxRetries:e?.maxRetries??0},{data:d,response:m}=await u.responses.create(c,f).withResponse();if(await e?.onResponse?.({status:m.status,headers:g(m.headers)},r),s.push({type:"start",partial:n}),await w(d,n,s,r),e?.signal?.aborted)throw new Error("Request was aborted");if(n.stopReason==="aborted"||n.stopReason==="error")throw new Error("An unknown error occurred");s.push({type:"done",reason:n.stopReason,message:n}),s.end()}catch(i){for(const u of n.content)delete u.index,delete u.partialJson;n.stopReason=e?.signal?.aborted?"aborted":"error",n.errorMessage=N(i),s.push({type:"error",reason:n.stopReason,error:n}),s.end()}})(),s},"streamAzureOpenAIResponses"),K=o((r,t,e)=>{const s=e?.apiKey;if(!s)throw new Error(`No API key for provider: ${r.provider}`);const a=U(r,e,s),n=e?.reasoning?E(r,e.reasoning):void 0;return b(r,t,{...a,reasoningEffort:n==="off"?void 0:n})},"streamSimpleAzureOpenAIResponses");function P(r){const t=r.trim().replace(/\/+$/,"");let e;try{e=new URL(t)}catch{throw new Error(`Invalid Azure OpenAI base URL: ${r}`)}const s=e.hostname.endsWith(".openai.azure.com")||e.hostname.endsWith(".cognitiveservices.azure.com"),a=e.pathname.replace(/\/+$/,"");return s&&(a===""||a==="/"||a==="/openai")&&(e.pathname="/openai/v1",e.search=""),e.toString().replace(/\/+$/,"")}o(P,"normalizeAzureBaseUrl");function S(r){return`https://${r}.openai.azure.com/openai/v1`}o(S,"buildDefaultBaseUrl");function L(r,t){const e=t?.azureApiVersion||process.env.AZURE_OPENAI_API_VERSION||O,s=t?.azureBaseUrl?.trim()||process.env.AZURE_OPENAI_BASE_URL?.trim()||void 0,a=t?.azureResourceName||process.env.AZURE_OPENAI_RESOURCE_NAME;let n=s;if(!n&&a&&(n=S(a)),!n&&r.baseUrl&&(n=r.baseUrl),!n)throw new Error("Azure OpenAI base URL is required. Set AZURE_OPENAI_BASE_URL or AZURE_OPENAI_RESOURCE_NAME, or pass azureBaseUrl, azureResourceName, or model.baseUrl.");return{baseUrl:P(n),apiVersion:e}}o(L,"resolveAzureConfig");function M(r,t,e){const s={...r.headers};e?.headers&&Object.assign(s,e.headers);const{baseUrl:a,apiVersion:n}=L(r,e);return new A({apiKey:t,apiVersion:n,dangerouslyAllowBrowser:!0,defaultHeaders:s,baseURL:a})}o(M,"createClient");function k(r,t,e,s){const a=y(r,t,v),n={model:s,input:a,stream:!0,prompt_cache_key:h(e?.sessionId)};if(e?.maxTokens&&(n.max_output_tokens=e?.maxTokens),e?.temperature!==void 0&&(n.temperature=e?.temperature),t.tools&&t.tools.length>0&&(n.tools=_(t.tools)),r.reasoning)if(e?.reasoningEffort||e?.reasoningSummary){const i=e?.reasoningEffort?r.thinkingLevelMap?.[e.reasoningEffort]??e.reasoningEffort:"medium";n.reasoning={effort:i,summary:e?.reasoningSummary||"auto"},n.include=["reasoning.encrypted_content"]}else r.thinkingLevelMap?.off!==null&&(n.reasoning={effort:r.thinkingLevelMap?.off??"none"});return n}o(k,"buildParams");export{b as streamAzureOpenAIResponses,K as streamSimpleAzureOpenAIResponses};
@@ -0,0 +1,12 @@
1
+ import type { Api, Model } from "../types.ts";
2
+ /** Workers AI direct endpoint. */
3
+ export declare const CLOUDFLARE_WORKERS_AI_BASE_URL = "https://api.cloudflare.com/client/v4/accounts/{CLOUDFLARE_ACCOUNT_ID}/ai/v1";
4
+ /** AI Gateway Unified API. https://developers.cloudflare.com/ai-gateway/usage/unified-api/ */
5
+ export declare const CLOUDFLARE_AI_GATEWAY_COMPAT_BASE_URL = "https://gateway.ai.cloudflare.com/v1/{CLOUDFLARE_ACCOUNT_ID}/{CLOUDFLARE_GATEWAY_ID}/compat";
6
+ /** AI Gateway → OpenAI passthrough. Used until /compat supports /v1/responses. */
7
+ export declare const CLOUDFLARE_AI_GATEWAY_OPENAI_BASE_URL = "https://gateway.ai.cloudflare.com/v1/{CLOUDFLARE_ACCOUNT_ID}/{CLOUDFLARE_GATEWAY_ID}/openai";
8
+ /** AI Gateway → Anthropic passthrough. */
9
+ export declare const CLOUDFLARE_AI_GATEWAY_ANTHROPIC_BASE_URL = "https://gateway.ai.cloudflare.com/v1/{CLOUDFLARE_ACCOUNT_ID}/{CLOUDFLARE_GATEWAY_ID}/anthropic";
10
+ export declare function isCloudflareProvider(provider: string): boolean;
11
+ /** Substitute `{VAR}` placeholders in a Cloudflare baseUrl from process.env. */
12
+ export declare function resolveCloudflareBaseUrl(model: Model<Api>): string;
@@ -0,0 +1 @@
1
+ var _=Object.defineProperty;var t=(r,e)=>_(r,"name",{value:e,configurable:!0});const l="https://api.cloudflare.com/client/v4/accounts/{CLOUDFLARE_ACCOUNT_ID}/ai/v1",s="https://gateway.ai.cloudflare.com/v1/{CLOUDFLARE_ACCOUNT_ID}/{CLOUDFLARE_GATEWAY_ID}/compat",E="https://gateway.ai.cloudflare.com/v1/{CLOUDFLARE_ACCOUNT_ID}/{CLOUDFLARE_GATEWAY_ID}/openai",C="https://gateway.ai.cloudflare.com/v1/{CLOUDFLARE_ACCOUNT_ID}/{CLOUDFLARE_GATEWAY_ID}/anthropic";function U(r){return r==="cloudflare-workers-ai"||r==="cloudflare-ai-gateway"}t(U,"isCloudflareProvider");function n(r){const e=r.baseUrl;return e.includes("{")?e.replace(/\{([A-Z_][A-Z0-9_]*)\}/g,(c,A)=>{const o=process.env[A];if(!o)throw new Error(`${A} is required for provider ${r.provider} but is not set.`);return o}):e}t(n,"resolveCloudflareBaseUrl");export{C as CLOUDFLARE_AI_GATEWAY_ANTHROPIC_BASE_URL,s as CLOUDFLARE_AI_GATEWAY_COMPAT_BASE_URL,E as CLOUDFLARE_AI_GATEWAY_OPENAI_BASE_URL,l as CLOUDFLARE_WORKERS_AI_BASE_URL,U as isCloudflareProvider,n as resolveCloudflareBaseUrl};
@@ -0,0 +1,55 @@
1
+ import type { AssistantMessage, Context, Model, StreamOptions, TextContent, ThinkingContent, ToolCall } from "../types.ts";
2
+ export interface FauxModelDefinition {
3
+ id: string;
4
+ name?: string;
5
+ reasoning?: boolean;
6
+ input?: ("text" | "image")[];
7
+ cost?: {
8
+ input: number;
9
+ output: number;
10
+ cacheRead: number;
11
+ cacheWrite: number;
12
+ };
13
+ contextWindow?: number;
14
+ maxTokens?: number;
15
+ }
16
+ export type FauxContentBlock = TextContent | ThinkingContent | ToolCall;
17
+ export declare function fauxText(text: string): TextContent;
18
+ export declare function fauxThinking(thinking: string): ThinkingContent;
19
+ export declare function fauxToolCall(name: string, arguments_: ToolCall["arguments"], options?: {
20
+ id?: string;
21
+ }): ToolCall;
22
+ export declare function fauxAssistantMessage(content: string | FauxContentBlock | FauxContentBlock[], options?: {
23
+ stopReason?: AssistantMessage["stopReason"];
24
+ errorMessage?: string;
25
+ responseId?: string;
26
+ timestamp?: number;
27
+ }): AssistantMessage;
28
+ export type FauxResponseFactory = (context: Context, options: StreamOptions | undefined, state: {
29
+ callCount: number;
30
+ }, model: Model<string>) => AssistantMessage | Promise<AssistantMessage>;
31
+ export type FauxResponseStep = AssistantMessage | FauxResponseFactory;
32
+ export interface RegisterFauxProviderOptions {
33
+ api?: string;
34
+ provider?: string;
35
+ models?: FauxModelDefinition[];
36
+ tokensPerSecond?: number;
37
+ tokenSize?: {
38
+ min?: number;
39
+ max?: number;
40
+ };
41
+ }
42
+ export interface FauxProviderRegistration {
43
+ api: string;
44
+ models: [Model<string>, ...Model<string>[]];
45
+ getModel(): Model<string>;
46
+ getModel(modelId: string): Model<string> | undefined;
47
+ state: {
48
+ callCount: number;
49
+ };
50
+ setResponses: (responses: FauxResponseStep[]) => void;
51
+ appendResponses: (responses: FauxResponseStep[]) => void;
52
+ getPendingResponseCount: () => number;
53
+ unregister: () => void;
54
+ }
55
+ export declare function registerFauxProvider(options?: RegisterFauxProviderOptions): FauxProviderRegistration;
@@ -0,0 +1,6 @@
1
+ var P=Object.defineProperty;var a=(t,e)=>P(t,"name",{value:e,configurable:!0});import{registerApiProvider as W,unregisterApiProviders as N}from"../api-registry.js";import{createAssistantMessageEventStream as z}from"../utils/event-stream.js";const I="faux",S="faux",C="faux-1",j="Faux Model",O="http://localhost:0",J=3,b=5,w={input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}};function B(t){return{type:"text",text:t}}a(B,"fauxText");function nt(t){return{type:"thinking",thinking:t}}a(nt,"fauxThinking");function ot(t,e,r={}){return{type:"toolCall",id:r.id??k("tool"),name:t,arguments:e}}a(ot,"fauxToolCall");function K(t){return typeof t=="string"?[B(t)]:Array.isArray(t)?t:[t]}a(K,"normalizeFauxAssistantContent");function rt(t,e={}){return{role:"assistant",content:K(t),api:I,provider:S,model:C,usage:w,stopReason:e.stopReason??"stop",errorMessage:e.errorMessage,responseId:e.responseId,timestamp:e.timestamp??Date.now()}}a(rt,"fauxAssistantMessage");function T(t){return Math.ceil(t.length/4)}a(T,"estimateTokens");function k(t){return`${t}:${Date.now()}:${Math.random().toString(36).slice(2)}`}a(k,"randomId");function L(t){return typeof t=="string"?t:t.map(e=>e.type==="text"?e.text:`[image:${e.mimeType}:${e.data.length}]`).join(`
2
+ `)}a(L,"contentToText");function U(t){return t.map(e=>e.type==="text"?e.text:e.type==="thinking"?e.thinking:`${e.name}:${JSON.stringify(e.arguments)}`).join(`
3
+ `)}a(U,"assistantContentToText");function Z(t){return[t.toolName,...t.content.map(e=>L([e]))].join(`
4
+ `)}a(Z,"toolResultToText");function G(t){return t.role==="user"?L(t.content):t.role==="assistant"?U(t.content):Z(t)}a(G,"messageToText");function V(t){const e=[];t.systemPrompt&&e.push(`system:${t.systemPrompt}`);for(const r of t.messages)e.push(`${r.role}:${G(r)}`);return t.tools?.length&&e.push(`tools:${JSON.stringify(t.tools)}`),e.join(`
5
+
6
+ `)}a(V,"serializeContext");function X(t,e){const r=Math.min(t.length,e.length);let o=0;for(;o<r&&t[o]===e[o];)o++;return o}a(X,"commonPrefixLength");function F(t,e,r,o){const c=V(e),l=T(c),n=T(U(t.content));let s=l,p=0,u=0;const d=r?.sessionId;if(d&&r?.cacheRetention!=="none"){const h=o.get(d);if(h){const m=X(h,c);p=T(h.slice(0,m)),u=T(c.slice(m)),s=Math.max(0,l-p)}else u=l;o.set(d,c)}return{...t,usage:{input:s,output:n,cacheRead:p,cacheWrite:u,totalTokens:s+n+p+u,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}}}}a(F,"withUsageEstimate");function A(t,e,r){const o=[];let c=0;for(;c<t.length;){const l=e+Math.floor(Math.random()*(r-e+1)),n=Math.max(1,l*4);o.push(t.slice(c,c+n)),c+=n}return o.length>0?o:[""]}a(A,"splitStringByTokenSize");function H(t,e,r,o){const c=structuredClone(t);return{...c,api:e,provider:r,model:o,timestamp:c.timestamp??Date.now(),usage:c.usage??w}}a(H,"cloneMessage");function $(t,e,r,o){return{role:"assistant",content:[],api:e,provider:r,model:o,usage:w,stopReason:"error",errorMessage:t instanceof Error?t.message:String(t),timestamp:Date.now()}}a($,"createErrorMessage");function M(t){return{...t,stopReason:"aborted",errorMessage:"Request was aborted",timestamp:Date.now()}}a(M,"createAbortedMessage");function D(t,e){if(!e||e<=0)return new Promise(o=>queueMicrotask(o));const r=T(t)/e*1e3;return new Promise(o=>setTimeout(o,r))}a(D,"scheduleChunk");async function Q(t,e,r,o,c,l){const n={...e,content:[]};if(l?.aborted){const s=M(n);t.push({type:"error",reason:"aborted",error:s}),t.end(s);return}t.push({type:"start",partial:{...n}});for(let s=0;s<e.content.length;s++){if(l?.aborted){const u=M(n);t.push({type:"error",reason:"aborted",error:u}),t.end(u);return}const p=e.content[s];if(p.type==="thinking"){n.content=[...n.content,{type:"thinking",thinking:""}],t.push({type:"thinking_start",contentIndex:s,partial:{...n}});for(const u of A(p.thinking,r,o)){if(await D(u,c),l?.aborted){const d=M(n);t.push({type:"error",reason:"aborted",error:d}),t.end(d);return}n.content[s].thinking+=u,t.push({type:"thinking_delta",contentIndex:s,delta:u,partial:{...n}})}t.push({type:"thinking_end",contentIndex:s,content:p.thinking,partial:{...n}});continue}if(p.type==="text"){n.content=[...n.content,{type:"text",text:""}],t.push({type:"text_start",contentIndex:s,partial:{...n}});for(const u of A(p.text,r,o)){if(await D(u,c),l?.aborted){const d=M(n);t.push({type:"error",reason:"aborted",error:d}),t.end(d);return}n.content[s].text+=u,t.push({type:"text_delta",contentIndex:s,delta:u,partial:{...n}})}t.push({type:"text_end",contentIndex:s,content:p.text,partial:{...n}});continue}n.content=[...n.content,{type:"toolCall",id:p.id,name:p.name,arguments:{}}],t.push({type:"toolcall_start",contentIndex:s,partial:{...n}});for(const u of A(JSON.stringify(p.arguments),r,o)){if(await D(u,c),l?.aborted){const d=M(n);t.push({type:"error",reason:"aborted",error:d}),t.end(d);return}t.push({type:"toolcall_delta",contentIndex:s,delta:u,partial:{...n}})}n.content[s].arguments=p.arguments,t.push({type:"toolcall_end",contentIndex:s,toolCall:p,partial:{...n}})}if(e.stopReason==="error"||e.stopReason==="aborted"){t.push({type:"error",reason:e.stopReason,error:e}),t.end(e);return}t.push({type:"done",reason:e.stopReason,message:e}),t.end(e)}a(Q,"streamWithDeltas");function at(t={}){const e=t.api??k(I),r=t.provider??S,o=k("faux-provider"),c=Math.max(1,Math.min(t.tokenSize?.min??J,t.tokenSize?.max??b)),l=Math.max(c,t.tokenSize?.max??b);let n=[];const s=t.tokensPerSecond,p={callCount:0},u=new Map,h=(t.models?.length?t.models:[{id:C,name:j,reasoning:!1,input:["text","image"],cost:{input:0,output:0,cacheRead:0,cacheWrite:0},contextWindow:128e3,maxTokens:16384}]).map(i=>({id:i.id,name:i.name??i.id,api:e,provider:r,baseUrl:O,reasoning:i.reasoning??!1,input:i.input??["text","image"],cost:i.cost??{input:0,output:0,cacheRead:0,cacheWrite:0},contextWindow:i.contextWindow??128e3,maxTokens:i.maxTokens??16384})),m=a((i,f,g)=>{const x=z(),R=n.shift();return p.callCount++,queueMicrotask(async()=>{try{if(await g?.onResponse?.({status:200,headers:{}},i),!R){let _=$(new Error("No more faux responses queued"),e,r,i.id);_=F(_,f,g,u),x.push({type:"error",reason:"error",error:_}),x.end(_);return}const E=typeof R=="function"?await R(f,g,p,i):R;let y=H(E,e,r,i.id);y=F(y,f,g,u),await Q(x,y,c,l,s,g?.signal)}catch(E){const y=$(E,e,r,i.id);x.push({type:"error",reason:"error",error:y}),x.end(y)}}),x},"stream");W({api:e,stream:m,streamSimple:a((i,f,g)=>m(i,f,g),"streamSimple")},o);function v(i){return i?h.find(f=>f.id===i):h[0]}return a(v,"getModel"),{api:e,models:h,getModel:v,state:p,setResponses(i){n=[...i]},appendResponses(i){n.push(...i)},getPendingResponseCount(){return n.length},unregister(){N(o)}}}a(at,"registerFauxProvider");export{rt as fauxAssistantMessage,B as fauxText,nt as fauxThinking,ot as fauxToolCall,at as registerFauxProvider};
@@ -0,0 +1,7 @@
1
+ import type { Message } from "../types.ts";
2
+ export declare function inferCopilotInitiator(messages: Message[]): "user" | "agent";
3
+ export declare function hasCopilotVisionInput(messages: Message[]): boolean;
4
+ export declare function buildCopilotDynamicHeaders(params: {
5
+ messages: Message[];
6
+ hasImages: boolean;
7
+ }): Record<string, string>;
@@ -0,0 +1 @@
1
+ var o=Object.defineProperty;var n=(e,t)=>o(e,"name",{value:t,configurable:!0});function i(e){const t=e[e.length-1];return t&&t.role!=="user"?"agent":"user"}n(i,"inferCopilotInitiator");function s(e){return e.some(t=>t.role==="user"&&Array.isArray(t.content)?t.content.some(r=>r.type==="image"):t.role==="toolResult"&&Array.isArray(t.content)?t.content.some(r=>r.type==="image"):!1)}n(s,"hasCopilotVisionInput");function u(e){const t={"X-Initiator":i(e.messages),"Openai-Intent":"conversation-edits"};return e.hasImages&&(t["Copilot-Vision-Request"]="true"),t}n(u,"buildCopilotDynamicHeaders");export{u as buildCopilotDynamicHeaders,s as hasCopilotVisionInput,i as inferCopilotInitiator};
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Shared utilities for Google Generative AI and Google Vertex providers.
3
+ */
4
+ import { type Content, FinishReason, FunctionCallingConfigMode, type Part } from "@google/genai";
5
+ import type { Context, Model, StopReason, Tool } from "../types.ts";
6
+ type GoogleApiType = "google-generative-ai" | "google-vertex";
7
+ /**
8
+ * Thinking level for Gemini 3 models.
9
+ * Mirrors Google's ThinkingLevel enum values.
10
+ */
11
+ export type GoogleThinkingLevel = "THINKING_LEVEL_UNSPECIFIED" | "MINIMAL" | "LOW" | "MEDIUM" | "HIGH";
12
+ /**
13
+ * Determines whether a streamed Gemini `Part` should be treated as "thinking".
14
+ *
15
+ * Protocol note (Gemini / Vertex AI thought signatures):
16
+ * - `thought: true` is the definitive marker for thinking content (thought summaries).
17
+ * - `thoughtSignature` is an encrypted representation of the model's internal thought process
18
+ * used to preserve reasoning context across multi-turn interactions.
19
+ * - `thoughtSignature` can appear on ANY part type (text, functionCall, etc.) - it does NOT
20
+ * indicate the part itself is thinking content.
21
+ * - For non-functionCall responses, the signature appears on the last part for context replay.
22
+ * - When persisting/replaying model outputs, signature-bearing parts must be preserved as-is;
23
+ * do not merge/move signatures across parts.
24
+ *
25
+ * See: https://ai.google.dev/gemini-api/docs/thought-signatures
26
+ */
27
+ export declare function isThinkingPart(part: Pick<Part, "thought" | "thoughtSignature">): boolean;
28
+ /**
29
+ * Retain thought signatures during streaming.
30
+ *
31
+ * Some backends only send `thoughtSignature` on the first delta for a given part/block; later deltas may omit it.
32
+ * This helper preserves the last non-empty signature for the current block.
33
+ *
34
+ * Note: this does NOT merge or move signatures across distinct response parts. It only prevents
35
+ * a signature from being overwritten with `undefined` within the same streamed block.
36
+ */
37
+ export declare function retainThoughtSignature(existing: string | undefined, incoming: string | undefined): string | undefined;
38
+ /**
39
+ * Models via Google APIs that require explicit tool call IDs in function calls/responses.
40
+ */
41
+ export declare function requiresToolCallId(modelId: string): boolean;
42
+ /**
43
+ * Convert internal messages to Gemini Content[] format.
44
+ */
45
+ export declare function convertMessages<T extends GoogleApiType>(model: Model<T>, context: Context): Content[];
46
+ /**
47
+ * Convert tools to Gemini function declarations format.
48
+ *
49
+ * By default uses `parametersJsonSchema` which supports full JSON Schema (including
50
+ * anyOf, oneOf, const, etc.). Set `useParameters` to true to use the legacy `parameters`
51
+ * field instead (OpenAPI 3.03 Schema). This is needed for Cloud Code Assist with Claude
52
+ * models, where the API translates `parameters` into Anthropic's `input_schema`.
53
+ */
54
+ export declare function convertTools(tools: Tool[], useParameters?: boolean): {
55
+ functionDeclarations: Record<string, unknown>[];
56
+ }[] | undefined;
57
+ /**
58
+ * Map tool choice string to Gemini FunctionCallingConfigMode.
59
+ */
60
+ export declare function mapToolChoice(choice: string): FunctionCallingConfigMode;
61
+ /**
62
+ * Map Gemini FinishReason to our StopReason.
63
+ */
64
+ export declare function mapStopReason(reason: FinishReason): StopReason;
65
+ /**
66
+ * Map string finish reason to our StopReason (for raw API responses).
67
+ */
68
+ export declare function mapStopReasonString(reason: string): StopReason;
69
+ export {};
@@ -0,0 +1,2 @@
1
+ var N=Object.defineProperty;var i=(t,e)=>N(t,"name",{value:e,configurable:!0});import{FinishReason as s,FunctionCallingConfigMode as h}from"@google/genai";import{sanitizeSurrogates as l}from"../utils/sanitize-unicode.js";import{transformMessages as _}from"./transform-messages.js";function k(t){return t.thought===!0}i(k,"isThinkingPart");function G(t,e){return typeof e=="string"&&e.length>0?e:t}i(G,"retainThoughtSignature");const M=/^[A-Za-z0-9+/]+={0,2}$/;function y(t){return!t||t.length%4!==0?!1:M.test(t)}i(y,"isValidThoughtSignature");function d(t,e){return t&&y(e)?e:void 0}i(d,"resolveThoughtSignature");function T(t){return t.startsWith("claude-")||t.startsWith("gpt-oss-")}i(T,"requiresToolCallId");function R(t){const e=t.toLowerCase().match(/^gemini(?:-live)?-(\d+)/);if(e)return Number.parseInt(e[1],10)}i(R,"getGeminiMajorVersion");function P(t){const e=R(t);return e!==void 0?e>=3:!0}i(P,"supportsMultimodalFunctionResponse");function w(t,e){const o=[],g=i(r=>T(t.id)?r.replace(/[^a-zA-Z0-9_-]/g,"_").slice(0,64):r,"normalizeToolCallId"),O=_(e.messages,t,g);for(const r of O)if(r.role==="user")if(typeof r.content=="string")o.push({role:"user",parts:[{text:l(r.content)}]});else{const u=r.content.map(a=>a.type==="text"?{text:l(a.text)}:{inlineData:{mimeType:a.mimeType,data:a.data}});if(u.length===0)continue;o.push({role:"user",parts:u})}else if(r.role==="assistant"){const u=[],a=r.provider===t.provider&&r.model===t.id;for(const n of r.content)if(n.type==="text"){if(!n.text||n.text.trim()==="")continue;const c=d(a,n.textSignature);u.push({text:l(n.text),...c&&{thoughtSignature:c}})}else if(n.type==="thinking"){if(!n.thinking||n.thinking.trim()==="")continue;if(a){const c=d(a,n.thinkingSignature);u.push({thought:!0,text:l(n.thinking),...c&&{thoughtSignature:c}})}else u.push({text:l(n.thinking)})}else if(n.type==="toolCall"){const c=d(a,n.thoughtSignature),f={functionCall:{name:n.name,args:n.arguments??{},...T(t.id)?{id:n.id}:{}},...c&&{thoughtSignature:c}};u.push(f)}if(u.length===0)continue;o.push({role:"model",parts:u})}else if(r.role==="toolResult"){const a=r.content.filter(p=>p.type==="text").map(p=>p.text).join(`
2
+ `),n=t.input.includes("image")?r.content.filter(p=>p.type==="image"):[],c=a.length>0,f=n.length>0,S=P(t.id),A=c?l(a):f?"(see attached image)":"",E=n.map(p=>({inlineData:{mimeType:p.mimeType,data:p.data}})),C=T(t.id),x={functionResponse:{name:r.toolName,response:r.isError?{error:A}:{output:A},...f&&S&&{parts:E},...C?{id:r.toolCallId}:{}}},m=o[o.length-1];m?.role==="user"&&m.parts?.some(p=>p.functionResponse)?m.parts.push(x):o.push({role:"user",parts:[x]}),f&&!S&&o.push({role:"user",parts:[{text:"Tool result image:"},...E]})}return o}i(w,"convertMessages");const F=new Set(["$schema","$id","$anchor","$dynamicAnchor","$vocabulary","$comment","$defs","definitions"]);function I(t){if(typeof t!="object"||t===null||Array.isArray(t))return t;const e={};for(const[o,g]of Object.entries(t))F.has(o)||(e[o]=I(g));return e}i(I,"sanitizeForOpenApi");function U(t,e=!1){if(t.length!==0)return[{functionDeclarations:t.map(o=>({name:o.name,description:o.description,...e?{parameters:I(o.parameters)}:{parametersJsonSchema:o.parameters}}))}]}i(U,"convertTools");function b(t){switch(t){case"auto":return h.AUTO;case"none":return h.NONE;case"any":return h.ANY;default:return h.AUTO}}i(b,"mapToolChoice");function H(t){switch(t){case s.STOP:return"stop";case s.MAX_TOKENS:return"length";case s.BLOCKLIST:case s.PROHIBITED_CONTENT:case s.SPII:case s.SAFETY:case s.IMAGE_SAFETY:case s.IMAGE_PROHIBITED_CONTENT:case s.IMAGE_RECITATION:case s.IMAGE_OTHER:case s.RECITATION:case s.FINISH_REASON_UNSPECIFIED:case s.OTHER:case s.LANGUAGE:case s.MALFORMED_FUNCTION_CALL:case s.UNEXPECTED_TOOL_CALL:case s.NO_IMAGE:return"error";default:{const e=t;throw new Error(`Unhandled stop reason: ${e}`)}}}i(H,"mapStopReason");function j(t){switch(t){case"STOP":return"stop";case"MAX_TOKENS":return"length";default:return"error"}}i(j,"mapStopReasonString");export{w as convertMessages,U as convertTools,k as isThinkingPart,H as mapStopReason,j as mapStopReasonString,b as mapToolChoice,T as requiresToolCallId,G as retainThoughtSignature};
@@ -0,0 +1,14 @@
1
+ import type { SimpleStreamOptions, StreamFunction, StreamOptions } from "../types.ts";
2
+ import type { GoogleThinkingLevel } from "./google-shared.ts";
3
+ export interface GoogleVertexOptions extends StreamOptions {
4
+ toolChoice?: "auto" | "none" | "any";
5
+ thinking?: {
6
+ enabled: boolean;
7
+ budgetTokens?: number;
8
+ level?: GoogleThinkingLevel;
9
+ };
10
+ project?: string;
11
+ location?: string;
12
+ }
13
+ export declare const streamGoogleVertex: StreamFunction<"google-vertex", GoogleVertexOptions>;
14
+ export declare const streamSimpleGoogleVertex: StreamFunction<"google-vertex", SimpleStreamOptions>;
@@ -0,0 +1 @@
1
+ var w=Object.defineProperty;var r=(e,t)=>w(e,"name",{value:t,configurable:!0});import{GoogleGenAI as L,ResourceScope as M,ThinkingLevel as p}from"@google/genai";import{calculateCost as R,clampThinkingLevel as v}from"../models.js";import{AssistantMessageEventStream as S}from"../utils/event-stream.js";import{sanitizeSurrogates as G}from"../utils/sanitize-unicode.js";import{convertMessages as N,convertTools as A,isThinkingPart as P,mapStopReason as U,mapToolChoice as D,retainThoughtSignature as O}from"./google-shared.js";import{buildBaseOptions as V}from"./simple-options.js";const T="v1",H="gcp-vertex-credentials",K={THINKING_LEVEL_UNSPECIFIED:p.THINKING_LEVEL_UNSPECIFIED,MINIMAL:p.MINIMAL,LOW:p.LOW,MEDIUM:p.MEDIUM,HIGH:p.HIGH};let W=0;const k=r((e,t,n)=>{const o=new S;return(async()=>{const i={role:"assistant",content:[],api:"google-vertex",provider:e.provider,model:e.id,usage:{input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},stopReason:"stop",timestamp:Date.now()};try{const u=q(n),l=u?B(e,u,n?.headers):j(e,z(n),X(n),n?.headers);let g=Q(e,t,n);const I=await n?.onPayload?.(g,e);I!==void 0&&(g=I);const _=await l.models.generateContentStream(g);o.push({type:"start",partial:i});let a=null;const y=i.content,c=r(()=>y.length-1,"blockIndex");for await(const d of _){i.responseId||=d.responseId;const f=d.candidates?.[0];if(f?.content?.parts)for(const s of f.content.parts){if(s.text!==void 0){const h=P(s);(!a||h&&a.type!=="thinking"||!h&&a.type!=="text")&&(a&&(a.type==="text"?o.push({type:"text_end",contentIndex:y.length-1,content:a.text,partial:i}):o.push({type:"thinking_end",contentIndex:c(),content:a.thinking,partial:i})),h?(a={type:"thinking",thinking:"",thinkingSignature:void 0},i.content.push(a),o.push({type:"thinking_start",contentIndex:c(),partial:i})):(a={type:"text",text:""},i.content.push(a),o.push({type:"text_start",contentIndex:c(),partial:i}))),a.type==="thinking"?(a.thinking+=s.text,a.thinkingSignature=O(a.thinkingSignature,s.thoughtSignature),o.push({type:"thinking_delta",contentIndex:c(),delta:s.text,partial:i})):(a.text+=s.text,a.textSignature=O(a.textSignature,s.thoughtSignature),o.push({type:"text_delta",contentIndex:c(),delta:s.text,partial:i}))}if(s.functionCall){a&&(a.type==="text"?o.push({type:"text_end",contentIndex:c(),content:a.text,partial:i}):o.push({type:"thinking_end",contentIndex:c(),content:a.thinking,partial:i}),a=null);const h=s.functionCall.id,m={type:"toolCall",id:!h||i.content.some(x=>x.type==="toolCall"&&x.id===h)?`${s.functionCall.name}_${Date.now()}_${++W}`:h,name:s.functionCall.name||"",arguments:s.functionCall.args??{},...s.thoughtSignature&&{thoughtSignature:s.thoughtSignature}};i.content.push(m),o.push({type:"toolcall_start",contentIndex:c(),partial:i}),o.push({type:"toolcall_delta",contentIndex:c(),delta:JSON.stringify(m.arguments),partial:i}),o.push({type:"toolcall_end",contentIndex:c(),toolCall:m,partial:i})}}f?.finishReason&&(i.stopReason=U(f.finishReason),i.content.some(s=>s.type==="toolCall")&&(i.stopReason="toolUse")),d.usageMetadata&&(i.usage={input:(d.usageMetadata.promptTokenCount||0)-(d.usageMetadata.cachedContentTokenCount||0),output:(d.usageMetadata.candidatesTokenCount||0)+(d.usageMetadata.thoughtsTokenCount||0),cacheRead:d.usageMetadata.cachedContentTokenCount||0,cacheWrite:0,totalTokens:d.usageMetadata.totalTokenCount||0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},R(e,i.usage))}if(a&&(a.type==="text"?o.push({type:"text_end",contentIndex:c(),content:a.text,partial:i}):o.push({type:"thinking_end",contentIndex:c(),content:a.thinking,partial:i})),n?.signal?.aborted)throw new Error("Request was aborted");if(i.stopReason==="aborted"||i.stopReason==="error")throw new Error("An unknown error occurred");o.push({type:"done",reason:i.stopReason,message:i}),o.end()}catch(u){for(const l of i.content)"index"in l&&delete l.index;i.stopReason=n?.signal?.aborted?"aborted":"error",i.errorMessage=u instanceof Error?u.message:JSON.stringify(u),o.push({type:"error",reason:i.stopReason,error:i}),o.end()}})(),o},"streamGoogleVertex"),le=r((e,t,n)=>{const o=V(e,n,void 0);if(!n?.reasoning)return k(e,t,{...o,thinking:{enabled:!1}});const i=v(e,n.reasoning),u=i==="off"?"high":i,l=e;return C(l)||E(l)?k(e,t,{...o,thinking:{enabled:!0,level:Z(u,l)}}):k(e,t,{...o,thinking:{enabled:!0,budgetTokens:ee(l,u,n.thinkingBudgets)}})},"streamSimpleGoogleVertex");function j(e,t,n,o){return new L({vertexai:!0,project:t,location:n,apiVersion:T,httpOptions:b(e,o)})}r(j,"createClient");function B(e,t,n){return new L({vertexai:!0,apiKey:t,apiVersion:T,httpOptions:b(e,n)})}r(B,"createClientWithApiKey");function b(e,t){const n={},o=J(e.baseUrl);return o&&(n.baseUrl=o,n.baseUrlResourceScope=M.COLLECTION,$(o)&&(n.apiVersion="")),(e.headers||t)&&(n.headers={...e.headers,...t}),Object.keys(n).length>0?n:void 0}r(b,"buildHttpOptions");function J(e){const t=e.trim();if(!(!t||t.includes("{location}")))return t}r(J,"resolveCustomBaseUrl");function $(e){try{return new URL(e).pathname.split("/").some(n=>/^v\d+(?:beta\d*)?$/.test(n))}catch{return/(?:^|\/)v\d+(?:beta\d*)?(?:\/|$)/.test(e)}}r($,"baseUrlIncludesApiVersion");function q(e){const t=e?.apiKey?.trim();if(!(!t||t===H||F(t)))return t}r(q,"resolveApiKey");function F(e){return/^<[^>]+>$/.test(e)}r(F,"isPlaceholderApiKey");function z(e){const t=e?.project||process.env.GOOGLE_CLOUD_PROJECT||process.env.GCLOUD_PROJECT;if(!t)throw new Error("Vertex AI requires a project ID. Set GOOGLE_CLOUD_PROJECT/GCLOUD_PROJECT or pass project in options.");return t}r(z,"resolveProject");function X(e){const t=e?.location||process.env.GOOGLE_CLOUD_LOCATION;if(!t)throw new Error("Vertex AI requires a location. Set GOOGLE_CLOUD_LOCATION or pass location in options.");return t}r(X,"resolveLocation");function Q(e,t,n={}){const o=N(e,t),i={};n.temperature!==void 0&&(i.temperature=n.temperature),n.maxTokens!==void 0&&(i.maxOutputTokens=n.maxTokens);const u={...Object.keys(i).length>0&&i,...t.systemPrompt&&{systemInstruction:G(t.systemPrompt)},...t.tools&&t.tools.length>0&&{tools:A(t.tools)}};if(t.tools&&t.tools.length>0&&n.toolChoice?u.toolConfig={functionCallingConfig:{mode:D(n.toolChoice)}}:u.toolConfig=void 0,n.thinking?.enabled&&e.reasoning){const g={includeThoughts:!0};n.thinking.level!==void 0?g.thinkingLevel=K[n.thinking.level]:n.thinking.budgetTokens!==void 0&&(g.thinkingBudget=n.thinking.budgetTokens),u.thinkingConfig=g}else e.reasoning&&n.thinking&&!n.thinking.enabled&&(u.thinkingConfig=Y(e));if(n.signal){if(n.signal.aborted)throw new Error("Request aborted");u.abortSignal=n.signal}return{model:e.id,contents:o,config:u}}r(Q,"buildParams");function C(e){return/gemini-3(?:\.\d+)?-pro/.test(e.id.toLowerCase())}r(C,"isGemini3ProModel");function E(e){return/gemini-3(?:\.\d+)?-flash/.test(e.id.toLowerCase())}r(E,"isGemini3FlashModel");function Y(e){const t=e;return C(t)?{thinkingLevel:p.LOW}:E(t)?{thinkingLevel:p.MINIMAL}:{thinkingBudget:0}}r(Y,"getDisabledThinkingConfig");function Z(e,t){if(C(t))switch(e){case"minimal":case"low":return"LOW";case"medium":case"high":return"HIGH"}switch(e){case"minimal":return"MINIMAL";case"low":return"LOW";case"medium":return"MEDIUM";case"high":return"HIGH"}}r(Z,"getGemini3ThinkingLevel");function ee(e,t,n){return n?.[t]!==void 0?n[t]:e.id.includes("2.5-pro")?{minimal:128,low:2048,medium:8192,high:32768}[t]:e.id.includes("2.5-flash")?{minimal:128,low:2048,medium:8192,high:24576}[t]:-1}r(ee,"getGoogleBudget");export{k as streamGoogleVertex,le as streamSimpleGoogleVertex};
@@ -0,0 +1,12 @@
1
+ import type { SimpleStreamOptions, StreamFunction, StreamOptions } from "../types.ts";
2
+ import type { GoogleThinkingLevel } from "./google-shared.ts";
3
+ export interface GoogleOptions extends StreamOptions {
4
+ toolChoice?: "auto" | "none" | "any";
5
+ thinking?: {
6
+ enabled: boolean;
7
+ budgetTokens?: number;
8
+ level?: GoogleThinkingLevel;
9
+ };
10
+ }
11
+ export declare const streamGoogle: StreamFunction<"google-generative-ai", GoogleOptions>;
12
+ export declare const streamSimpleGoogle: StreamFunction<"google-generative-ai", SimpleStreamOptions>;
@@ -0,0 +1 @@
1
+ var T=Object.defineProperty;var g=(e,a)=>T(e,"name",{value:a,configurable:!0});import{GoogleGenAI as v}from"@google/genai";import{calculateCost as S,clampThinkingLevel as R}from"../models.js";import{AssistantMessageEventStream as L}from"../utils/event-stream.js";import{sanitizeSurrogates as _}from"../utils/sanitize-unicode.js";import{convertMessages as G,convertTools as O,isThinkingPart as N,mapStopReason as A,mapToolChoice as P,retainThoughtSignature as b}from"./google-shared.js";import{buildBaseOptions as E}from"./simple-options.js";let W=0;const k=g((e,a,n)=>{const i=new L;return(async()=>{const t={role:"assistant",content:[],api:"google-generative-ai",provider:e.provider,model:e.id,usage:{input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},stopReason:"stop",timestamp:Date.now()};try{const s=n?.apiKey;if(!s)throw new Error(`No API key for provider: ${e.provider}`);const h=B(e,s,n?.headers);let u=H(e,a,n);const C=await n?.onPayload?.(u,e);C!==void 0&&(u=C);const M=await h.models.generateContentStream(u);i.push({type:"start",partial:t});let o=null;const I=t.content,l=g(()=>I.length-1,"blockIndex");for await(const c of M){t.responseId||=c.responseId;const p=c.candidates?.[0];if(p?.content?.parts)for(const r of p.content.parts){if(r.text!==void 0){const d=N(r);(!o||d&&o.type!=="thinking"||!d&&o.type!=="text")&&(o&&(o.type==="text"?i.push({type:"text_end",contentIndex:I.length-1,content:o.text,partial:t}):i.push({type:"thinking_end",contentIndex:l(),content:o.thinking,partial:t})),d?(o={type:"thinking",thinking:"",thinkingSignature:void 0},t.content.push(o),i.push({type:"thinking_start",contentIndex:l(),partial:t})):(o={type:"text",text:""},t.content.push(o),i.push({type:"text_start",contentIndex:l(),partial:t}))),o.type==="thinking"?(o.thinking+=r.text,o.thinkingSignature=b(o.thinkingSignature,r.thoughtSignature),i.push({type:"thinking_delta",contentIndex:l(),delta:r.text,partial:t})):(o.text+=r.text,o.textSignature=b(o.textSignature,r.thoughtSignature),i.push({type:"text_delta",contentIndex:l(),delta:r.text,partial:t}))}if(r.functionCall){o&&(o.type==="text"?i.push({type:"text_end",contentIndex:l(),content:o.text,partial:t}):i.push({type:"thinking_end",contentIndex:l(),content:o.thinking,partial:t}),o=null);const d=r.functionCall.id,f={type:"toolCall",id:!d||t.content.some(x=>x.type==="toolCall"&&x.id===d)?`${r.functionCall.name}_${Date.now()}_${++W}`:d,name:r.functionCall.name||"",arguments:r.functionCall.args??{},...r.thoughtSignature&&{thoughtSignature:r.thoughtSignature}};t.content.push(f),i.push({type:"toolcall_start",contentIndex:l(),partial:t}),i.push({type:"toolcall_delta",contentIndex:l(),delta:JSON.stringify(f.arguments),partial:t}),i.push({type:"toolcall_end",contentIndex:l(),toolCall:f,partial:t})}}p?.finishReason&&(t.stopReason=A(p.finishReason),t.content.some(r=>r.type==="toolCall")&&(t.stopReason="toolUse")),c.usageMetadata&&(t.usage={input:(c.usageMetadata.promptTokenCount||0)-(c.usageMetadata.cachedContentTokenCount||0),output:(c.usageMetadata.candidatesTokenCount||0)+(c.usageMetadata.thoughtsTokenCount||0),cacheRead:c.usageMetadata.cachedContentTokenCount||0,cacheWrite:0,totalTokens:c.usageMetadata.totalTokenCount||0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},S(e,t.usage))}if(o&&(o.type==="text"?i.push({type:"text_end",contentIndex:l(),content:o.text,partial:t}):i.push({type:"thinking_end",contentIndex:l(),content:o.thinking,partial:t})),n?.signal?.aborted)throw new Error("Request was aborted");if(t.stopReason==="aborted"||t.stopReason==="error")throw new Error("An unknown error occurred");i.push({type:"done",reason:t.stopReason,message:t}),i.end()}catch(s){for(const h of t.content)"index"in h&&delete h.index;t.stopReason=n?.signal?.aborted?"aborted":"error",t.errorMessage=s instanceof Error?s.message:JSON.stringify(s),i.push({type:"error",reason:t.stopReason,error:t}),i.end()}})(),i},"streamGoogle"),Y=g((e,a,n)=>{const i=n?.apiKey;if(!i)throw new Error(`No API key for provider: ${e.provider}`);const t=E(e,n,i);if(!n?.reasoning)return k(e,a,{...t,thinking:{enabled:!1}});const s=R(e,n.reasoning),h=s==="off"?"high":s,u=e;return y(u)||w(u)||m(u)?k(e,a,{...t,thinking:{enabled:!0,level:$(h,u)}}):k(e,a,{...t,thinking:{enabled:!0,budgetTokens:D(u,h,n.thinkingBudgets)}})},"streamSimpleGoogle");function B(e,a,n){const i={};return e.baseUrl&&(i.baseUrl=e.baseUrl,i.apiVersion=""),(e.headers||n)&&(i.headers={...e.headers,...n}),new v({apiKey:a,httpOptions:Object.keys(i).length>0?i:void 0})}g(B,"createClient");function H(e,a,n={}){const i=G(e,a),t={};n.temperature!==void 0&&(t.temperature=n.temperature),n.maxTokens!==void 0&&(t.maxOutputTokens=n.maxTokens);const s={...Object.keys(t).length>0&&t,...a.systemPrompt&&{systemInstruction:_(a.systemPrompt)},...a.tools&&a.tools.length>0&&{tools:O(a.tools)}};if(a.tools&&a.tools.length>0&&n.toolChoice?s.toolConfig={functionCallingConfig:{mode:P(n.toolChoice)}}:s.toolConfig=void 0,n.thinking?.enabled&&e.reasoning){const u={includeThoughts:!0};n.thinking.level!==void 0?u.thinkingLevel=n.thinking.level:n.thinking.budgetTokens!==void 0&&(u.thinkingBudget=n.thinking.budgetTokens),s.thinkingConfig=u}else e.reasoning&&n.thinking&&!n.thinking.enabled&&(s.thinkingConfig=U(e));if(n.signal){if(n.signal.aborted)throw new Error("Request aborted");s.abortSignal=n.signal}return{model:e.id,contents:i,config:s}}g(H,"buildParams");function m(e){return/gemma-?4/.test(e.id.toLowerCase())}g(m,"isGemma4Model");function y(e){return/gemini-3(?:\.\d+)?-pro/.test(e.id.toLowerCase())}g(y,"isGemini3ProModel");function w(e){return/gemini-3(?:\.\d+)?-flash/.test(e.id.toLowerCase())}g(w,"isGemini3FlashModel");function U(e){return y(e)?{thinkingLevel:"LOW"}:w(e)?{thinkingLevel:"MINIMAL"}:m(e)?{thinkingLevel:"MINIMAL"}:{thinkingBudget:0}}g(U,"getDisabledThinkingConfig");function $(e,a){if(y(a))switch(e){case"minimal":case"low":return"LOW";case"medium":case"high":return"HIGH"}if(m(a))switch(e){case"minimal":case"low":return"MINIMAL";case"medium":case"high":return"HIGH"}switch(e){case"minimal":return"MINIMAL";case"low":return"LOW";case"medium":return"MEDIUM";case"high":return"HIGH"}}g($,"getThinkingLevel");function D(e,a,n){return n?.[a]!==void 0?n[a]:e.id.includes("2.5-pro")?{minimal:128,low:2048,medium:8192,high:32768}[a]:e.id.includes("2.5-flash-lite")?{minimal:512,low:2048,medium:8192,high:24576}[a]:e.id.includes("2.5-flash")?{minimal:128,low:2048,medium:8192,high:24576}[a]:-1}g(D,"getGoogleBudget");export{k as streamGoogle,Y as streamSimpleGoogle};
@@ -0,0 +1,2 @@
1
+ import type { ImagesFunction, ImagesOptions } from "../../types.ts";
2
+ export declare const generateImagesOpenRouter: ImagesFunction<"openrouter-images", ImagesOptions>;
@@ -0,0 +1 @@
1
+ var R=Object.defineProperty;var u=(e,r)=>R(e,"name",{value:r,configurable:!0});import x from"openai";import{headersToRecord as _}from"../../utils/headers.js";import{sanitizeSurrogates as k}from"../../utils/sanitize-unicode.js";const O=u(async(e,r,t)=>{const s={api:e.api,provider:e.provider,model:e.id,output:[],stopReason:"stop",timestamp:Date.now()};try{const a=t?.apiKey;if(!a)throw new Error(`No API key for provider: ${e.provider}`);const c=w(e,a,t?.headers);let n=T(e,r);const i=await t?.onPayload?.(n,e);i!==void 0&&(n=i);const o={...t?.signal?{signal:t.signal}:{},...t?.timeoutMs!==void 0?{timeout:t.timeoutMs}:{},maxRetries:t?.maxRetries??0},{data:y,response:f}=await c.chat.completions.create(n,o).withResponse();await t?.onResponse?.({status:f.status,headers:_(f.headers)},e);const p=y;s.responseId=p.id,p.usage&&(s.usage=b(p.usage,e));const m=p.choices[0];if(m){const d=m.message.content;typeof d=="string"&&d.length>0&&s.output.push({type:"text",text:d});for(const h of m.message.images??[]){const l=typeof h.image_url=="string"?h.image_url:h.image_url?.url;if(!l?.startsWith("data:"))continue;const g=l.match(/^data:([^;]+);base64,(.+)$/);g&&s.output.push({type:"image",mimeType:g[1],data:g[2]})}}return s}catch(a){return s.stopReason=t?.signal?.aborted?"aborted":"error",s.errorMessage=a instanceof Error?a.message:JSON.stringify(a),s}},"generateImagesOpenRouter");function w(e,r,t){return new x({apiKey:r,baseURL:e.baseUrl,dangerouslyAllowBrowser:!0,defaultHeaders:{...e.headers,...t}})}u(w,"createClient");function T(e,r){const t=r.input.map(s=>s.type==="text"?{type:"text",text:k(s.text)}:{type:"image_url",image_url:{url:`data:${s.mimeType};base64,${s.data}`}});return{model:e.id,messages:[{role:"user",content:t}],stream:!1,modalities:e.output.includes("text")?["image","text"]:["image"]}}u(T,"buildParams");function b(e,r){const t=e.prompt_tokens||0,s=e.prompt_tokens_details?.cached_tokens||0,a=e.prompt_tokens_details?.cache_write_tokens||0,c=a>0?Math.max(0,s-a):s,n=Math.max(0,t-c-a),i=e.completion_tokens||0,o={input:n,output:i,cacheRead:c,cacheWrite:a,totalTokens:n+i+c+a,cost:{input:r.cost.input/1e6*n,output:r.cost.output/1e6*i,cacheRead:r.cost.cacheRead/1e6*c,cacheWrite:r.cost.cacheWrite/1e6*a,total:0}};return o.cost.total=o.cost.input+o.cost.output+o.cost.cacheRead+o.cost.cacheWrite,o}u(b,"parseUsage");export{O as generateImagesOpenRouter};
@@ -0,0 +1,3 @@
1
+ import type { ImagesFunction, ImagesOptions } from "../../types.ts";
2
+ export declare const generateImagesOpenRouter: ImagesFunction<"openrouter-images", ImagesOptions>;
3
+ export declare function registerBuiltInImagesApiProviders(): void;
@@ -0,0 +1 @@
1
+ var i=Object.defineProperty;var t=(e,r)=>i(e,"name",{value:r,configurable:!0});import{registerImagesApiProvider as s}from"../../images-api-registry.js";let a;function p(e,r){return{api:e.api,provider:e.provider,model:e.id,output:[],stopReason:"error",errorMessage:r instanceof Error?r.message:String(r),timestamp:Date.now()}}t(p,"createLazyLoadErrorImages");function u(){return a||=import("./openrouter.js").then(e=>e),a}t(u,"loadOpenRouterImagesProviderModule");const g=t(async(e,r,n)=>{try{return await(await u()).generateImagesOpenRouter(e,r,n)}catch(o){return p(e,o)}},"generateImagesOpenRouter");function m(){s({api:"openrouter-images",generateImages:g})}t(m,"registerBuiltInImagesApiProviders"),m();export{g as generateImagesOpenRouter,m as registerBuiltInImagesApiProviders};
@@ -0,0 +1,24 @@
1
+ import type { SimpleStreamOptions, StreamFunction, StreamOptions } from "../types.ts";
2
+ /**
3
+ * Provider-specific options for the Mistral API.
4
+ */
5
+ type MistralReasoningEffort = "none" | "high";
6
+ export interface MistralOptions extends StreamOptions {
7
+ toolChoice?: "auto" | "none" | "any" | "required" | {
8
+ type: "function";
9
+ function: {
10
+ name: string;
11
+ };
12
+ };
13
+ promptMode?: "reasoning";
14
+ reasoningEffort?: MistralReasoningEffort;
15
+ }
16
+ /**
17
+ * Stream responses from Mistral using `chat.stream`.
18
+ */
19
+ export declare const streamMistral: StreamFunction<"mistral-conversations", MistralOptions>;
20
+ /**
21
+ * Maps provider-agnostic `SimpleStreamOptions` to Mistral options.
22
+ */
23
+ export declare const streamSimpleMistral: StreamFunction<"mistral-conversations", SimpleStreamOptions>;
24
+ export {};
@@ -0,0 +1,3 @@
1
+ var A=Object.defineProperty;var a=(e,t)=>A(e,"name",{value:t,configurable:!0});import{Mistral as $}from"@mistralai/mistralai";import{calculateCost as S,clampThinkingLevel as E}from"../models.js";import{AssistantMessageEventStream as O}from"../utils/event-stream.js";import{shortHash as P}from"../utils/hash.js";import{parseStreamingJson as I}from"../utils/json-parse.js";import{sanitizeSurrogates as y}from"../utils/sanitize-unicode.js";import{buildBaseOptions as L}from"./simple-options.js";import{transformMessages as B}from"./transform-messages.js";const T=9,N=4e3,j=a((e,t,r)=>{const n=new O;return(async()=>{const o=v(e);try{const u=r?.apiKey;if(!u)throw new Error(`No API key for provider: ${e.provider}`);const l=new $({apiKey:u,serverURL:e.baseUrl}),p=z(),s=B(t.messages,e,x=>p(x));let c=q(e,t,s,r);const i=await r?.onPayload?.(c,e);i!==void 0&&(c=i);const f=await l.chat.stream(c,J(e,r));if(n.push({type:"start",partial:o}),await H(e,o,n,f),r?.signal?.aborted)throw new Error("Request was aborted");if(o.stopReason==="aborted"||o.stopReason==="error")throw new Error("An unknown error occurred");n.push({type:"done",reason:o.stopReason,message:o}),n.end()}catch(u){for(const l of o.content)delete l.partialArgs;o.stopReason=r?.signal?.aborted?"aborted":"error",o.errorMessage=D(u),n.push({type:"error",reason:o.stopReason,error:o}),n.end()}})(),n},"streamMistral"),ct=a((e,t,r)=>{const n=r?.apiKey;if(!n)throw new Error(`No API key for provider: ${e.provider}`);const o=L(e,r,n),u=r?.reasoning?E(e,r.reasoning):void 0,l=u==="off"?void 0:u,p=e.reasoning&&l!==void 0;return j(e,t,{...o,promptMode:p&&G(e)?"reasoning":void 0,reasoningEffort:p&&w(e)?X(e,l):void 0})},"streamSimpleMistral");function v(e){return{role:"assistant",content:[],api:e.api,provider:e.provider,model:e.id,usage:{input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},stopReason:"stop",timestamp:Date.now()}}a(v,"createOutput");function z(){const e=new Map,t=new Map;return r=>{const n=e.get(r);if(n)return n;let o=0;for(;;){const u=b(r,o),l=t.get(u);if(!l||l===r)return e.set(r,u),t.set(u,r),u;o++}}}a(z,"createMistralToolCallIdNormalizer");function b(e,t){const r=e.replace(/[^a-zA-Z0-9]/g,"");if(t===0&&r.length===T)return r;const n=r||e,o=t===0?n:`${n}:${t}`;return P(o).replace(/[^a-zA-Z0-9]/g,"").slice(0,T)}a(b,"deriveMistralToolCallId");function D(e){if(e instanceof Error){const t=e,r=typeof t.statusCode=="number"?t.statusCode:void 0,n=typeof t.body=="string"?t.body.trim():void 0;return r!==void 0&&n?`Mistral API error (${r}): ${K(n,N)}`:r!==void 0?`Mistral API error (${r}): ${e.message}`:e.message}return U(e)}a(D,"formatMistralError");function K(e,t){return e.length<=t?e:`${e.slice(0,t)}... [truncated ${e.length-t} chars]`}a(K,"truncateErrorText");function U(e){try{const t=JSON.stringify(e);return t===void 0?String(e):t}catch{return String(e)}}a(U,"safeJsonStringify");function J(e,t){const r={retries:{strategy:"none"}};t?.signal&&(r.signal=t.signal);const n={};return e.headers&&Object.assign(n,e.headers),t?.headers&&Object.assign(n,t.headers),t?.sessionId&&!n["x-affinity"]&&(n["x-affinity"]=t.sessionId),Object.keys(n).length>0&&(r.headers=n),r}a(J,"buildRequestOptions");function q(e,t,r,n){const o={model:e.id,stream:!0,messages:Z(r,e.input.includes("image"))};return t.tools?.length&&(o.tools=W(t.tools)),n?.temperature!==void 0&&(o.temperature=n.temperature),n?.maxTokens!==void 0&&(o.maxTokens=n.maxTokens),n?.toolChoice&&(o.toolChoice=Y(n.toolChoice)),n?.promptMode&&(o.promptMode=n.promptMode),n?.reasoningEffort&&(o.reasoningEffort=n.reasoningEffort),t.systemPrompt&&o.messages.unshift({role:"system",content:y(t.systemPrompt)}),o}a(q,"buildChatPayload");async function H(e,t,r,n){let o=null;const u=t.content,l=a(()=>u.length-1,"blockIndex"),p=new Map,s=a(c=>{if(c){if(c.type==="text"){r.push({type:"text_end",contentIndex:l(),content:c.text,partial:t});return}c.type==="thinking"&&r.push({type:"thinking_end",contentIndex:l(),content:c.thinking,partial:t})}},"finishCurrentBlock");for await(const c of n){const i=c.data;t.responseId||=i.id,i.usage&&(t.usage.input=i.usage.promptTokens||0,t.usage.output=i.usage.completionTokens||0,t.usage.cacheRead=0,t.usage.cacheWrite=0,t.usage.totalTokens=i.usage.totalTokens||t.usage.input+t.usage.output,S(e,t.usage));const f=i.choices[0];if(!f)continue;f.finishReason&&(t.stopReason=Q(f.finishReason));const x=f.delta;if(x.content!==null&&x.content!==void 0){const g=typeof x.content=="string"?[x.content]:x.content;for(const h of g){if(typeof h=="string"){const m=y(h);(!o||o.type!=="text")&&(s(o),o={type:"text",text:""},t.content.push(o),r.push({type:"text_start",contentIndex:l(),partial:t})),o.text+=m,r.push({type:"text_delta",contentIndex:l(),delta:m,partial:t});continue}if(h.type==="thinking"){const m=h.thinking.map(d=>"text"in d?d.text:"").filter(d=>d.length>0).join(""),k=y(m);if(!k)continue;(!o||o.type!=="thinking")&&(s(o),o={type:"thinking",thinking:""},t.content.push(o),r.push({type:"thinking_start",contentIndex:l(),partial:t})),o.thinking+=k,r.push({type:"thinking_delta",contentIndex:l(),delta:k,partial:t});continue}if(h.type==="text"){const m=y(h.text);(!o||o.type!=="text")&&(s(o),o={type:"text",text:""},t.content.push(o),r.push({type:"text_start",contentIndex:l(),partial:t})),o.text+=m,r.push({type:"text_delta",contentIndex:l(),delta:m,partial:t})}}}const _=x.toolCalls||[];for(const g of _){o&&(s(o),o=null);const h=g.id&&g.id!=="null"?g.id:b(`toolcall:${g.index??0}`,0),m=`${h}:${g.index||0}`,k=p.get(m);let d;if(k!==void 0){const C=t.content[k];C?.type==="toolCall"&&(d=C)}d||(d={type:"toolCall",id:h,name:g.function.name,arguments:{},partialArgs:""},t.content.push(d),p.set(m,t.content.length-1),r.push({type:"toolcall_start",contentIndex:t.content.length-1,partial:t}));const R=typeof g.function.arguments=="string"?g.function.arguments:JSON.stringify(g.function.arguments||{});d.partialArgs=(d.partialArgs||"")+R,d.arguments=I(d.partialArgs),r.push({type:"toolcall_delta",contentIndex:p.get(m),delta:R,partial:t})}}s(o);for(const c of p.values()){const i=t.content[c];if(i.type!=="toolCall")continue;const f=i;f.arguments=I(f.partialArgs),delete f.partialArgs,r.push({type:"toolcall_end",contentIndex:c,toolCall:f,partial:t})}}a(H,"consumeChatStream");function W(e){return e.map(t=>({type:"function",function:{name:t.name,description:t.description,parameters:M(t.parameters),strict:!1}}))}a(W,"toFunctionTools");function M(e){if(Array.isArray(e))return e.map(t=>M(t));if(e&&typeof e=="object"){const t={};for(const[r,n]of Object.entries(e))t[r]=M(n);return t}return e}a(M,"stripSymbolKeys");function Z(e,t){const r=[];for(const n of e){if(n.role==="user"){if(typeof n.content=="string"){r.push({role:"user",content:y(n.content)});continue}const s=n.content.some(i=>i.type==="image"),c=n.content.filter(i=>i.type==="text"||t).map(i=>i.type==="text"?{type:"text",text:y(i.text)}:{type:"image_url",imageUrl:`data:${i.mimeType};base64,${i.data}`});if(c.length>0){r.push({role:"user",content:c});continue}s&&!t&&r.push({role:"user",content:"(image omitted: model does not support images)"});continue}if(n.role==="assistant"){const s=[],c=[];for(const f of n.content){if(f.type==="text"){f.text.trim().length>0&&s.push({type:"text",text:y(f.text)});continue}if(f.type==="thinking"){f.thinking.trim().length>0&&s.push({type:"thinking",thinking:[{type:"text",text:y(f.thinking)}]});continue}c.push({id:f.id,type:"function",function:{name:f.name,arguments:JSON.stringify(f.arguments||{})}})}const i={role:"assistant"};s.length>0&&(i.content=s),c.length>0&&(i.toolCalls=c),(s.length>0||c.length>0)&&r.push(i);continue}const o=[],u=n.content.filter(s=>s.type==="text").map(s=>s.type==="text"?y(s.text):"").join(`
2
+ `),l=n.content.some(s=>s.type==="image"),p=F(u,l,t,n.isError);o.push({type:"text",text:p});for(const s of n.content)t&&s.type==="image"&&o.push({type:"image_url",imageUrl:`data:${s.mimeType};base64,${s.data}`});r.push({role:"tool",toolCallId:n.toolCallId,name:n.toolName,content:o})}return r}a(Z,"toChatMessages");function F(e,t,r,n){const o=e.trim(),u=n?"[tool error] ":"";return o.length>0?`${u}${o}${t&&!r?`
3
+ [tool image omitted: model does not support images]`:""}`:t?r?n?"[tool error] (see attached image)":"(see attached image)":n?"[tool error] (image omitted: model does not support images)":"(image omitted: model does not support images)":n?"[tool error] (no tool output)":"(no tool output)"}a(F,"buildToolResultText");function w(e){return e.id==="mistral-small-2603"||e.id==="mistral-small-latest"||e.id==="mistral-medium-3.5"}a(w,"usesReasoningEffort");function G(e){return e.reasoning&&!w(e)}a(G,"usesPromptModeReasoning");function X(e,t){return e.thinkingLevelMap?.[t]??"high"}a(X,"mapReasoningEffort");function Y(e){if(e)return e==="auto"||e==="none"||e==="any"||e==="required"?e:{type:"function",function:{name:e.function.name}}}a(Y,"mapToolChoice");function Q(e){if(e===null)return"stop";switch(e){case"stop":return"stop";case"length":case"model_length":return"length";case"tool_calls":return"toolUse";case"error":return"error";default:return"stop"}}a(Q,"mapChatStopReason");export{j as streamMistral,ct as streamSimpleMistral};