vern-llm 2.9.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -22,7 +22,7 @@
22
22
 
23
23
  <p align="center">The LLM call framework. Resilience, observability, and control for every call, in your own process.</p>
24
24
 
25
- **Full documentation: [vernllm.dev](https://vernllm.dev)** for installation, structured output, caching, circuit breaker, provider fallback, rate limiting, observability, every adapter, and the complete API reference. This README is a quick reference, not the manual.
25
+ **Full documentation: [vernllm.dev](https://vernllm.dev)** for installation, every adapter, and the complete API reference. This README is a quick reference, not the manual.
26
26
 
27
27
  ## Install
28
28
 
@@ -35,15 +35,18 @@ npm i vern-llm
35
35
  ```ts
36
36
  import Anthropic from '@anthropic-ai/sdk';
37
37
  import OpenAI from 'openai';
38
- import { fromAnthropic, fromOpenAI, VernLLM } from 'vern-llm';
38
+ import { VernLLM } from 'vern-llm';
39
+ import { fromAnthropic, fromOpenAI } from 'vern-llm/adapters';
39
40
 
40
- const openai = fromOpenAI(new OpenAI({ apiKey: process.env.OPENAI_API_KEY }));
41
- const anthropic = fromAnthropic(new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY }));
41
+ const openai = fromOpenAI(new OpenAI({ apiKey: process.env.OPENAI_API_KEY, maxRetries: 0 }));
42
+ const anthropic = fromAnthropic(
43
+ new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY, maxRetries: 0 }),
44
+ );
42
45
 
43
46
  const llm = new VernLLM({
44
47
  client: openai,
45
- model: 'gpt-4o',
46
- fallback: { client: anthropic, model: 'claude-sonnet-5', circuitBreaker: true },
48
+ model: 'gpt-6-sol',
49
+ fallback: { client: anthropic, model: 'claude-sonnet-5-5', circuitBreaker: true },
47
50
  rateLimit: { requestsPerMinute: 500, tokensPerMinute: 100_000, maxConcurrent: 20 },
48
51
  retryBudget: { windowMs: 60_000, minCalls: 20, retryRatio: 0.2 },
49
52
  maxRetries: 3,
@@ -55,28 +58,59 @@ const llm = new VernLLM({
55
58
  const result = await llm.call({ userContent: "What's the weather in New York?" });
56
59
  ```
57
60
 
58
- ## Why vern-llm?
61
+ Pass `maxRetries: 0` to provider SDKs so vern-llm is the only retry authority.
59
62
 
60
- - **Retries with backoff**: transient failures retry automatically; validation errors and non-retryable status codes fail fast instead
61
- - **Provider fallback**: declare an ordered list of backup targets, tried in order after the primary, with no scoring or health-checking, `fallback` on the same constructor
62
- - **Client-side rate limiting**: queue locally against requests-per-minute, tokens-per-minute, and concurrency ceilings instead of letting the provider reject the call
63
- - **Structured output**: pass a Zod schema, get a typed, validated result back
64
- - **Tool calling**: pass `tools`, vern-llm handles retries and validation around them the same as any other call; you run the tools and continue the conversation
65
- - **Streaming**: set `stream: true` on any call and get live chunks alongside the same validated result the call would otherwise resolve to
66
- - **Provider-native JSON Schema mode**: constrain generation itself, not just validate after the fact
67
- - **Caching**: wrap any LLM call with `cachedCall`, bring your own cache adapter
68
- - **Middleware pipeline**: `transform` patches the outgoing request per attempt, `wrap` runs once around the whole logical call regardless of retries or fallback, patches from separate middleware merge instead of clobbering each other, order is controlled by `priority`, and each entry can be conditionally `enabled` per call
69
- - **Circuit breaker**: trips after repeated failures, recovers automatically once the provider's back, independent per fallback target too
70
- - **Observability**: one `onEvent` stream reports retries, fallovers, circuit transitions, and rate-limit waits
71
- - **Usage tracking**: `onUsage` and `onUsageFailure` report token spend on success and on failure, so nothing goes unaccounted for when a call fails after the provider already responded
72
- - **One interface, every provider**: OpenAI, Groq, Mistral, DeepSeek, Cerebras, Together, Fireworks, Ollama, Anthropic, Gemini, Bedrock, or raw HTTP via `fromFetch`
73
- - **Zero runtime dependencies**: `zod` and provider SDKs are not required dependencies; vern-llm relies on compatible interfaces rather than specific implementations.
63
+ ## Resilience
74
64
 
75
- ### Why not a gateway?
65
+ Calls keep working when providers fail, and a failing provider can't take your app down with it.
76
66
 
77
- The customization is something a gateway can't match. vern-llm runs in your process, so you bring your own rate limiter, cache, and middlewares which transform the call instead of picking from a config panel, and hooks like `reserveUsage`, `onEvent` and even more give you superior control over billing and observability.
67
+ - **Retries**: full jitter backoff that honors `Retry-After` up to your cap. Validation and caller errors fail fast
68
+ - **Retry budget**: caps retries at a share of each target's traffic, so an outage can't turn into a retry storm
69
+ - **Circuit breaker per target**: consecutive, rolling, or custom tripping, with half open trials and a success ratio for recovery. Caller errors never open it
70
+ - **Soft failures**: an empty body, JSON cut off at `max_tokens`, a stream that fails before its first chunk, or anything `detectSoftFailure` flags counts as a failure, even behind a 200
71
+ - **Ordered fallback**: each target gets its own retries, breaker, limiter, and budget. When every target is open, the call fails fast with `FallbackExhaustedError`
72
+ - **Client side rate limiting**: requests, tokens, and concurrency per target, with a wait queue that adapts after or ahead of a 429
73
+ - **Timeouts**: per attempt, whole call via `deadlineMs`, stream idle, and reader stall
74
+ - **Caching**: `cachedCall` shares one provider call across concurrent misses, treats a failing cache as a miss, and never caches a failed call
78
75
 
79
- See the [docs](https://vernllm.dev) for adapter setup, caching, the circuit breaker, provider fallback, rate limiting, and structured output in depth.
76
+ ## Observability
77
+
78
+ Every retry, fallback, wait, and breaker change is reported, tied to the call and the tenant that caused it.
79
+
80
+ - **One event stream**: `onEvent` reports retries, fallbacks, breaker transitions, rate limit waits, usage, and middleware events from `ctx.emit`
81
+ - **Usage on success and failure**: `onUsage` and `onUsageFailure`, with prompt cache reads and writes split out
82
+ - **Typed errors**: every `LLMError` carries a code and each attempt with its request snapshot, auth headers stripped
83
+ - **Live health state**: `getCircuitStates()`, `getFailureBreakdown()`, `getRetryBudgetState()`, and `readRateLimitState()`
84
+ - **OpenTelemetry**: [`vern-llm-otel`](https://www.npmjs.com/package/vern-llm-otel) turns events into GenAI traces and metrics in your own setup
85
+
86
+ ## Control
87
+
88
+ Your code decides which providers a call may use, in what order, and when to give up.
89
+
90
+ - **Per call targets**: `targets: ['bedrock', 'primary']` picks the providers and order for one call
91
+ - **Middleware**: `transform` patches each attempt, `wrap` runs once around the whole call, and `dispatch` sees the final request. Order it with `priority`, `runsAfter`, and `runsBefore`
92
+ - **Policy that only narrows**: a `wrap` can drop or reorder targets through `next({ targets })`, and an inner one can never add back what an outer one removed
93
+ - **Fallback decisions**: `fallbackOn` sees the error, the failed target, and the next one
94
+ - **Call scoped data**: `context` reaches every hook, event, and usage report
95
+ - **Manual breakers**: `openCircuit()` and `closeCircuit()` per target
96
+ - **No surprises**: vern-llm never reorders targets on its own, and bad config throws at construction
97
+
98
+ ## Also included
99
+
100
+ - **Structured output** with any validator or provider native JSON Schema mode
101
+ - **Tool calling** with typed calls. You run the tools and continue the conversation
102
+ - **Streaming** with `stream: true`, returning live chunks and the same validated result
103
+ - **Adapters** for OpenAI compatible providers, Anthropic, Gemini, Bedrock (via `vern-llm-bedrock`), and raw HTTP via `fromFetch`
104
+ - **Shared state across processes** for the breaker, rate limits, and cache via `vern-llm-redis`
105
+ - **Zero runtime dependencies**. `zod` and provider SDKs are optional
106
+
107
+ ## Why not a gateway?
108
+
109
+ A gateway sees an HTTP request and response. vern-llm sees the call: the schema the answer must pass, the tenant it belongs to, and which providers it may use. So it judges the answer instead of the status code, tells your fault from the provider's, and adds no network hop, no server, and no third party in the path of your prompts.
110
+
111
+ It is not a gateway, dashboard, key manager, pricing table, or agent framework, and it never executes tools for you. It works alongside one: point an OpenAI compatible adapter at LiteLLM, Portkey, or `fromVercelAIGateway`, and pick one retry owner.
112
+
113
+ See [Why VernLLM](https://vernllm.dev/docs/why) for the full comparison with the AI SDK, LiteLLM, and Portkey.
80
114
 
81
115
  ## License
82
116
 
@@ -0,0 +1,12 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../responseBody.utils-CknznUJA.cjs");async function t(e){let{data:t,response:n}=await e.withResponse();return{data:t,headers:n.headers}}function n(e){return e.remainingRequests!==void 0||e.limitRequests!==void 0?{type:`rate_limit_hint`,hint:e}:void 0}async function r(e,n){return n?t(e()):{data:await e()}}const i={minimal:1024,low:4096,medium:16e3,high:32e3};function a(t){if(!t)return i;let n={...i,...t};if(!(n.minimal<n.low&&n.low<n.medium&&n.medium<n.high))throw new e.s(`reasoningEffortTokens must keep tiers in strictly ascending order (minimal < low < medium < high), got ${JSON.stringify(n)}. An out-of-order override doesn't just misrank tiers, it can make some of them unreachable.`,`invalid_params`);return n}function o(e,t=i){return t[e]}function s(e,t=i){return e<=t.minimal?`minimal`:e<=t.low?`low`:e<=t.medium?`medium`:`high`}function c(e){let t=/opus-(\d+)(?:-(\d+))?/.exec(e);if(!t)return null;let n=t[2],r=n===void 0||n.length>=8?0:Number(n);return[Number(t[1]),r]}function l(e){let t=c(e);if(t){let[e,n]=t;return e>4||e===4&&n>=7}return[`sonnet-5`,`fable-5`,`mythos`].some(t=>e.includes(t))}function u(e,t){return l(e)?!0:t?Array.isArray(t)?t.includes(e):t(e):!1}function d(e,t){return!u(e,t)}function f(t,n){if(t<1024)throw new e.s(`budgetTokens (${t}) is below Anthropic's minimum of 1024. Raise budgetTokens, or use a reasoningEffort tier of 'low' or above with the default conversion table.`,`invalid_params`);if(t>=n)throw new e.s(`budgetTokens (${t}) must be less than maxTokens (${n}); the thinking budget and the reply share the same max_tokens ceiling on Anthropic. Raise maxTokens, or lower budgetTokens/reasoningEffort.`,`invalid_params`)}function p(t){if(t)throw new e.s(`budgetTokens/reasoningEffort was set alongside ${t}. Anthropic rejects thinking combined with a tool_choice that forces tool use, the model has to be able to reply with plain text for thinking to run. Use toolChoice: 'auto' (or omit toolChoice) for this call, or drop budgetTokens/reasoningEffort for it.`,`invalid_params`)}function m(e){return e===`minimal`?`low`:e}function h(e,t){return te(t,e.toUpperCase())}function ee(e){let t=/gemini-\d+\.(\d+)/.exec(e);return t?Number(t[1]):0}function te(e,t){if(!e.includes(`pro`))return t;let n=g(e);return n===null||n<3?t:ee(e)===0?t===`HIGH`?`HIGH`:`LOW`:t===`MINIMAL`?`LOW`:t}function g(e){let t=/gemini-(\d+)/.exec(e);return t?Number(t[1]):null}function _(e){let t=g(e);return t!==null&&t>=3}function ne(e,t){return _(e)?!0:t?Array.isArray(t)?t.includes(e):t(e):!1}const v=new Set;function y(e,t,n){return r=>{if(v.has(e))return;let i=t();i!==void 0&&i>0&&(v.add(e),r.warn(`[VernLLM] ${e}: the SDK client retries up to ${i} times on its own, hidden from VernLLM's retries, circuit breaker, rate limiter, and events. ${n} so VernLLM is the only retry owner.`))}}function b(e){let t=e?.maxRetries;return typeof t==`number`?t:void 0}function x(t,n){return new e.s(t,`invalid_params`,{code:`unsupported_capability`,issues:{capability:n}})}function S(t,n,r){let i=e.t(`${t} (${n.status})`,r);return i.status=n.status,i.headers=n.headers,i}function re(e){let t=/claude-([a-z]+)-(\d+)(?:[-.](\d+))?/i.exec(e),n=t??/claude-(\d+)(?:[-.](\d+))?/i.exec(e);if(!n)return null;let[,r,i,a]=t?n:[n[0],void 0,n[1],n[2]],o=a===void 0||a.length>=8?0:Number(a);return{family:r?.toLowerCase(),major:Number(i),minor:o}}function C(e,t,n,r){return e>n||e===n&&t>=r}function w(e){let t=re(e);if(!t)return!1;let{family:n,major:r,minor:i}=t;return r>=6?!0:n===`fable`?C(r,i,5,1):n===`opus`&&C(r,i,5,5)}function T(e,t){return t?Array.isArray(t)?t.includes(e):t(e):w(e)}function E(e,t,n,r){if(n&&n!==`auto`&&n!==`none`&&T(t,r))throw x(`${e} model "${t}" rejects a tool_choice that forces tool use, so ${n===`required`?`toolChoice: 'required'`:`toolChoice: { name: '${n.function.name}' }`} can't be sent. Use toolChoice: 'auto' and ask for the tool in the prompt instead. If this model does accept it, list the models that reject it in forcedToolChoiceUnsupportedModels.`,`forced_tool_choice`)}function D(e,t){return t?Array.isArray(t)?t.includes(e):t(e):!1}function ie(t,n,r,i){let a=n.response_format?.type===`json_schema`?n.response_format.json_schema:void 0,o=a?.name.trim();if(a&&!o)throw new e.s(`json_schema.name must not be empty.`,`validation`);let s=T(n.model,r.forcedToolChoiceUnsupportedModels);n.tools?.length&&E(t,n.model,n.tool_choice,r.forcedToolChoiceUnsupportedModels);let c=!!a&&(s||D(n.model,r.nativeStructuredOutputModels));if(a&&n.tools?.length&&!c)throw x(i.toolsWithJsonSchema(n.model),`tools_with_json_schema`);if(n.response_format?.type===`json_object`)throw new e.s(i.jsonObject,`validation`);return!a||!o?{mode:`none`}:{mode:c?`native`:`forcedTool`,jsonSchema:a,schemaName:o}}function ae(e,t,n){if(e.budget_tokens!==void 0||e.reasoning_effort!==void 0){if(p(t),d(e.model,n.adaptiveOnlyModels)){let t=e.budget_tokens??o(e.reasoning_effort,n.effortTokenTable);return f(t,e.max_tokens),{thinking:{type:`enabled`,budget_tokens:t}}}return{thinking:{type:`adaptive`},effort:m(e.reasoning_effort??s(e.budget_tokens,n.effortTokenTable))}}}const O=[`image/png`,`image/jpeg`,`image/gif`,`image/webp`];function k(t){if(O.includes(t))return t;throw new e.s(`Unsupported image mimeType "${t}": expected one of ${O.join(`, `)}`,`invalid_params`)}function oe(e){return e.map(e=>e.type===`image`?{type:`image`,source:{type:`base64`,media_type:k(e.mimeType),data:e.data}}:{type:`text`,text:e.text})}function A(t,n){if(t.type!==`object`)throw new e.s(`Tool "${n}"'s schema must have "type": "object" (Anthropic requires object-shaped tool parameters).`,`validation`);return t}function se(e){let t=e||`auto`;switch(t){case`auto`:return{type:`auto`};case`none`:return{type:`none`};case`required`:return{type:`any`};default:return{type:`tool`,name:t.function.name}}}function ce(e,t){return{tools:e.map(e=>({name:e.function.name,description:e.function.description,input_schema:A(e.function.parameters,e.function.name)})),toolChoice:se(t)}}const le={toolsWithJsonSchema:e=>`Anthropic model "${e}" is not covered by nativeStructuredOutputModels, so \`jsonSchema\` is emulated as a forced single tool call there, which collides with the \`tools\` you also provided. Either drop \`tools\` or \`jsonSchema\` for this call, or pass this model in fromAnthropic's \`nativeStructuredOutputModels\` option once you've confirmed it supports Anthropic's \`output_config.format\`.`,jsonObject:'response_format: "json_object" is not supported on Anthropic. Unlike OpenAI, Anthropic has no API-level field that mechanically guarantees valid JSON output for this mode, so it used to be emulated by injecting a "respond with JSON only" instruction into the system prompt, a guarantee this adapter can no longer make. Use `jsonSchema` instead, which maps to a real API-level constraint (Anthropic\'s native output_config.format on covered models, or a forced single tool call otherwise).'};function ue(e){if(e?.type===`tool`)return`toolChoice forcing the "${e.name}" tool`;if(e?.type===`any`)return`toolChoice: 'required' (Anthropic's "any" tool_choice)`}function de(e,t,n,r,i){let a=e.messages.find(e=>e.role===`system`),o=e.messages.filter(e=>e.role===`user`||e.role===`assistant`||e.role===`tool`),s=ie(`Anthropic`,e,{nativeStructuredOutputModels:t,forcedToolChoiceUnsupportedModels:i},le),c,l,u,d;if(s.mode===`forcedTool`){let{schema:e,description:t,strict:n}=s.jsonSchema;c=s.schemaName,u=[{name:c,description:t,input_schema:A(e,c),strict:n}],d={type:`tool`,name:c}}else s.mode===`native`&&(l={type:`json_schema`,schema:s.jsonSchema.schema}),e.tools?.length&&({tools:u,toolChoice:d}=ce(e.tools,e.tool_choice));let f=ae(e,ue(d),{adaptiveOnlyModels:r,effortTokenTable:n}),p=f?.effort,m=a?.content,h=f?void 0:e.temperature;return{body:{model:e.model,max_tokens:e.max_tokens,...h===void 0?{}:{temperature:h},system:m||void 0,messages:fe(o.map(e=>pe(e))),...u?{tools:u,tool_choice:d}:{},...l||p?{output_config:{...l?{format:l}:{},...p?{effort:p}:{}}}:{},...f?{thinking:f.thinking}:{}},toolName:c}}function fe(e){let t=e=>e.role===`user`&&Array.isArray(e.content)&&e.content.length>0&&e.content.every(e=>e.type===`tool_result`),n=[];for(let r of e){let e=n.at(-1);t(r)&&e&&t(e)?e.content.push(...r.content):n.push(r)}return n}function pe(t){if(t.role===`tool`)return{role:`user`,content:[{type:`tool_result`,tool_use_id:t.tool_call_id,content:t.content,...t.is_error?{is_error:!0}:{}}]};if(t.role===`assistant`&&(t.tool_calls?.length||t.thinking?.length)){let n=(t.thinking??[]).map(e=>e.type===`thinking`?{type:`thinking`,thinking:e.thinking,signature:e.signature}:{type:`redacted_thinking`,data:e.data});t.content&&n.push({type:`text`,text:t.content});for(let r of t.tool_calls??[]){let t;try{t=r.function.arguments.trim()?JSON.parse(r.function.arguments):{}}catch(t){throw new e.s(`Assistant tool call "${r.function.name}" (${r.id}) has arguments that are not valid JSON.`,`validation`,{cause:t})}if(t===null||Array.isArray(t)||typeof t!=`object`)throw new e.s(`Assistant tool call "${r.function.name}" (${r.id}) arguments must be a JSON object.`,`validation`);n.push({type:`tool_use`,id:r.id,name:r.function.name,input:t})}return{role:`assistant`,content:n}}return{role:t.role,content:Array.isArray(t.content)?oe(t.content):t.content??``}}function j(e,t){return e===t?{finish_reason:`length`}:{}}function M(t,n){throw new e.s(`${t} did not return the required structured output tool "${n}".`,`validation`)}function N(t,n,r){if(!r||typeof r!=`object`||Array.isArray(r))throw new e.s(`${t} returned invalid structured output for tool "${n}". Expected an object.`,`validation`)}const P=e=>typeof e==`number`&&Number.isFinite(e)?e:0;function F(e){let t=[e?.input_tokens,e?.cache_creation_input_tokens,e?.cache_read_input_tokens];if(!t.every(e=>e==null))return t.reduce((e,t)=>e+P(t),0)}function I(e){if(!e)return;let t=e.cache_creation?{"5m":P(e.cache_creation.ephemeral_5m_input_tokens),"1h":P(e.cache_creation.ephemeral_1h_input_tokens)}:void 0;return{cached_tokens:e.cache_read_input_tokens??void 0,cache_write_tokens:e.cache_creation_input_tokens??void 0,...t?{cache_write_tokens_by_ttl:t}:{}}}function L(e){return e.flatMap(e=>e.type===`thinking`?[{type:`thinking`,thinking:e.thinking??``,signature:e.signature??``}]:e.type===`redacted_thinking`?[{type:`redacted_thinking`,data:e.data??``}]:[])}function R(e,t){let n,r,i=L(e.content);if(t){let r=e.content.find(e=>e.type===`tool_use`&&e.name===t);r||M(`Anthropic`,t),N(`Anthropic`,t,r.input),n=JSON.stringify(r.input)}else{n=e.content.filter(e=>e.type===`text`).map(e=>e.text??``).join(``);let t=e.content.filter(e=>e.type===`tool_use`);t.length&&(r=t.map(e=>({id:e.id,type:`function`,function:{name:e.name,arguments:JSON.stringify(e.input??{})}})))}return{choices:[{message:{content:n,...r?{tool_calls:r}:{},...i.length?{thinking:i}:{}},...j(e.stop_reason,`max_tokens`)}],usage:{prompt_tokens:F(e.usage),completion_tokens:e.usage?.output_tokens,total_tokens:(F(e.usage)??0)+(e.usage?.output_tokens??0),prompt_tokens_details:I(e.usage),...e.usage?.output_tokens_details?.thinking_tokens===void 0?{}:{completion_tokens_details:{reasoning_tokens:e.usage.output_tokens_details.thinking_tokens}}}}}function*z(e,t){let n=t.content_block;switch(n.type){case`tool_use`:{let r=n.name===e.toolName?`json-tool`:`tool_use`;e.blockKinds.set(t.index,r),r===`json-tool`?e.sawJsonTool=!0:e.toolName||(yield{type:`tool_call_delta`,index:t.index,id:n.id,name:n.name});return}case`thinking`:e.thinkingBlocks.set(t.index,{type:`thinking`,thinking:n.thinking??``,signature:n.signature??``});return;case`redacted_thinking`:e.thinkingBlocks.set(t.index,{type:`redacted_thinking`,data:n.data??``});return;default:e.blockKinds.set(t.index,`text`)}}function*B(e,t){let{delta:n}=t;switch(n.type){case`text_delta`:e.toolName||(yield{type:`text-delta`,delta:n.text});return;case`thinking_delta`:{let r=e.thinkingBlocks.get(t.index);r?.type===`thinking`&&(r.thinking+=n.thinking),yield{type:`ping`};return}case`signature_delta`:{let r=e.thinkingBlocks.get(t.index);r?.type===`thinking`&&(r.signature+=n.signature),yield{type:`ping`};return}case`input_json_delta`:e.blockKinds.get(t.index)===`json-tool`?yield{type:`text-delta`,delta:n.partial_json}:e.toolName||(yield{type:`tool_call_delta`,index:t.index,argumentsDelta:n.partial_json})}}function*me(e,t){let n=e.thinkingBlocks.get(t.index);n&&(e.thinkingBlocks.delete(t.index),yield{type:`thinking_block`,block:n})}const he=[`input_tokens`,`cache_creation_input_tokens`,`cache_read_input_tokens`];function ge(e,t){let n={...e};for(let e of he){let r=t?.[e];r!=null&&(n[e]=r)}return n}function _e(e,t){let n=ge(e.startUsage,t.usage),r=F(n)??0,i=t.usage?.output_tokens??0,a=t.usage?.output_tokens_details?.thinking_tokens;return{type:`usage`,usage:{prompt_tokens:r,completion_tokens:i,total_tokens:r+i,prompt_tokens_details:I(n),...a===void 0?{}:{completion_tokens_details:{reasoning_tokens:a}}}}}async function*ve(e,t){let n={toolName:t,blockKinds:new Map,thinkingBlocks:new Map,startUsage:void 0,sawJsonTool:!1};for await(let t of e)switch(t.type){case`message_start`:n.startUsage=t.message.usage;break;case`content_block_start`:yield*z(n,t);break;case`content_block_delta`:yield*B(n,t);break;case`content_block_stop`:yield*me(n,t);break;case`message_delta`:yield _e(n,t);break;case`ping`:yield{type:`ping`}}t&&!n.sawJsonTool&&M(`Anthropic`,t)}function ye(t,i){let o=a(i?.reasoningEffortTokens),s=i?.supportsWithResponse??!1,c=y(`anthropic`,()=>b(t),`Pass maxRetries: 0 to the client`),l=e=>de(e,i?.nativeStructuredOutputModels,o,i?.adaptiveOnlyModels,i?.forcedToolChoiceUnsupportedModels),u=(e,n)=>r(()=>t.messages.create(e,n),s);return{supportsJsonObjectMode:!1,cacheReadsCountTowardRateLimit:!1,adapter:{name:`anthropic`,provider:`anthropic`},setLogger:c,chat:{completions:{async create(t,n){let{body:r,toolName:i}=l(t),{data:a,headers:o}=await u(r,n),s=R(a,i);return o&&e.r(s,e.i(o)),s},async*createStream(t,r){let{body:i,toolName:a}=l(t),{data:o,headers:s}=await u({...i,stream:!0},r);if(s){let t=n(e.i(s));t&&(yield t)}yield*ve(o,a)}}}}}function be(e){return e.map(e=>e.type===`image`?{inlineData:{mimeType:k(e.mimeType),data:e.data}}:{text:e.text})}function xe(e){let t=e||`auto`;switch(t){case`auto`:return{functionCallingConfig:{mode:`AUTO`}};case`none`:return{functionCallingConfig:{mode:`NONE`}};case`required`:return{functionCallingConfig:{mode:`ANY`}};default:return{functionCallingConfig:{mode:`ANY`,allowedFunctionNames:[t.function.name]}}}}function Se(e){let t=new Map;for(let n of e)if(n.role===`assistant`)for(let e of n.tool_calls??[])t.set(e.id,e.function.name);return t}function Ce(e,t){if(e.role===`tool`)return{role:`user`,parts:[{functionResponse:{id:e.tool_call_id,name:t.get(e.tool_call_id)??e.tool_call_id,response:Te(e.content)}}]};if(e.role===`assistant`&&e.tool_calls?.length){let t=[];return typeof e.content==`string`&&e.content&&t.push({text:e.content}),t.push(...e.tool_calls.map(e=>({functionCall:{id:e.id,name:e.function.name,args:we(e.function.arguments,e.function.name)}}))),{role:`model`,parts:t}}return{role:e.role===`assistant`?`model`:`user`,parts:Array.isArray(e.content)?be(e.content):[{text:e.content??``}]}}function we(t,n){let r;try{r=t.trim()?JSON.parse(t):{}}catch(t){throw new e.s(`Tool call "${n}" arguments are not valid JSON.`,`parse`,{cause:t,code:`tool_arguments_parse_failed`})}if(!r||Array.isArray(r)||typeof r!=`object`)throw new e.s(`Tool call "${n}" arguments must be a JSON object.`,`validation`);return r}function Te(e){let t;try{t=e.trim()?JSON.parse(e):``}catch{t=e}return t&&!Array.isArray(t)&&typeof t==`object`?t:{output:t}}function Ee(e){let t=e=>e.role===`user`&&e.parts.length>0&&e.parts.every(e=>`functionResponse`in e),n=[];for(let r of e){let e=n.at(-1);t(r)&&e&&t(e)?e.parts.push(...r.parts):n.push(r)}return n}function De(e,t,n){if(ne(e.model,n)){let n=e.reasoning_effort??(e.budget_tokens===void 0?void 0:s(e.budget_tokens,t));return n===void 0?void 0:{thinkingLevel:h(n,e.model)}}let r=e.budget_tokens??(e.reasoning_effort?o(e.reasoning_effort,t):void 0);return r===void 0?void 0:{thinkingBudget:r}}function V(e,t,n){let r=e.messages.find(e=>e.role===`system`),i=e.messages.filter(e=>e.role===`user`||e.role===`assistant`||e.role===`tool`),a=!!e.response_format,o={...e.temperature===void 0?{}:{temperature:e.temperature},maxOutputTokens:e.max_tokens,...r?{systemInstruction:{parts:[{text:r.content}]}}:{}};if(a&&(o.responseMimeType=`application/json`),e.response_format?.type===`json_schema`){let{schema:t,description:n}=e.response_format.json_schema;o.responseSchema={...t,...n?{description:n}:{}}}e.tools?.length&&(o.tools=[{functionDeclarations:e.tools.map(e=>({name:e.function.name,description:e.function.description,parameters:e.function.parameters}))}],o.toolConfig=xe(e.tool_choice));let s=De(e,t,n);s&&(o.thinkingConfig=s);let c=Se(i);return{model:e.model,contents:Ee(i.map(e=>Ce(e,c))),config:o}}function H(e,t){return`${e}#${t}`}function U(e){return{prompt_tokens:e?.promptTokenCount,completion_tokens:e?.candidatesTokenCount,total_tokens:e?.totalTokenCount,prompt_tokens_details:{cached_tokens:e?.cachedContentTokenCount},...e?.thoughtsTokenCount===void 0?{}:{completion_tokens_details:{reasoning_tokens:e.thoughtsTokenCount}}}}function Oe(e){let t=e.candidates?.[0]?.content?.parts??[],n=t.map(e=>e.text??``).join(``),r=t.filter(e=>e.functionCall),i;if(r.length){let e=new Map;i=r.map(t=>{let n=t.functionCall.name,r=t.functionCall.id,i=e.get(n)??0;return e.set(n,i+1),{id:r??H(n,i),type:`function`,function:{name:n,arguments:JSON.stringify(t.functionCall.args??{})}}})}return{choices:[{message:{content:n,...i?{tool_calls:i}:{}},...j(e.candidates?.[0]?.finishReason,`MAX_TOKENS`)}],usage:U(e.usageMetadata)}}async function*ke(e){let t=0,n=new Map,r;for await(let i of e){let e=i.candidates?.[0]?.content?.parts??[];for(let r of e)if(r.text&&(yield{type:`text-delta`,delta:r.text}),r.functionCall){let e=r.functionCall.name,i=r.functionCall.id,a=e?n.get(e)??0:0;e&&n.set(e,a+1),yield{type:`tool_call_delta`,index:t,id:i??(e?H(e,a):void 0),name:r.functionCall.name,argumentsDelta:JSON.stringify(r.functionCall.args??{}),complete:!0},t++}i.usageMetadata&&(r=i.usageMetadata)}r&&(yield{type:`usage`,usage:U(r)})}function Ae(e){return e.vertexai===!0?{provider:`gcp.vertex_ai`}:e.vertexai===!1?{provider:`gcp.gemini`}:{}}function je(e){let t=e.httpOptions?.retryOptions;if(t&&typeof t==`object`)return Math.max(1,Number(t.attempts??5))-1}function Me(e,t){let n=a(t?.reasoningEffortTokens),r=t?.thinkingLevelModels,i=e.models;if(!i&&typeof e.generateContent==`function`)throw x(`fromGemini takes the top level client: pass ai (new GoogleGenAI(...)), not ai.models.`,`top_level_client`);if(typeof i?.generateContent!=`function`)throw x(`fromGemini requires a client with models.generateContent: pass ai (new GoogleGenAI(...)).`,`generateContent`);let o=y(`gemini`,()=>je(e),`Remove httpOptions.retryOptions from the client, or set its attempts to 1,`),s=i.generateContent.bind(i),c=typeof i.generateContentStream==`function`?i.generateContentStream.bind(i):void 0;return{adapter:{name:`gemini`,...Ae(e)},setLogger:o,chat:{completions:{async create(e,t){let i=V(e,n,r);return i.config={...i.config,abortSignal:t.signal},Oe(await s(i))},async*createStream(e,t){if(!c)throw x(`stream: true requires a Gemini client with generateContentStream`,`generateContentStream`);let i=V(e,n,r);i.config={...i.config,abortSignal:t.signal},yield*ke(await c(i))}}}}}async function*W(t){let n=new TextDecoder(`utf-8`,{fatal:!0}),r=Ne();for await(let i of t){let t;try{t=typeof i==`string`?i:n.decode(i,{stream:!0})}catch(t){throw new e.s(`Invalid UTF-8 in SSE stream`,`parse`,{cause:t})}for(let e of r.push(t)){let t=J(e);if(t===G)return;t!==K&&(yield t)}}let i;try{i=n.decode()}catch(t){throw new e.s(`Invalid UTF-8 in SSE stream`,`parse`,{cause:t})}let{frames:a,trailing:o}=r.end(i);for(let e of a){let t=J(e);if(t===G)return;t!==K&&(yield t)}let s=o.trim();if(s){let e=J(s);e!==G&&e!==K&&(yield e)}}function Ne(){let e=[],t=!1,n=!1;function r(r){let i=n?`\r${r}`:r;n=i.endsWith(`\r`),n&&(i=i.slice(0,-1)),i=i.replace(/\r\n?/g,`
2
+ `);let a=[],o=0;t&&i.startsWith(`
3
+ `)&&(a.push(e.join(``).slice(0,-1)),e=[],t=!1,o=1);let s=i.indexOf(`
4
+
5
+ `,o);for(;s!==-1;)e.push(i.slice(o,s)),a.push(e.join(``)),e=[],o=s+2,s=i.indexOf(`
6
+
7
+ `,o);let c=i.slice(o);return c?(e.push(c),t=c.endsWith(`
8
+ `)):o>0&&(t=!1),a}return{push:r,end(t){let i=r(t);return n&&(n=!1,i.push(...r(`
9
+ `))),{frames:i,trailing:e.join(``)}}}}const G=Symbol(`sse-stream-done`),K=Symbol(`sse-frame-no-data`),q=Symbol(`sse-frame-ping`);function J(t){let n=[],r=!1;for(let e of t.split(`
10
+ `)){if(e.startsWith(`:`)){r=!0;continue}e.startsWith(`data:`)&&n.push(e.startsWith(`data: `)?e.slice(6):e.slice(5))}if(!n.length)return r?q:K;let i=n.join(`
11
+ `);if(i===`[DONE]`)return G;try{return JSON.parse(i)}catch(t){throw new e.s(`Invalid JSON in SSE frame: ${i.slice(0,200)}`,`parse`,{cause:t,code:`stream_frame_invalid`})}}function Pe(e){return e.cacheReadTokens!==void 0||e.cacheWriteTokens!==void 0||e.cacheWriteTokensByTtl!==void 0}function Fe(e){let{content:t,usage:n,toolCalls:r}=e,i=r?.length?r.map(e=>({id:e.id,type:`function`,function:{name:e.name,arguments:e.arguments}})):void 0;return{choices:[{message:{content:t,...i?{tool_calls:i}:{}}}],usage:n?{prompt_tokens:n.promptTokens,completion_tokens:n.completionTokens,total_tokens:n.totalTokens,...Pe(n)?{prompt_tokens_details:{cached_tokens:n.cacheReadTokens,cache_write_tokens:n.cacheWriteTokens,cache_write_tokens_by_ttl:n.cacheWriteTokensByTtl}}:{}}:void 0}}async function*Ie(e,t){for await(let n of e){if(n===q){yield{type:`ping`};continue}let e=t(n);e&&(Array.isArray(e)?yield*e:yield e)}}async function*Le(e){let t=e.getReader();try{for(;;){let{done:e,value:n}=await t.read();if(e)return;n&&(yield n)}}finally{try{await t.cancel()}catch{}t.releaseLock()}}async function Re(e,t){let n=await fetch(e,t);if(!n.ok)throw S(`Fetch adapter stream request failed`,n,await n.text().catch(()=>``));if(!n.body)throw Error(`Fetch adapter stream request received a response with no body.`);return{headers:n.headers,body:Le(n.body)}}async function Y(e,t,n){let r=typeof e.url==`function`?e.url(t):e.url,i=typeof e.headers==`function`?await e.headers():e.headers,a=e.method??`POST`,o=![`GET`,`HEAD`].includes(a.toUpperCase());return{url:r,method:a,headers:o?{"Content-Type":`application/json`,...i}:{...i},...o?{body:JSON.stringify(n)}:{}}}async function ze(e,t,n){let{url:r,method:i,headers:a,body:o}=await Y(e,t,e.mapRequest(t)),s=await(e.request??fetch)(r,{method:i,headers:a,body:o,signal:n});if(!s.ok)throw S(`Fetch adapter request failed`,s,await s.text().catch(()=>``));return s}async function Be(e,t,n){if(e.request&&!e.requestStream)throw x("`stream: true` requires `requestStream` to be configured on fromFetch when a custom `request` transport is set. `requestStream` does not fall back to `request` (it needs an async-iterable byte stream, which `RequestLike`'s buffered `ResponseLike` has no way to provide), without it, `stream: true` would silently use plain native `fetch` instead of your configured transport. Add a `requestStream` that opens the same connection your `request` does, or omit `request` if native `fetch` is fine for both.",`requestStream`);let{url:r,method:i,headers:a,body:o}=await Y(e,t,e.mapRequest(t)),s={method:i,headers:a,body:o,signal:n};return e.requestStream?{body:await e.requestStream(r,s)}:Re(r,s)}function X(t,n){if(n&&typeof n.get==`function`)return(t.parseRateLimitHint??e.a)(n)}function Ve(t){return{adapter:{name:`fetch`,...typeof t.provider==`string`&&t.provider.trim()!==``?{provider:t.provider}:{}},chat:{completions:{async create(n,r){let i=await ze(t,n,r.signal),a=Fe(t.mapResponse(await i.json()));return e.r(a,X(t,i.headers)),a},async*createStream(e,r){let{mapStreamEvent:i}=t;if(!i)throw x(`stream: true requires mapStreamEvent to be configured on fromFetch`,`mapStreamEvent`);let a=t.parseStreamFrames??W,o=await Be(t,e,r.signal),s=X(t,o.headers),c=s&&n(s);c&&(yield c),yield*Ie(a(o.body),i)}}}}}const He=[[/^api\.openai\.com$/,`openai`],[/\.openai\.azure\.com$/,`azure.ai.openai`],[/^api\.groq\.com$/,`groq`],[/^api\.mistral\.ai$/,`mistral_ai`],[/^api\.deepseek\.com$/,`deepseek`],[/^api\.x\.ai$/,`x_ai`],[/^api\.perplexity\.ai$/,`perplexity`]];function Ue(e,t){if(typeof t==`string`&&t.trim()!==``)return t;let n=e.baseURL;if(typeof n!=`string`)return;let r;try{r=new URL(n).hostname.toLowerCase()}catch{return}return He.find(([e])=>e.test(r))?.[1]}function We(e){if(/-chat/.test(e))return!1;let t=/^gpt-(\d+)/.exec(e)?.[1];return t!==void 0&&Number(t)>=6}function Ge(e,t){return t?Array.isArray(t)?t.includes(e):t(e):We(e)}function Ke(e,t){if(!e.tools?.length||!Ge(e.model,t))return!1;if(e.reasoning_effort!==void 0||e.budget_tokens!==void 0)throw x(`OpenAI model "${e.model}" only accepts tools on Chat Completions with reasoning_effort "none", but this call asks for reasoning through reasoningEffort or budgetTokens (an instance default counts). Pass reasoningEffort: null and budgetTokens: null for this call, or use the Responses API for reasoning with tools.`,`tools_with_reasoning`);return!0}function qe(e,t,n){return t?(n?.debug(`[VernLLM] ${e.model}: sending reasoning_effort "none", required for tools on Chat Completions`),{...e,reasoning_effort:`none`}):e}function Je(e,t){if(e.budget_tokens===void 0)return e;let{budget_tokens:n,...r}=e;return r.reasoning_effort===void 0?{...r,reasoning_effort:s(n,t)}:r}function Ye(e){if(/-chat/.test(e))return!1;if(/^o\d/.test(e))return!0;let t=/^gpt-(\d+)/.exec(e)?.[1];return t!==void 0&&Number(t)>=5}function Xe(e){if(!Ye(e.model))return e;let{max_tokens:t,temperature:n,...r}=e;return{...r,max_completion_tokens:t}}function Ze(e){return e.map(e=>e.type===`image`?{type:`image_url`,image_url:{url:`data:${k(e.mimeType)};base64,${e.data}`}}:{type:`text`,text:e.text})}function Qe(e){return e.messages.map(e=>{if(e.role===`user`&&Array.isArray(e.content))return{...e,content:Ze(e.content)};if(e.role===`tool`){let{is_error:t,...n}=e;return t?{...n,content:`Error: ${n.content}`}:n}if(e.role===`assistant`&&e.thinking){let{thinking:t,...n}=e;return n}return e})}function $e(e,t){return t?.type===`json_object`?e.some(e=>{let t=e.content;return(Array.isArray(t)?t:[t]).some(e=>{let t=typeof e==`string`?e:e?.text;return typeof t==`string`&&/json/i.test(t)})})?e:[{role:`system`,content:`Respond with a valid JSON object.`},...e]:e}function Z(e){let t=e.prompt_tokens_details?.cached_tokens??e.prompt_cache_hit_tokens;return t===void 0?e:{...e,prompt_tokens_details:{...e.prompt_tokens_details,cached_tokens:t}}}function*et(e){let t=e.choices?.[0]?.delta;if(t?.content&&(yield{type:`text-delta`,delta:t.content}),t?.tool_calls?.length)for(let e of t.tool_calls)yield{type:`tool_call_delta`,index:e.index,id:e.id,name:e.function?.name,argumentsDelta:e.function?.arguments};e.usage&&(yield{type:`usage`,usage:Z(e.usage)})}function Q(t,i={}){let o=t,{supportsStreamUsage:s=!0,supportsWithResponse:c=!1}=i,l=a(i.reasoningEffortTokens),u=Ue(t,i.provider),d,f=y(`openai-compatible`,()=>b(t),`Pass maxRetries: 0 to the client`),p=(e,t={})=>{let n=Ke(e,i.noReasoningToolModels),r=$e(Qe(e),e.response_format);return qe(Xe(Je({...e,messages:r,...t},l)),n,d)},m=(e,t)=>r(()=>o.chat.completions.create(e,t),c);return{adapter:{name:`openai-compatible`,...u?{provider:u}:{}},setLogger(e){d=e,f(e)},chat:{completions:{async create(t,n){let{data:r,headers:i}=await m(p(t),n),a=r?.usage?{...r,usage:Z(r.usage)}:r;return i&&a&&typeof a==`object`&&e.r(a,e.a(i)),a},async*createStream(t,r){let i=p(t,{stream:!0,...s?{stream_options:{include_usage:!0}}:{}}),{data:a,headers:o}=await m(i,r);if(o){let t=n(e.a(o));t&&(yield t)}for await(let e of a)yield*et(e)}}}}}const tt=Q,nt=Q,rt=Q,it=Q,at=Q,ot=Q,st=Q,ct=Q,lt=Q,ut=Q,dt=Q,ft=Q,pt=Q,mt=Q,ht=Q,gt=Q,_t=Q,vt=Q,yt=Q,bt=Q,xt=Q,St=Q,Ct=Q,wt=Q,Tt=Q,Et=Q,$=Q,Dt=Q,Ot=Q,kt=Q,At=Q,jt=Q,Mt=Q,Nt=Q,Pt=Q,Ft=Q,It=Q,Lt=Q;exports.SSE_PING=q,exports.from01AI=Lt,exports.fromAnthropic=ye,exports.fromAnyscale=Mt,exports.fromAtlasCloud=It,exports.fromBaseten=wt,exports.fromCerebras=at,exports.fromCloudflareWorkersAI=xt,exports.fromDeepInfra=dt,exports.fromDeepSeek=it,exports.fromFeatherless=Tt,exports.fromFetch=Ve,exports.fromFireworks=st,exports.fromFriendli=Et,exports.fromGemini=Me,exports.fromGroq=nt,exports.fromHyperbolic=pt,exports.fromInferenceNet=Pt,exports.fromInfermatic=Ft,exports.fromLMStudio=gt,exports.fromLambdaLabs=At,exports.fromLepton=Nt,exports.fromMiniMax=kt,exports.fromMistral=rt,exports.fromMoonshot=mt,exports.fromNebius=St,exports.fromNovita=ft,exports.fromNvidiaNIM=yt,exports.fromOllama=ct,exports.fromOpenAI=tt,exports.fromOpenAICompatible=Q,exports.fromOpenRouter=lt,exports.fromParasail=Dt,exports.fromPerplexity=ut,exports.fromSambaNova=Ct,exports.fromSiliconFlow=$,exports.fromSnowflakeCortex=jt,exports.fromStepFun=Ot,exports.fromTogether=ot,exports.fromVLLM=_t,exports.fromVercelAIGateway=bt,exports.fromXAI=vt,exports.fromZhipu=ht,exports.parseSseStream=W;
12
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":["LLMError","LLMError","errorWithResponseBody","LLMError","LLMError","LLMError","LLMError","toWireResponse","toWireStreamChunks","toWireResponse","parseAnthropicRateLimitHeaders","toWireStreamChunks","LLMError","toWireResponse","toWireStreamChunks","toWireResponse","toWireStreamChunks","LLMError","toWireStreamChunks","parseOpenAIRateLimitHeaders","toWireStreamChunks","parseOpenAIRateLimitHeaders"],"sources":["../../src/adapters/internal/rateLimitHeaders.ts","../../src/adapters/internal/reasoningBudget.utils.ts","../../src/adapters/internal/sdkRetries.ts","../../src/adapters/internal/errors.ts","../../src/adapters/internal/forcedToolChoice.ts","../../src/adapters/internal/nativeStructuredOutput.ts","../../src/adapters/internal/claudeRequest.ts","../../src/adapters/internal/imageFormat.ts","../../src/adapters/claude/request.ts","../../src/adapters/internal/finishReason.ts","../../src/adapters/internal/forcedJsonSchemaTool.ts","../../src/adapters/claude/response.ts","../../src/adapters/claude/stream.ts","../../src/adapters/claude/anthropic.ts","../../src/adapters/gemini/request.ts","../../src/adapters/gemini/response.ts","../../src/adapters/gemini/stream.ts","../../src/adapters/gemini/gemini.ts","../../src/adapters/internal/sse.ts","../../src/adapters/fetch/response.ts","../../src/adapters/fetch/stream.ts","../../src/adapters/fetch/transport.ts","../../src/adapters/fetch/fetch.ts","../../src/adapters/openai/provider.ts","../../src/adapters/openai/reasoning.ts","../../src/adapters/openai/request.ts","../../src/adapters/openai/usage.ts","../../src/adapters/openai/stream.ts","../../src/adapters/openai/openaiCompatible.ts","../../src/adapters/openai/aliases.ts"],"sourcesContent":["import type {\n HeaderReader,\n ProviderRateLimitHint,\n} from '../../internal/utils/rate-limit/rateLimitHint.utils.js';\nimport type { WireStreamChunk } from '../../types/index.js';\n\n/**\n * Calls `.withResponse()` on an SDK request promise (the `openai` and\n * `@anthropic-ai/sdk` `APIPromise`), for the response headers AIMD reads.\n * Only for clients known to support it, since the structural client types\n * don't declare it.\n */\nexport async function withRawResponse<T>(\n request: unknown,\n): Promise<{ data: T; headers: HeaderReader }> {\n const { data, response } = await (\n request as { withResponse(): Promise<{ data: T; response: { headers: HeaderReader } }> }\n ).withResponse();\n\n return { data, headers: response.headers };\n}\n\n/**\n * The `rate_limit_hint` chunk a stream yields before its content, or\n * `undefined` when the headers carried no limit or remaining count, so an\n * empty hint never reaches the limiter.\n */\nexport function rateLimitHintChunk(hint: ProviderRateLimitHint): WireStreamChunk | undefined {\n return hint.remainingRequests !== undefined || hint.limitRequests !== undefined\n ? { type: 'rate_limit_hint', hint }\n : undefined;\n}\n\n/**\n * Sends a request, reading its response headers too when the client supports\n * `.withResponse()`. `headers` is left out otherwise.\n */\nexport async function sendWithHeaders<T>(\n request: () => unknown,\n withHeaders: boolean,\n): Promise<{ data: T; headers?: HeaderReader }> {\n if (!withHeaders) return { data: (await request()) as T };\n return withRawResponse<T>(request());\n}\n","import { LLMError } from '../../types/errors.js';\n\nimport type { ModelCapabilityOverride } from './nativeStructuredOutput.js';\n\n/**\n * Converts between `reasoningEffort` tiers and `budgetTokens`, for a\n * provider that only understands the other one. The numbers are a guess,\n * not a provider guarantee, and each adapter's `reasoningEffortTokens`\n * overrides them.\n */\nexport type EffortTokenTable = Record<'minimal' | 'low' | 'medium' | 'high', number>;\n\nexport const DEFAULT_EFFORT_TOKENS: EffortTokenTable = {\n minimal: 1024,\n low: 4096,\n medium: 16000,\n high: 32000,\n};\n\n/**\n * Merges a partial override over the defaults. Throws\n * `LLMError('invalid_params')` unless the tiers stay strictly ascending,\n * since `budgetTokensToEffort` walks them in order and an unordered table\n * would silently make some tiers unreachable.\n */\nexport function resolveEffortTokenTable(override?: Partial<EffortTokenTable>): EffortTokenTable {\n if (!override) return DEFAULT_EFFORT_TOKENS;\n\n const table = { ...DEFAULT_EFFORT_TOKENS, ...override };\n\n if (!(table.minimal < table.low && table.low < table.medium && table.medium < table.high)) {\n throw new LLMError(\n `reasoningEffortTokens must keep tiers in strictly ascending order ` +\n `(minimal < low < medium < high), got ${JSON.stringify(table)}. An out-of-order ` +\n `override doesn't just misrank tiers, it can make some of them unreachable.`,\n 'invalid_params',\n );\n }\n\n return table;\n}\n\n/** Converts a `reasoningEffort` tier into the nearest `budgetTokens` value. */\nexport function effortToBudgetTokens(\n effort: 'minimal' | 'low' | 'medium' | 'high',\n table: EffortTokenTable = DEFAULT_EFFORT_TOKENS,\n): number {\n return table[effort];\n}\n\n/**\n * Converts `budgetTokens` into a tier. A value between two tiers rounds up\n * to the first tier it is `<=`, so this agrees with `effortToBudgetTokens`\n * at the boundaries given the same table.\n */\nexport function budgetTokensToEffort(\n budgetTokens: number,\n table: EffortTokenTable = DEFAULT_EFFORT_TOKENS,\n): 'minimal' | 'low' | 'medium' | 'high' {\n if (budgetTokens <= table.minimal) return 'minimal';\n if (budgetTokens <= table.low) return 'low';\n if (budgetTokens <= table.medium) return 'medium';\n return 'high';\n}\n\n/**\n * An Opus id's `[major, minor]`, or `null` for a non-Opus id. Not anchored,\n * so Bedrock ids match too. An 8 digit second segment is a snapshot date,\n * as in `claude-opus-4-20250514`, not a minor version, or that model would\n * read as adaptive-only.\n */\nfunction parseOpusVersion(model: string): [major: number, minor: number] | null {\n const match = /opus-(\\d+)(?:-(\\d+))?/.exec(model);\n if (!match) return null;\n\n const minorStr = match[2];\n const minor = minorStr === undefined || minorStr.length >= 8 ? 0 : Number(minorStr);\n\n return [Number(match[1]), minor];\n}\n\n/**\n * Built in rule for models that reject manual `budget_tokens` thinking:\n * Opus 4.7 and later, as a version threshold, and every Claude 5 tier\n * model. A new family name needs a change here or `adaptiveOnlyModels`.\n */\nfunction isDefaultAdaptiveOnly(model: string): boolean {\n const opusVersion = parseOpusVersion(model);\n\n if (opusVersion) {\n const [major, minor] = opusVersion;\n return major > 4 || (major === 4 && minor >= 7);\n }\n\n return ['sonnet-5', 'fable-5', 'mythos'].some((s) => model.includes(s));\n}\n\n/**\n * Whether `model` is adaptive-only. The override only adds models: a false\n * positive in the built in rule needs a fix here, not a per-caller workaround.\n */\nexport function isAdaptiveOnlyModel(model: string, override?: ModelCapabilityOverride): boolean {\n if (isDefaultAdaptiveOnly(model)) return true;\n if (!override) return false;\n\n return Array.isArray(override) ? override.includes(model) : override(model);\n}\n\n/** Whether `model` is known to support manual, budget-based thinking. */\nexport function supportsManualThinkingBudget(\n model: string,\n override?: ModelCapabilityOverride,\n): boolean {\n return !isAdaptiveOnlyModel(model, override);\n}\n\n/**\n * Claude needs `budget_tokens` of at least 1024 and below `max_tokens`,\n * which the reply shares. VernLLM's default `maxTokens` of 1000 fails this,\n * so it is checked locally instead of costing a round trip.\n */\nexport function assertValidClaudeBudgetTokens(budgetTokens: number, maxTokens: number): void {\n if (budgetTokens < 1024) {\n throw new LLMError(\n `budgetTokens (${budgetTokens}) is below Anthropic's minimum of 1024. Raise budgetTokens, ` +\n `or use a reasoningEffort tier of 'low' or above with the default conversion table.`,\n 'invalid_params',\n );\n }\n\n if (budgetTokens >= maxTokens) {\n throw new LLMError(\n `budgetTokens (${budgetTokens}) must be less than maxTokens (${maxTokens}); the thinking ` +\n `budget and the reply share the same max_tokens ceiling on Anthropic. Raise maxTokens, ` +\n `or lower budgetTokens/reasoningEffort.`,\n 'invalid_params',\n );\n }\n}\n\n/**\n * Claude rejects any thinking alongside a `tool_choice` that forces tool\n * use. Adapters pass a description of their resolved choice, or `undefined`\n * when nothing is forced, so a `jsonSchema` call that forces a tool is\n * caught too, and neither wire shape leaks in here.\n */\nexport function assertNoForcedToolChoiceWithThinking(\n forcedChoiceDescription: string | undefined,\n): void {\n if (!forcedChoiceDescription) return;\n\n throw new LLMError(\n `budgetTokens/reasoningEffort was set alongside ${forcedChoiceDescription}. Anthropic ` +\n 'rejects thinking combined with a tool_choice that forces tool use, the model has to be ' +\n \"able to reply with plain text for thinking to run. Use toolChoice: 'auto' (or omit \" +\n 'toolChoice) for this call, or drop budgetTokens/reasoningEffort for it.',\n 'invalid_params',\n );\n}\n\n/** Claude's adaptive thinking effort levels. */\nexport type ClaudeAdaptiveEffort = 'low' | 'medium' | 'high' | 'xhigh' | 'max';\n\n/** Maps a `reasoningEffort` tier onto Claude's effort. `xhigh` and `max` aren't reachable. */\nexport function toClaudeAdaptiveEffort(\n effort: 'minimal' | 'low' | 'medium' | 'high',\n): ClaudeAdaptiveEffort {\n return effort === 'minimal' ? 'low' : effort;\n}\n\n/** Gemini 3's `thinkingLevel`, one level per `reasoningEffort` tier. */\nexport type GeminiThinkingLevel = 'MINIMAL' | 'LOW' | 'MEDIUM' | 'HIGH';\n\n/** Converts VernLLM's `reasoningEffort` directly into Gemini's `ThinkingLevel` enum value. */\nexport function toGeminiThinkingLevel(\n effort: 'minimal' | 'low' | 'medium' | 'high',\n model: string,\n): GeminiThinkingLevel {\n return clampGeminiThinkingLevel(model, effort.toUpperCase() as GeminiThinkingLevel);\n}\n\n/** A Gemini id's minor version, `0` when it has none. */\nfunction parseGeminiMinorVersion(model: string): number {\n const match = /gemini-\\d+\\.(\\d+)/.exec(model);\n return match ? Number(match[1]) : 0;\n}\n\n/**\n * Gemini 3 Pro tier models reject some levels with a 400: Gemini 3 Pro\n * takes only LOW and HIGH, Gemini 3.1 Pro and later no MINIMAL. Clamped\n * rather than left to fail, since the tier is per call and the failure\n * would look intermittent. Best effort: a later release may change this.\n */\nfunction clampGeminiThinkingLevel(model: string, level: GeminiThinkingLevel): GeminiThinkingLevel {\n if (!model.includes('pro')) return level;\n\n const major = parseGeminiMajorVersion(model);\n if (major === null || major < 3) return level;\n\n const minor = parseGeminiMinorVersion(model);\n\n if (minor === 0) {\n // Gemini 3 Pro: only LOW and HIGH are accepted.\n return level === 'HIGH' ? 'HIGH' : 'LOW';\n }\n\n // Gemini 3.1 Pro and later: LOW/MEDIUM/HIGH accepted, no MINIMAL.\n return level === 'MINIMAL' ? 'LOW' : level;\n}\n\n/** A Gemini id's major version, or `null` for a non-Gemini id. Not anchored, so prefixed ids match. */\nfunction parseGeminiMajorVersion(model: string): number | null {\n const match = /gemini-(\\d+)/.exec(model);\n return match ? Number(match[1]) : null;\n}\n\n/** Built in rule for `thinkingLevel`: Gemini 3 and later, as a version threshold. */\nfunction isDefaultThinkingLevelModel(model: string): boolean {\n const major = parseGeminiMajorVersion(model);\n return major !== null && major >= 3;\n}\n\n/** Whether `model` uses `thinkingLevel`. The override only adds models. */\nexport function usesGeminiThinkingLevel(\n model: string,\n override?: ModelCapabilityOverride,\n): boolean {\n if (isDefaultThinkingLevelModel(model)) return true;\n if (!override) return false;\n\n return Array.isArray(override) ? override.includes(model) : override(model);\n}\n","import type { Logger } from '../../logger.js';\n\n/**\n * Adapter names already warned about. Module scoped so the warning prints once per process for\n * each SDK, not again for every client or `VernLLM` instance an app builds, such as one per\n * request in a serverless handler.\n */\nconst warnedAdapters = new Set<string>();\n\n/** Clears the once per process state. Tests only; not exported from the package. */\nexport function resetSdkRetryWarnings(): void {\n warnedAdapters.clear();\n}\n\n/**\n * Returns a `setLogger` body that warns when the wrapped SDK client retries on its own. Those\n * retries happen inside one `create()` call, where VernLLM's retries, breaker, limiter, and events\n * can't see them. `readRetries` returns `undefined` for a client that isn't the SDK (a fake or a\n * thin wrapper), which stays silent.\n */\nexport function sdkRetryWarning(\n adapterName: string,\n readRetries: () => number | undefined,\n fix: string,\n): (logger: Logger) => void {\n return (logger) => {\n if (warnedAdapters.has(adapterName)) return;\n const retries = readRetries();\n // `> 0` also rejects NaN, which the SDKs would treat as no retry.\n if (retries === undefined || !(retries > 0)) return;\n\n warnedAdapters.add(adapterName);\n logger.warn(\n `[VernLLM] ${adapterName}: the SDK client retries up to ${retries} times on its own, ` +\n `hidden from VernLLM's retries, circuit breaker, rate limiter, and events. ${fix} so ` +\n 'VernLLM is the only retry owner.',\n );\n };\n}\n\n/** `maxRetries` off a Stainless generated client (`openai`, `@anthropic-ai/sdk`, `groq-sdk`). */\nexport function readMaxRetries(client: unknown): number | undefined {\n const value = (client as { maxRetries?: unknown } | null)?.maxRetries;\n return typeof value === 'number' ? value : undefined;\n}\n","import { errorWithResponseBody } from '../../internal/utils/errors/responseBody.utils.js';\nimport { LLMError } from '../../types/index.js';\n\nimport type { HeaderReader } from '../../internal/utils/rate-limit/rateLimitHint.utils.js';\n\n/**\n * `LLMError('invalid_params')`, code `unsupported_capability`, for a request\n * the adapter or model can't serve. Thrown before dispatch, so it is never\n * retried, never counts toward the breaker, and fallback may still try\n * another target.\n */\nexport function unsupportedCapability(message: string, capability: string): LLMError {\n return new LLMError(message, 'invalid_params', {\n code: 'unsupported_capability',\n issues: { capability },\n });\n}\n\n/** An error for a non-2xx HTTP response, shaped the way core classifies SDK errors. */\nexport type HttpResponseError = Error & { status: number; headers?: HeaderReader };\n\n/**\n * The error for a non-2xx HTTP response. The body stays redactable, `status`\n * drives retry and breaker decisions, and `headers` lets core read\n * Retry-After and rate limit headers off it.\n */\nexport function httpResponseError(\n prefix: string,\n response: { status: number; headers?: HeaderReader },\n body: string,\n): HttpResponseError {\n const error = errorWithResponseBody(`${prefix} (${response.status})`, body) as HttpResponseError;\n\n error.status = response.status;\n error.headers = response.headers;\n\n return error;\n}\n","import { unsupportedCapability } from './errors.js';\n\nimport type { WireToolChoice } from '../../types/index.js';\nimport type { ModelCapabilityOverride } from './nativeStructuredOutput.js';\n\n/**\n * A Claude model id's family and version, e.g. `\"claude-opus-5-5\"` ->\n * `{ family: 'opus', major: 5, minor: 5 }`. Not anchored, so a Bedrock id\n * (`anthropic.claude-...-v1:0`), a region prefixed inference profile\n * (`us.anthropic.claude-...`), or an ARN containing one all match. The\n * older `claude-3-5-sonnet` order has no family ahead of the version.\n *\n * A second segment of 8 digits or more is a snapshot date\n * (`claude-sonnet-5-20260101`), not a minor version, so it reads as `0`.\n */\nfunction parseClaudeVersion(\n model: string,\n): { family?: string; major: number; minor: number } | null {\n const named = /claude-([a-z]+)-(\\d+)(?:[-.](\\d+))?/i.exec(model);\n const match = named ?? /claude-(\\d+)(?:[-.](\\d+))?/i.exec(model);\n if (!match) return null;\n\n const [, first, second, third] = named ? match : [match[0], undefined, match[1], match[2]];\n const minor = third === undefined || third.length >= 8 ? 0 : Number(third);\n\n return { family: first?.toLowerCase(), major: Number(second), minor };\n}\n\n/** Whether `[major, minor]` is at least `[atLeastMajor, atLeastMinor]`. */\nfunction versionAtLeast(major: number, minor: number, atLeastMajor: number, atLeastMinor: number) {\n return major > atLeastMajor || (major === atLeastMajor && minor >= atLeastMinor);\n}\n\n/**\n * Built in rule for Claude models that reject a `tool_choice` forcing\n * tool use (`any` or a named `tool`): Claude Fable 5.1 and later, Opus\n * 5.5 and later, and every Claude model of major version 6 or later.\n * Matched as version thresholds so later point releases are covered\n * without a list entry each.\n */\nfunction isDefaultForcedToolChoiceUnsupported(model: string): boolean {\n const version = parseClaudeVersion(model);\n if (!version) return false;\n\n const { family, major, minor } = version;\n\n if (major >= 6) return true;\n if (family === 'fable') return versionAtLeast(major, minor, 5, 1);\n if (family === 'opus') return versionAtLeast(major, minor, 5, 5);\n return false;\n}\n\n/**\n * Whether `model` rejects a forced `tool_choice`. `override`, when given,\n * replaces the built in rule entirely, so a caller can both add a model\n * and take one back out, for a model the rule gets wrong either way.\n */\nexport function rejectsForcedToolChoice(\n model: string,\n override?: ModelCapabilityOverride,\n): boolean {\n if (!override) return isDefaultForcedToolChoiceUnsupported(model);\n\n return Array.isArray(override) ? override.includes(model) : override(model);\n}\n\n/**\n * Throws `unsupported_capability` when `toolChoice` forces tool use on a\n * model that rejects it. `'auto'`, `'none'` and an unset choice pass.\n */\nexport function assertForcedToolChoiceSupported(\n provider: string,\n model: string,\n toolChoice: WireToolChoice | undefined,\n override?: ModelCapabilityOverride,\n): void {\n if (!toolChoice || toolChoice === 'auto' || toolChoice === 'none') return;\n if (!rejectsForcedToolChoice(model, override)) return;\n\n const described =\n toolChoice === 'required'\n ? \"toolChoice: 'required'\"\n : `toolChoice: { name: '${toolChoice.function.name}' }`;\n\n throw unsupportedCapability(\n `${provider} model \"${model}\" rejects a tool_choice that forces tool use, so ${described} ` +\n \"can't be sent. Use toolChoice: 'auto' and ask for the tool in the prompt instead. If \" +\n 'this model does accept it, list the models that reject it in forcedToolChoiceUnsupportedModels.',\n 'forced_tool_choice',\n );\n}\n","/**\n * A list of model ids, or a predicate, naming models with a capability.\n * Native structured output has no built in list: which models support it\n * is the provider's call and changes over time, and a wrong guess would\n * trade a clear local error for a confusing provider one.\n */\nexport type ModelCapabilityOverride = string[] | ((model: string) => boolean);\n\n/** Resolves whether `model` is covered by a caller-supplied allow-list/predicate. */\nexport function supportsNativeStructuredOutput(\n model: string,\n override?: ModelCapabilityOverride,\n): boolean {\n if (!override) return false;\n\n return Array.isArray(override) ? override.includes(model) : override(model);\n}\n","import { LLMError, type WireCallRequest } from '../../types/index.js';\nimport { unsupportedCapability } from './errors.js';\nimport { assertForcedToolChoiceSupported, rejectsForcedToolChoice } from './forcedToolChoice.js';\nimport {\n supportsNativeStructuredOutput,\n type ModelCapabilityOverride,\n} from './nativeStructuredOutput.js';\nimport {\n assertNoForcedToolChoiceWithThinking,\n assertValidClaudeBudgetTokens,\n budgetTokensToEffort,\n effortToBudgetTokens,\n supportsManualThinkingBudget,\n toClaudeAdaptiveEffort,\n type ClaudeAdaptiveEffort,\n type EffortTokenTable,\n} from './reasoningBudget.utils.js';\n\n// Claude's request rules, shared by every adapter that talks to Claude so\n// each only maps the decisions onto its own wire shape.\n\ntype WireJsonSchema = Extract<\n NonNullable<WireCallRequest['response_format']>,\n { type: 'json_schema' }\n>['json_schema'];\n\n/**\n * How `jsonSchema` is sent: not at all, as native structured output, or as a\n * forced call to a tool named `schemaName`, the trimmed schema name.\n */\nexport type ClaudeStructuredOutputPlan =\n | { mode: 'none' }\n | { mode: 'native'; jsonSchema: WireJsonSchema; schemaName: string }\n | { mode: 'forcedTool'; jsonSchema: WireJsonSchema; schemaName: string };\n\n/**\n * Checks `jsonSchema`, `tools` and `tool_choice` against a Claude model and\n * picks how structured output is sent. A model that rejects a forced\n * `tool_choice` can't run the forced tool emulation, so native output is its\n * only working path. Throws before dispatch for a request the model can't\n * serve; `messages` keeps each provider's wording.\n */\nexport function planClaudeStructuredOutput(\n provider: string,\n params: WireCallRequest,\n models: {\n nativeStructuredOutputModels?: ModelCapabilityOverride;\n forcedToolChoiceUnsupportedModels?: ModelCapabilityOverride;\n },\n messages: { toolsWithJsonSchema: (model: string) => string; jsonObject: string },\n): ClaudeStructuredOutputPlan {\n const jsonSchema =\n params.response_format?.type === 'json_schema' ? params.response_format.json_schema : undefined;\n const schemaName = jsonSchema?.name.trim();\n\n if (jsonSchema && !schemaName) {\n throw new LLMError('json_schema.name must not be empty.', 'validation');\n }\n\n const rejectsForced = rejectsForcedToolChoice(\n params.model,\n models.forcedToolChoiceUnsupportedModels,\n );\n\n if (params.tools?.length) {\n assertForcedToolChoiceSupported(\n provider,\n params.model,\n params.tool_choice,\n models.forcedToolChoiceUnsupportedModels,\n );\n }\n\n const isNative =\n Boolean(jsonSchema) &&\n (rejectsForced ||\n supportsNativeStructuredOutput(params.model, models.nativeStructuredOutputModels));\n\n if (jsonSchema && params.tools?.length && !isNative) {\n throw unsupportedCapability(\n messages.toolsWithJsonSchema(params.model),\n 'tools_with_json_schema',\n );\n }\n\n if (params.response_format?.type === 'json_object') {\n throw new LLMError(messages.jsonObject, 'validation');\n }\n\n if (!jsonSchema || !schemaName) return { mode: 'none' };\n return { mode: isNative ? 'native' : 'forcedTool', jsonSchema, schemaName };\n}\n\n/** Claude's `thinking` for a request, plus the adaptive effort when it has one. */\nexport interface ClaudeThinking {\n thinking: { type: 'enabled'; budget_tokens: number } | { type: 'adaptive' };\n effort?: ClaudeAdaptiveEffort;\n}\n\n/**\n * Resolves `budgetTokens` and `reasoningEffort` into Claude's thinking, or\n * `undefined` when neither is set. Adaptive-only models reject\n * `budget_tokens`, so they get adaptive thinking with an effort converted\n * from whatever the caller set. `forcedChoice` describes the resolved\n * forced `tool_choice`, if any, since Claude rejects thinking with one.\n */\nexport function resolveClaudeThinking(\n params: WireCallRequest,\n forcedChoice: string | undefined,\n options: { adaptiveOnlyModels?: ModelCapabilityOverride; effortTokenTable?: EffortTokenTable },\n): ClaudeThinking | undefined {\n if (params.budget_tokens === undefined && params.reasoning_effort === undefined) {\n return undefined;\n }\n\n assertNoForcedToolChoiceWithThinking(forcedChoice);\n\n if (supportsManualThinkingBudget(params.model, options.adaptiveOnlyModels)) {\n const budgetTokens =\n params.budget_tokens ??\n effortToBudgetTokens(params.reasoning_effort!, options.effortTokenTable);\n\n assertValidClaudeBudgetTokens(budgetTokens, params.max_tokens);\n\n return { thinking: { type: 'enabled', budget_tokens: budgetTokens } };\n }\n\n const effortTier =\n params.reasoning_effort ??\n budgetTokensToEffort(params.budget_tokens!, options.effortTokenTable);\n\n return { thinking: { type: 'adaptive' }, effort: toClaudeAdaptiveEffort(effortTier) };\n}\n","import { LLMError } from '../../types/index.js';\n\n/**\n * `ImageBlock.mimeType` values every adapter accepts: the types all\n * supported providers share, so content valid for one is valid for all.\n */\nexport const SUPPORTED_IMAGE_MIME_TYPES = [\n 'image/png',\n 'image/jpeg',\n 'image/gif',\n 'image/webp',\n] as const;\n\nexport type SupportedImageMimeType = (typeof SUPPORTED_IMAGE_MIME_TYPES)[number];\n\n/** Throws a non-retryable `LLMError('invalid_params')` for a MIME type outside the shared set. */\nexport function assertSupportedImageMimeType(mimeType: string): SupportedImageMimeType {\n if ((SUPPORTED_IMAGE_MIME_TYPES as readonly string[]).includes(mimeType)) {\n return mimeType as SupportedImageMimeType;\n }\n\n throw new LLMError(\n `Unsupported image mimeType \"${mimeType}\": expected one of ${SUPPORTED_IMAGE_MIME_TYPES.join(', ')}`,\n 'invalid_params',\n );\n}\n","import { LLMError, type ContentBlock, type LLMClient } from '../../types/index.js';\nimport { planClaudeStructuredOutput, resolveClaudeThinking } from '../internal/claudeRequest.js';\nimport { assertSupportedImageMimeType } from '../internal/imageFormat.js';\n\nimport type { ModelCapabilityOverride } from '../internal/nativeStructuredOutput.js';\nimport type { EffortTokenTable } from '../internal/reasoningBudget.utils.js';\nimport type { AnthropicClient, AnthropicContentBlock, AnthropicRequestBody } from './types.js';\n\n/** Translates `ContentBlock[]` into Anthropic content blocks, images as base64 sources. */\nfunction toAnthropicContent(blocks: ContentBlock[]): AnthropicContentBlock[] {\n return blocks.map((block) =>\n block.type === 'image'\n ? {\n type: 'image',\n source: {\n type: 'base64',\n media_type: assertSupportedImageMimeType(block.mimeType),\n data: block.data,\n },\n }\n : { type: 'text', text: block.text },\n );\n}\n\n/**\n * Anthropic's `input_schema` must be an object schema, which VernLLM's\n * freeform schemas don't guarantee, so a mismatch fails here instead of at\n * the provider.\n */\nfunction assertObjectSchema(\n schema: Record<string, unknown>,\n toolName: string,\n): { type: 'object'; [key: string]: unknown } {\n if (schema.type !== 'object') {\n throw new LLMError(\n `Tool \"${toolName}\"'s schema must have \"type\": \"object\" (Anthropic requires object-shaped tool parameters).`,\n 'validation',\n );\n }\n\n return schema as { type: 'object'; [key: string]: unknown };\n}\n\n/** Maps the wire `tool_choice` onto Anthropic's; `'required'` is Anthropic's `'any'`. */\nfunction toAnthropicToolChoice(\n toolChoice: Parameters<LLMClient['chat']['completions']['create']>[0]['tool_choice'],\n):\n | { type: 'auto' }\n | { type: 'any' }\n | { type: 'none' }\n | { type: 'tool'; name: string }\n | undefined {\n const normalized = !toolChoice ? 'auto' : toolChoice;\n\n switch (normalized) {\n case 'auto':\n return { type: 'auto' };\n case 'none':\n return { type: 'none' };\n case 'required':\n return { type: 'any' };\n default:\n return { type: 'tool', name: normalized.function.name };\n }\n}\n\n/** Maps the caller's real tools, alone or next to native structured output. */\nfunction buildAnthropicTools(\n tools: NonNullable<Parameters<LLMClient['chat']['completions']['create']>[0]['tools']>,\n toolChoiceParam: Parameters<LLMClient['chat']['completions']['create']>[0]['tool_choice'],\n): {\n tools: NonNullable<Parameters<AnthropicClient['messages']['create']>[0]['tools']>;\n toolChoice: Parameters<AnthropicClient['messages']['create']>[0]['tool_choice'];\n} {\n return {\n tools: tools.map((t) => ({\n name: t.function.name,\n description: t.function.description,\n input_schema: assertObjectSchema(t.function.parameters, t.function.name),\n })),\n toolChoice: toAnthropicToolChoice(toolChoiceParam),\n };\n}\n\nconst ANTHROPIC_MESSAGES = {\n toolsWithJsonSchema: (model: string) =>\n `Anthropic model \"${model}\" is not covered by nativeStructuredOutputModels, so ` +\n '`jsonSchema` is emulated as a forced single tool call there, which collides with the ' +\n '`tools` you also provided. Either drop `tools` or `jsonSchema` for this call, or pass ' +\n \"this model in fromAnthropic's `nativeStructuredOutputModels` option once you've \" +\n \"confirmed it supports Anthropic's `output_config.format`.\",\n jsonObject:\n 'response_format: \"json_object\" is not supported on Anthropic. Unlike OpenAI, Anthropic ' +\n 'has no API-level field that mechanically guarantees valid JSON output for this mode, so ' +\n 'it used to be emulated by injecting a \"respond with JSON only\" instruction into the ' +\n 'system prompt, a guarantee this adapter can no longer make. Use `jsonSchema` instead, ' +\n \"which maps to a real API-level constraint (Anthropic's native output_config.format on \" +\n 'covered models, or a forced single tool call otherwise).',\n};\n\n/** Describes a forced `tool_choice` for the thinking check, `undefined` when nothing is forced. */\nfunction describeForcedChoice(toolChoice: AnthropicRequestBody['tool_choice']): string | undefined {\n if (toolChoice?.type === 'tool') return `toolChoice forcing the \"${toolChoice.name}\" tool`;\n if (toolChoice?.type === 'any') return \"toolChoice: 'required' (Anthropic's \\\"any\\\" tool_choice)\";\n return undefined;\n}\n\n/**\n * Builds the request body shared by `create` and `createStream`.\n *\n * `toolName` is set when `jsonSchema` is emulated as a forced single tool\n * call, so the caller unwraps that tool's input back into text content.\n * On the native path it stays unset: the JSON arrives as ordinary text.\n */\nexport function buildAnthropicRequestBody(\n params: Parameters<LLMClient['chat']['completions']['create']>[0],\n nativeStructuredOutputModels?: ModelCapabilityOverride,\n effortTokenTable?: EffortTokenTable,\n adaptiveOnlyModels?: ModelCapabilityOverride,\n forcedToolChoiceUnsupportedModels?: ModelCapabilityOverride,\n): { body: AnthropicRequestBody; toolName: string | undefined } {\n const systemMessage = params.messages.find((m) => m.role === 'system');\n\n // Tool results travel as user turns, since Anthropic has no tool role.\n const conversationMessages = params.messages.filter(\n (m) => m.role === 'user' || m.role === 'assistant' || m.role === 'tool',\n );\n\n const plan = planClaudeStructuredOutput(\n 'Anthropic',\n params,\n { nativeStructuredOutputModels, forcedToolChoiceUnsupportedModels },\n ANTHROPIC_MESSAGES,\n );\n\n let toolName: string | undefined;\n let outputFormat: NonNullable<AnthropicRequestBody['output_config']>['format'] | undefined;\n let tools: NonNullable<AnthropicRequestBody['tools']> | undefined;\n let toolChoice: AnthropicRequestBody['tool_choice'];\n\n if (plan.mode === 'forcedTool') {\n const { schema, description, strict } = plan.jsonSchema;\n\n toolName = plan.schemaName;\n tools = [\n { name: toolName, description, input_schema: assertObjectSchema(schema, toolName), strict },\n ];\n toolChoice = { type: 'tool', name: toolName };\n } else {\n // `output_config.format` has no name, description or strict field, so\n // only the schema is sent; real tools go alongside it.\n if (plan.mode === 'native') {\n outputFormat = { type: 'json_schema', schema: plan.jsonSchema.schema };\n }\n\n if (params.tools?.length) {\n ({ tools, toolChoice } = buildAnthropicTools(params.tools, params.tool_choice));\n }\n }\n\n const resolved = resolveClaudeThinking(params, describeForcedChoice(toolChoice), {\n adaptiveOnlyModels,\n effortTokenTable,\n });\n const effort = resolved?.effort;\n const system = systemMessage?.content;\n\n // Anthropic rejects temperature alongside any thinking mode, and VernLLM\n // always sends one, so it is dropped whenever thinking goes out.\n const temperature = resolved ? undefined : params.temperature;\n\n const body: AnthropicRequestBody = {\n model: params.model,\n max_tokens: params.max_tokens,\n ...(temperature !== undefined ? { temperature } : {}),\n system: system || undefined,\n messages: mergeConsecutiveToolResults(conversationMessages.map((m) => toAnthropicMessage(m))),\n ...(tools ? { tools, tool_choice: toolChoice } : {}),\n ...(outputFormat || effort\n ? {\n output_config: {\n ...(outputFormat ? { format: outputFormat } : {}),\n ...(effort ? { effort } : {}),\n },\n }\n : {}),\n ...(resolved ? { thinking: resolved.thinking } : {}),\n };\n\n return { body, toolName };\n}\n\n/**\n * Anthropic requires strict role alternation, so a run of tool-result-only\n * user turns, from parallel tool calls, is merged into one.\n */\nfunction mergeConsecutiveToolResults(\n messages: { role: 'user' | 'assistant'; content: string | AnthropicContentBlock[] }[],\n): { role: 'user' | 'assistant'; content: string | AnthropicContentBlock[] }[] {\n const isToolResultOnly = (\n m: (typeof messages)[number],\n ): m is { role: 'user'; content: AnthropicContentBlock[] } =>\n m.role === 'user' &&\n Array.isArray(m.content) &&\n m.content.length > 0 &&\n m.content.every((b) => b.type === 'tool_result');\n\n const merged: (typeof messages)[number][] = [];\n\n for (const m of messages) {\n const prev = merged.at(-1);\n\n if (isToolResultOnly(m) && prev && isToolResultOnly(prev)) {\n prev.content.push(...m.content);\n } else {\n merged.push(m);\n }\n }\n\n return merged;\n}\n\n/** Translates one wire message into Anthropic's `{ role, content }` shape. */\nfunction toAnthropicMessage(\n m: Extract<\n Parameters<LLMClient['chat']['completions']['create']>[0]['messages'][number],\n { role: 'user' | 'assistant' | 'tool' }\n >,\n): { role: 'user' | 'assistant'; content: string | AnthropicContentBlock[] } {\n if (m.role === 'tool') {\n return {\n role: 'user',\n content: [\n {\n type: 'tool_result',\n tool_use_id: m.tool_call_id,\n content: m.content,\n ...(m.is_error ? { is_error: true } : {}),\n },\n ],\n };\n }\n\n if (m.role === 'assistant' && (m.tool_calls?.length || m.thinking?.length)) {\n // Claude requires its reasoning ahead of the text and tool calls it led to.\n const blocks: AnthropicContentBlock[] = (m.thinking ?? []).map((block) =>\n block.type === 'thinking'\n ? { type: 'thinking', thinking: block.thinking, signature: block.signature }\n : { type: 'redacted_thinking', data: block.data },\n );\n\n if (m.content) blocks.push({ type: 'text', text: m.content });\n\n for (const tc of m.tool_calls ?? []) {\n let input: unknown;\n\n try {\n input = tc.function.arguments.trim() ? JSON.parse(tc.function.arguments) : {};\n } catch (cause) {\n throw new LLMError(\n `Assistant tool call \"${tc.function.name}\" (${tc.id}) has arguments that are not valid JSON.`,\n 'validation',\n { cause },\n );\n }\n\n if (input === null || Array.isArray(input) || typeof input !== 'object') {\n throw new LLMError(\n `Assistant tool call \"${tc.function.name}\" (${tc.id}) arguments must be a JSON object.`,\n 'validation',\n );\n }\n\n blocks.push({ type: 'tool_use', id: tc.id, name: tc.function.name, input });\n }\n\n return { role: 'assistant', content: blocks };\n }\n\n return {\n role: m.role,\n content: Array.isArray(m.content) ? toAnthropicContent(m.content) : (m.content ?? ''),\n };\n}\n","/**\n * The wire `finish_reason` for a provider's stop reason. Core only acts on\n * truncation, so `lengthReason`, the provider's own spelling of it, maps to\n * `'length'` and every other reason is left off.\n */\nexport function finishReason(\n reason: string | null | undefined,\n lengthReason: string,\n): { finish_reason?: 'length' } {\n return reason === lengthReason ? { finish_reason: 'length' } : {};\n}\n","import { LLMError } from '../../types/index.js';\n\n// Shared by adapters that emulate `jsonSchema` as a forced single tool call,\n// so the errors read the same across providers and entry points.\n\n/**\n * Throws `LLMError('validation')` when the model never called the forced\n * json_schema tool at all (ignored it, called a different tool, or\n * replied with plain text instead).\n */\nexport function throwMissingForcedJsonSchemaTool(provider: string, toolName: string): never {\n throw new LLMError(\n `${provider} did not return the required structured output tool \"${toolName}\".`,\n 'validation',\n );\n}\n\n/**\n * Throws `LLMError('validation')` when the forced tool's parsed `input`\n * isn't a JSON object. Only non-streaming paths have a parsed value to check.\n */\nexport function assertForcedJsonSchemaToolInputIsObject(\n provider: string,\n toolName: string,\n input: unknown,\n): asserts input is Record<string, unknown> {\n if (!input || typeof input !== 'object' || Array.isArray(input)) {\n throw new LLMError(\n `${provider} returned invalid structured output for tool \"${toolName}\". Expected an object.`,\n 'validation',\n );\n }\n}\n","import { finishReason } from '../internal/finishReason.js';\nimport {\n assertForcedJsonSchemaToolInputIsObject,\n throwMissingForcedJsonSchemaTool,\n} from '../internal/forcedJsonSchemaTool.js';\n\nimport type { ThinkingBlock, WireToolCall } from '../../types/index.js';\nimport type { AnthropicResponse, AnthropicUsage } from './types.js';\n\nconst finite = (value: number | null | undefined) =>\n typeof value === 'number' && Number.isFinite(value) ? value : 0;\n\n/**\n * Every input token: uncached, cache writes and cache reads. `undefined` when none is reported,\n * so a missing count isn't passed off as 0; a non finite value counts as 0 rather than poisoning\n * the sum.\n */\nexport function promptTokens(usage: AnthropicUsage | undefined): number | undefined {\n const parts = [\n usage?.input_tokens,\n usage?.cache_creation_input_tokens,\n usage?.cache_read_input_tokens,\n ];\n\n if (parts.every((part) => part === undefined || part === null)) return undefined;\n\n return parts.reduce<number>((sum, part) => sum + finite(part), 0);\n}\n\n/** The cache split, in the wire shape. `undefined` when there is no usage. */\nexport function promptTokensDetails(usage: AnthropicUsage | undefined) {\n if (!usage) return undefined;\n\n const byTtl = usage.cache_creation\n ? {\n '5m': finite(usage.cache_creation.ephemeral_5m_input_tokens),\n '1h': finite(usage.cache_creation.ephemeral_1h_input_tokens),\n }\n : undefined;\n\n return {\n cached_tokens: usage.cache_read_input_tokens ?? undefined,\n cache_write_tokens: usage.cache_creation_input_tokens ?? undefined,\n ...(byTtl ? { cache_write_tokens_by_ttl: byTtl } : {}),\n };\n}\n\n/** The reasoning blocks of a response, in order, in VernLLM's shape. */\nfunction toThinkingBlocks(content: AnthropicResponse['content']): ThinkingBlock[] {\n return content.flatMap((block): ThinkingBlock[] => {\n if (block.type === 'thinking') {\n return [\n { type: 'thinking', thinking: block.thinking ?? '', signature: block.signature ?? '' },\n ];\n }\n\n if (block.type === 'redacted_thinking') {\n return [{ type: 'redacted_thinking', data: block.data ?? '' }];\n }\n\n return [];\n });\n}\n\n/**\n * Maps a message onto the wire response. A forced json-schema tool's input\n * becomes the text content, as the structured output.\n */\nexport function toWireResponse(response: AnthropicResponse, toolName: string | undefined) {\n let text: string;\n let wireToolCalls: WireToolCall[] | undefined;\n const thinking = toThinkingBlocks(response.content);\n\n if (toolName) {\n const toolUse = response.content.find(\n (block) => block.type === 'tool_use' && block.name === toolName,\n );\n\n if (!toolUse) throwMissingForcedJsonSchemaTool('Anthropic', toolName);\n\n assertForcedJsonSchemaToolInputIsObject('Anthropic', toolName, toolUse.input);\n\n text = JSON.stringify(toolUse.input);\n } else {\n text = response.content\n .filter((block) => block.type === 'text')\n .map((block) => block.text ?? '')\n .join('');\n\n const toolUses = response.content.filter((block) => block.type === 'tool_use');\n\n if (toolUses.length) {\n wireToolCalls = toolUses.map((block) => ({\n id: block.id!,\n type: 'function' as const,\n function: { name: block.name!, arguments: JSON.stringify(block.input ?? {}) },\n }));\n }\n }\n\n return {\n choices: [\n {\n message: {\n content: text,\n ...(wireToolCalls ? { tool_calls: wireToolCalls } : {}),\n ...(thinking.length ? { thinking } : {}),\n },\n ...finishReason(response.stop_reason, 'max_tokens'),\n },\n ],\n usage: {\n prompt_tokens: promptTokens(response.usage),\n completion_tokens: response.usage?.output_tokens,\n total_tokens: (promptTokens(response.usage) ?? 0) + (response.usage?.output_tokens ?? 0),\n prompt_tokens_details: promptTokensDetails(response.usage),\n ...(response.usage?.output_tokens_details?.thinking_tokens !== undefined\n ? {\n completion_tokens_details: {\n reasoning_tokens: response.usage.output_tokens_details.thinking_tokens,\n },\n }\n : {}),\n },\n };\n}\n","import { throwMissingForcedJsonSchemaTool } from '../internal/forcedJsonSchemaTool.js';\nimport { promptTokens, promptTokensDetails } from './response.js';\n\nimport type { ThinkingBlock, WireStreamChunk } from '../../types/index.js';\nimport type { AnthropicStreamEvent, AnthropicUsage } from './types.js';\n\ntype StreamEvent<T extends AnthropicStreamEvent['type']> = Extract<\n AnthropicStreamEvent,\n { type: T }\n>;\n\n/** What the stream loop remembers between events. */\ninterface StreamState {\n /** The forced json-schema tool, whose input is the structured output. */\n toolName: string | undefined;\n /**\n * Deltas only carry a block index, so each block's kind is kept. A\n * `json-tool` block's input is re-emitted as text, the streaming\n * counterpart of `create` unwrapping the forced tool.\n */\n blockKinds: Map<number, 'text' | 'tool_use' | 'json-tool'>;\n /** Reasoning is only usable once whole, so it is gathered per block until its stop event. */\n thinkingBlocks: Map<number, ThinkingBlock>;\n /** `message_start`'s usage, completed by `message_delta`'s cumulative input counts. */\n startUsage: AnthropicUsage | undefined;\n sawJsonTool: boolean;\n}\n\nfunction* onBlockStart(\n state: StreamState,\n event: StreamEvent<'content_block_start'>,\n): Generator<WireStreamChunk> {\n const block = event.content_block;\n\n switch (block.type) {\n case 'tool_use': {\n const kind = block.name === state.toolName ? 'json-tool' : 'tool_use';\n state.blockKinds.set(event.index, kind);\n\n if (kind === 'json-tool') {\n state.sawJsonTool = true;\n } else if (!state.toolName) {\n // With a forced tool in play, any other tool_use block is\n // unexpected and would corrupt the JSON the caller expects.\n yield { type: 'tool_call_delta', index: event.index, id: block.id, name: block.name };\n }\n return;\n }\n case 'thinking':\n state.thinkingBlocks.set(event.index, {\n type: 'thinking',\n thinking: block.thinking ?? '',\n signature: block.signature ?? '',\n });\n return;\n case 'redacted_thinking':\n state.thinkingBlocks.set(event.index, { type: 'redacted_thinking', data: block.data ?? '' });\n return;\n default:\n state.blockKinds.set(event.index, 'text');\n }\n}\n\nfunction* onBlockDelta(\n state: StreamState,\n event: StreamEvent<'content_block_delta'>,\n): Generator<WireStreamChunk> {\n const { delta } = event;\n\n switch (delta.type) {\n case 'text_delta':\n // Text next to a forced json-schema tool would corrupt its JSON\n // payload in the same buffer, so it is dropped then.\n if (!state.toolName) yield { type: 'text-delta', delta: delta.text };\n return;\n case 'thinking_delta': {\n const block = state.thinkingBlocks.get(event.index);\n if (block?.type === 'thinking') block.thinking += delta.thinking;\n // Reasoning reaches the caller only at content_block_stop, so a ping\n // keeps a long thinking block from idling out.\n yield { type: 'ping' };\n return;\n }\n case 'signature_delta': {\n const block = state.thinkingBlocks.get(event.index);\n if (block?.type === 'thinking') block.signature += delta.signature;\n yield { type: 'ping' };\n return;\n }\n case 'input_json_delta':\n if (state.blockKinds.get(event.index) === 'json-tool') {\n yield { type: 'text-delta', delta: delta.partial_json };\n } else if (!state.toolName) {\n yield { type: 'tool_call_delta', index: event.index, argumentsDelta: delta.partial_json };\n }\n }\n}\n\nfunction* onBlockStop(\n state: StreamState,\n event: StreamEvent<'content_block_stop'>,\n): Generator<WireStreamChunk> {\n const block = state.thinkingBlocks.get(event.index);\n\n if (block) {\n state.thinkingBlocks.delete(event.index);\n yield { type: 'thinking_block', block };\n }\n}\n\nconst CUMULATIVE_INPUT_KEYS = [\n 'input_tokens',\n 'cache_creation_input_tokens',\n 'cache_read_input_tokens',\n] as const;\n\n/**\n * `message_start`'s usage with `message_delta`'s input counts laid over it. Those are cumulative\n * whole message totals, omitted when they don't apply, so, as in Anthropic's own stream\n * accumulator, a present value overwrites and is never added.\n */\nfunction withCumulativeInput(\n start: AnthropicUsage | undefined,\n delta: StreamEvent<'message_delta'>['usage'],\n): AnthropicUsage {\n const merged: AnthropicUsage = { ...start };\n\n for (const key of CUMULATIVE_INPUT_KEYS) {\n const value = delta?.[key];\n if (value !== undefined && value !== null) merged[key] = value;\n }\n\n return merged;\n}\n\nfunction usageChunk(state: StreamState, event: StreamEvent<'message_delta'>): WireStreamChunk {\n const usage = withCumulativeInput(state.startUsage, event.usage);\n const inputTokens = promptTokens(usage) ?? 0;\n const outputTokens = event.usage?.output_tokens ?? 0;\n const thinkingTokens = event.usage?.output_tokens_details?.thinking_tokens;\n\n return {\n type: 'usage',\n usage: {\n prompt_tokens: inputTokens,\n completion_tokens: outputTokens,\n total_tokens: inputTokens + outputTokens,\n prompt_tokens_details: promptTokensDetails(usage),\n ...(thinkingTokens !== undefined\n ? { completion_tokens_details: { reasoning_tokens: thinkingTokens } }\n : {}),\n },\n };\n}\n\n/**\n * Translates Anthropic stream events into wire chunks. With `toolName` set,\n * only the forced json-schema tool's input comes through, as text.\n */\nexport async function* toWireStreamChunks(\n stream: AsyncIterable<AnthropicStreamEvent>,\n toolName: string | undefined,\n): AsyncGenerator<WireStreamChunk> {\n const state: StreamState = {\n toolName,\n blockKinds: new Map(),\n thinkingBlocks: new Map(),\n startUsage: undefined,\n sawJsonTool: false,\n };\n\n for await (const event of stream) {\n switch (event.type) {\n case 'message_start':\n state.startUsage = event.message.usage;\n break;\n case 'content_block_start':\n yield* onBlockStart(state, event);\n break;\n case 'content_block_delta':\n yield* onBlockDelta(state, event);\n break;\n case 'content_block_stop':\n yield* onBlockStop(state, event);\n break;\n case 'message_delta':\n yield usageChunk(state, event);\n break;\n case 'ping':\n // Resets the idle-timeout clock.\n yield { type: 'ping' };\n }\n }\n\n if (toolName && !state.sawJsonTool) throwMissingForcedJsonSchemaTool('Anthropic', toolName);\n}\n","import {\n attachRateLimitHint,\n parseAnthropicRateLimitHeaders,\n} from '../../internal/utils/rate-limit/rateLimitHint.utils.js';\nimport { rateLimitHintChunk, sendWithHeaders } from '../internal/rateLimitHeaders.js';\nimport {\n resolveEffortTokenTable,\n type EffortTokenTable,\n} from '../internal/reasoningBudget.utils.js';\nimport { readMaxRetries, sdkRetryWarning } from '../internal/sdkRetries.js';\nimport { buildAnthropicRequestBody } from './request.js';\nimport { toWireResponse } from './response.js';\nimport { toWireStreamChunks } from './stream.js';\n\nimport type { LLMClient } from '../../types/index.js';\nimport type { ModelCapabilityOverride } from '../internal/nativeStructuredOutput.js';\nimport type {\n AnthropicClient,\n AnthropicRequestBody,\n AnthropicResponse,\n AnthropicStreamEvent,\n} from './types.js';\n\n/** Optional configuration for `fromAnthropic`. */\nexport interface AnthropicAdapterOptions {\n /**\n * Models that support native structured output (`output_config.format`),\n * which can be combined with real `tools`. No default: other models\n * emulate `jsonSchema` as a forced tool call.\n */\n nativeStructuredOutputModels?: ModelCapabilityOverride;\n /** Overrides the token count each `reasoningEffort` tier maps onto. Omitted tiers keep the default. */\n reasoningEffortTokens?: Partial<EffortTokenTable>;\n /**\n * Adds models that only accept adaptive thinking, on top of the built in\n * rule (Claude Opus 4.7 and later, every Claude 5 tier model).\n */\n adaptiveOnlyModels?: ModelCapabilityOverride;\n /**\n * Replaces the built in list of models that reject a forced `tool_choice`\n * (Claude Fable 5.1 and later, Opus 5.5 and later, every Claude major 6\n * and later). On these, `toolChoice: 'required'` or `{ name }` throws\n * `unsupported_capability` before dispatch, and `jsonSchema` always uses\n * native structured output.\n */\n forcedToolChoiceUnsupportedModels?: ModelCapabilityOverride;\n /**\n * Whether `messages.create` supports `.withResponse()`, which AIMD's\n * proactive path needs. Default `false`, since a fake or thin wrapper\n * won't implement it.\n */\n supportsWithResponse?: boolean;\n}\n\n/**\n * Wraps an Anthropic SDK client as an `LLMClient`. `jsonSchema` uses native\n * structured output on covered models and a forced tool call elsewhere,\n * which can't be combined with `tools`. `json_object` throws, since\n * Anthropic can't guarantee it.\n */\nexport function fromAnthropic(\n anthropicClient: AnthropicClient,\n options?: AnthropicAdapterOptions,\n): LLMClient {\n const effortTokenTable = resolveEffortTokenTable(options?.reasoningEffortTokens);\n const supportsWithResponse = options?.supportsWithResponse ?? false;\n const warnOnSdkRetries = sdkRetryWarning(\n 'anthropic',\n () => readMaxRetries(anthropicClient),\n 'Pass maxRetries: 0 to the client',\n );\n\n const buildBody = (params: Parameters<LLMClient['chat']['completions']['create']>[0]) =>\n buildAnthropicRequestBody(\n params,\n options?.nativeStructuredOutputModels,\n effortTokenTable,\n options?.adaptiveOnlyModels,\n options?.forcedToolChoiceUnsupportedModels,\n );\n\n // The body is widened since, with `stream: true`, the SDK takes an extra\n // field and returns an iterable of events the structural type doesn't cover.\n const send = <T>(body: unknown, signal: { signal: AbortSignal }) =>\n sendWithHeaders<T>(\n () => anthropicClient.messages.create(body as AnthropicRequestBody, signal),\n supportsWithResponse,\n );\n\n return {\n // Lets core downgrade a default jsonMode to plain text instead of\n // requesting json_object, which this adapter throws on.\n supportsJsonObjectMode: false,\n // Anthropic's input rate limit skips cache reads, so the limiter must too.\n cacheReadsCountTowardRateLimit: false,\n adapter: { name: 'anthropic', provider: 'anthropic' },\n setLogger: warnOnSdkRetries,\n chat: {\n completions: {\n async create(params, requestOptions) {\n const { body, toolName } = buildBody(params);\n const { data, headers } = await send<AnthropicResponse>(body, requestOptions);\n const result = toWireResponse(data, toolName);\n\n if (headers) attachRateLimitHint(result, parseAnthropicRateLimitHeaders(headers));\n\n return result;\n },\n\n async *createStream(params, requestOptions) {\n const { body, toolName } = buildBody(params);\n const { data: stream, headers } = await send<AsyncIterable<AnthropicStreamEvent>>(\n { ...body, stream: true },\n requestOptions,\n );\n\n // Headers arrive before the body, so the hint precedes content.\n if (headers) {\n const hint = rateLimitHintChunk(parseAnthropicRateLimitHeaders(headers));\n if (hint) yield hint;\n }\n\n yield* toWireStreamChunks(stream, toolName);\n },\n },\n },\n };\n}\n","import { LLMError, type ContentBlock, type LLMClient } from '../../types/index.js';\nimport { assertSupportedImageMimeType } from '../internal/imageFormat.js';\nimport {\n budgetTokensToEffort,\n effortToBudgetTokens,\n toGeminiThinkingLevel,\n usesGeminiThinkingLevel,\n type EffortTokenTable,\n} from '../internal/reasoningBudget.utils.js';\n\nimport type { ModelCapabilityOverride } from '../internal/nativeStructuredOutput.js';\nimport type { GeminiConfig, GeminiModels, GeminiPart, GeminiRequest } from './types.js';\n\n/** Translates `ContentBlock[]` into Gemini parts, images as inline base64 data. */\nfunction toGeminiParts(blocks: ContentBlock[]): GeminiPart[] {\n return blocks.map((block) =>\n block.type === 'image'\n ? { inlineData: { mimeType: assertSupportedImageMimeType(block.mimeType), data: block.data } }\n : { text: block.text },\n );\n}\n\n/** Maps VernLLM's OpenAI-shaped wire `tool_choice` onto Gemini's `functionCallingConfig`. */\nfunction toGeminiToolConfig(\n toolChoice: Parameters<LLMClient['chat']['completions']['create']>[0]['tool_choice'],\n): NonNullable<\n NonNullable<Parameters<GeminiModels['generateContent']>[0]['config']>['toolConfig']\n> {\n const normalized = !toolChoice ? 'auto' : toolChoice;\n\n switch (normalized) {\n case 'auto':\n return { functionCallingConfig: { mode: 'AUTO' } };\n case 'none':\n return { functionCallingConfig: { mode: 'NONE' } };\n case 'required':\n return { functionCallingConfig: { mode: 'ANY' } };\n default:\n return {\n functionCallingConfig: { mode: 'ANY', allowedFunctionNames: [normalized.function.name] },\n };\n }\n}\n\n/**\n * Maps each tool call id to its function name, from the assistant turns\n * that made the calls. Ids are opaque, native or synthesized, so the name\n * is never derived from one.\n */\nfunction buildToolCallNameMap(\n messages: Parameters<LLMClient['chat']['completions']['create']>[0]['messages'],\n): Map<string, string> {\n const map = new Map<string, string>();\n\n for (const m of messages) {\n if (m.role === 'assistant') {\n for (const tc of m.tool_calls ?? []) {\n map.set(tc.id, tc.function.name);\n }\n }\n }\n\n return map;\n}\n\n/**\n * Translates one wire message into a Gemini `contents` entry. Tool requests\n * become `functionCall` parts on a model turn, results `functionResponse`\n * parts on a user turn.\n */\nfunction toGeminiContent(\n m: Extract<\n Parameters<LLMClient['chat']['completions']['create']>[0]['messages'][number],\n { role: 'user' | 'assistant' | 'tool' }\n >,\n toolCallNames: Map<string, string>,\n): { role: 'user' | 'model'; parts: GeminiPart[] } {\n if (m.role === 'tool') {\n // Gemini 3 and later correlate the response by the unchanged id.\n return {\n role: 'user',\n parts: [\n {\n functionResponse: {\n id: m.tool_call_id,\n name: toolCallNames.get(m.tool_call_id) ?? m.tool_call_id,\n response: parseToolResult(m.content),\n },\n },\n ],\n };\n }\n\n if (m.role === 'assistant' && m.tool_calls?.length) {\n const parts: GeminiPart[] = [];\n\n if (typeof m.content === 'string' && m.content) {\n parts.push({ text: m.content });\n }\n\n parts.push(\n ...m.tool_calls.map((tc) => ({\n functionCall: {\n id: tc.id,\n name: tc.function.name,\n args: parseToolArguments(tc.function.arguments, tc.function.name),\n },\n })),\n );\n\n return {\n role: 'model',\n parts,\n };\n }\n\n return {\n role: m.role === 'assistant' ? 'model' : 'user',\n parts: Array.isArray(m.content) ? toGeminiParts(m.content) : [{ text: m.content ?? '' }],\n };\n}\n\nfunction parseToolArguments(text: string, toolName: string): Record<string, unknown> {\n let parsed: unknown;\n\n try {\n parsed = text.trim() ? JSON.parse(text) : {};\n } catch (cause) {\n throw new LLMError(`Tool call \"${toolName}\" arguments are not valid JSON.`, 'parse', {\n cause,\n code: 'tool_arguments_parse_failed',\n });\n }\n\n if (!parsed || Array.isArray(parsed) || typeof parsed !== 'object') {\n throw new LLMError(`Tool call \"${toolName}\" arguments must be a JSON object.`, 'validation');\n }\n\n return parsed as Record<string, unknown>;\n}\n\n/**\n * `functionResponse.response` must be an object, so any other result, parsed\n * or not, is wrapped under `output`, Gemini's convention for it.\n */\nfunction parseToolResult(text: string): Record<string, unknown> {\n let parsed: unknown;\n\n try {\n parsed = text.trim() ? JSON.parse(text) : '';\n } catch {\n parsed = text;\n }\n\n if (parsed && !Array.isArray(parsed) && typeof parsed === 'object') {\n return parsed as Record<string, unknown>;\n }\n\n return { output: parsed };\n}\n\n/** Gemini expects parallel tool results as parts of one user entry, so a run of them is merged. */\nfunction mergeConsecutiveFunctionResponses(\n contents: { role: 'user' | 'model'; parts: GeminiPart[] }[],\n): { role: 'user' | 'model'; parts: GeminiPart[] }[] {\n const isFunctionResponseOnly = (\n c: (typeof contents)[number],\n ): c is { role: 'user'; parts: GeminiPart[] } =>\n c.role === 'user' && c.parts.length > 0 && c.parts.every((p) => 'functionResponse' in p);\n\n const merged: (typeof contents)[number][] = [];\n\n for (const c of contents) {\n const prev = merged.at(-1);\n\n if (isFunctionResponseOnly(c) && prev && isFunctionResponseOnly(prev)) {\n prev.parts.push(...c.parts);\n } else {\n merged.push(c);\n }\n }\n\n return merged;\n}\n\n/**\n * Gemini's `thinkingConfig` for a request, `undefined` when no reasoning was\n * asked for. Gemini 3 still accepts thinkingBudget, but Google warns it \"may\n * result in unexpected performance\", so thinkingLevel is sent there. 0 and\n * -1 have no level, and collapse to MINIMAL, the closest to off. Earlier\n * models get thinkingBudget, where 0 (off) and -1 (automatic) pass through\n * unchanged.\n */\nfunction resolveGeminiThinking(\n params: Parameters<LLMClient['chat']['completions']['create']>[0],\n effortTokenTable?: EffortTokenTable,\n thinkingLevelModels?: ModelCapabilityOverride,\n): GeminiConfig['thinkingConfig'] {\n if (usesGeminiThinkingLevel(params.model, thinkingLevelModels)) {\n const effortTier =\n params.reasoning_effort ??\n (params.budget_tokens !== undefined\n ? budgetTokensToEffort(params.budget_tokens, effortTokenTable)\n : undefined);\n\n return effortTier === undefined\n ? undefined\n : { thinkingLevel: toGeminiThinkingLevel(effortTier, params.model) };\n }\n\n const thinkingBudget =\n params.budget_tokens ??\n (params.reasoning_effort\n ? effortToBudgetTokens(params.reasoning_effort, effortTokenTable)\n : undefined);\n\n return thinkingBudget === undefined ? undefined : { thinkingBudget };\n}\n\n/** Builds the request shared by `create` and `createStream`, which add `abortSignal`. */\nexport function buildGeminiRequest(\n params: Parameters<LLMClient['chat']['completions']['create']>[0],\n effortTokenTable?: EffortTokenTable,\n thinkingLevelModels?: ModelCapabilityOverride,\n): GeminiRequest {\n const systemMessage = params.messages.find((m) => m.role === 'system');\n const conversationMessages = params.messages.filter(\n (m) => m.role === 'user' || m.role === 'assistant' || m.role === 'tool',\n );\n\n const wantsJson = Boolean(params.response_format);\n const config: GeminiConfig = {\n ...(params.temperature !== undefined ? { temperature: params.temperature } : {}),\n maxOutputTokens: params.max_tokens,\n ...(systemMessage\n ? // System turns are always plain strings; only user turns can carry ContentBlock[]\n { systemInstruction: { parts: [{ text: systemMessage.content as string }] } }\n : {}),\n };\n\n if (wantsJson) {\n config.responseMimeType = 'application/json';\n }\n\n if (params.response_format?.type === 'json_schema') {\n const { schema, description } = params.response_format.json_schema;\n\n config.responseSchema = {\n ...schema,\n ...(description ? { description } : {}),\n };\n }\n\n if (params.tools?.length) {\n config.tools = [\n {\n functionDeclarations: params.tools.map((t) => ({\n name: t.function.name,\n description: t.function.description,\n parameters: t.function.parameters,\n })),\n },\n ];\n config.toolConfig = toGeminiToolConfig(params.tool_choice);\n }\n\n const thinkingConfig = resolveGeminiThinking(params, effortTokenTable, thinkingLevelModels);\n if (thinkingConfig) config.thinkingConfig = thinkingConfig;\n\n const toolCallNames = buildToolCallNameMap(conversationMessages);\n\n return {\n model: params.model,\n contents: mergeConsecutiveFunctionResponses(\n conversationMessages.map((m) => toGeminiContent(m, toolCallNames)),\n ),\n config,\n };\n}\n","import { finishReason } from '../internal/finishReason.js';\n\nimport type { WireToolCall } from '../../types/index.js';\nimport type { GeminiResponse, GeminiUsage } from './types.js';\n\n/**\n * An id for a functionCall Gemini gave none, as before Gemini 3. The\n * occurrence index keeps repeated calls to one tool in a turn distinct.\n */\nexport function synthesizeToolCallId(name: string, occurrenceIndex: number): string {\n return `${name}#${occurrenceIndex}`;\n}\n\n/** Maps Gemini's usage metadata onto the wire usage shape. */\nexport function toWireUsage(usage: GeminiUsage | undefined) {\n return {\n prompt_tokens: usage?.promptTokenCount,\n completion_tokens: usage?.candidatesTokenCount,\n total_tokens: usage?.totalTokenCount,\n prompt_tokens_details: { cached_tokens: usage?.cachedContentTokenCount },\n ...(usage?.thoughtsTokenCount !== undefined\n ? { completion_tokens_details: { reasoning_tokens: usage.thoughtsTokenCount } }\n : {}),\n };\n}\n\n/** Maps a Gemini response onto the wire response, naming each function call. */\nexport function toWireResponse(response: GeminiResponse) {\n const parts = response.candidates?.[0]?.content?.parts ?? [];\n const text = parts.map((p) => p.text ?? '').join('');\n const functionCalls = parts.filter((p) => p.functionCall);\n\n let wireToolCalls: WireToolCall[] | undefined;\n\n if (functionCalls.length) {\n const nameOccurrence = new Map<string, number>();\n\n wireToolCalls = functionCalls.map((p) => {\n // INVARIANT: typed optional like the SDK, but Gemini always\n // names a function call part.\n const name = p.functionCall!.name!;\n const nativeId = p.functionCall!.id;\n const occurrenceIndex = nameOccurrence.get(name) ?? 0;\n nameOccurrence.set(name, occurrenceIndex + 1);\n\n return {\n // Gemini 3 and later send a native id; earlier models get\n // one synthesized.\n id: nativeId ?? synthesizeToolCallId(name, occurrenceIndex),\n type: 'function' as const,\n function: {\n name,\n arguments: JSON.stringify(p.functionCall!.args ?? {}),\n },\n };\n });\n }\n\n return {\n choices: [\n {\n message: { content: text, ...(wireToolCalls ? { tool_calls: wireToolCalls } : {}) },\n ...finishReason(response.candidates?.[0]?.finishReason, 'MAX_TOKENS'),\n },\n ],\n usage: toWireUsage(response.usageMetadata),\n };\n}\n","import { synthesizeToolCallId, toWireUsage } from './response.js';\n\nimport type { WireStreamChunk } from '../../types/index.js';\nimport type { GeminiStream, GeminiUsage } from './types.js';\n\n/**\n * Translates Gemini's partial responses into wire chunks. Function calls\n * arrive whole, so each is one complete `tool_call_delta`.\n */\nexport async function* toWireStreamChunks(stream: GeminiStream): AsyncGenerator<WireStreamChunk> {\n let toolCallIndex = 0;\n const nameOccurrence = new Map<string, number>();\n let lastUsage: GeminiUsage | undefined;\n\n for await (const chunk of stream) {\n const parts = chunk.candidates?.[0]?.content?.parts ?? [];\n\n for (const part of parts) {\n if (part.text) {\n yield { type: 'text-delta', delta: part.text };\n }\n\n if (part.functionCall) {\n const name = part.functionCall.name;\n const nativeId = part.functionCall.id;\n const occurrenceIndex = name ? (nameOccurrence.get(name) ?? 0) : 0;\n if (name) nameOccurrence.set(name, occurrenceIndex + 1);\n\n yield {\n type: 'tool_call_delta',\n index: toolCallIndex,\n id: nativeId ?? (name ? synthesizeToolCallId(name, occurrenceIndex) : undefined),\n name: part.functionCall.name,\n argumentsDelta: JSON.stringify(part.functionCall.args ?? {}),\n // INVARIANT: Gemini sends each call's args whole, never\n // incrementally. The \"INVARIANT: hardcodes complete: true\"\n // stream test guards this.\n complete: true,\n } satisfies WireStreamChunk;\n toolCallIndex++;\n }\n }\n\n if (chunk.usageMetadata) {\n lastUsage = chunk.usageMetadata;\n }\n }\n\n // Gemini only reliably reports usage on the last chunk.\n if (lastUsage) {\n yield { type: 'usage', usage: toWireUsage(lastUsage) };\n }\n}\n","import { unsupportedCapability } from '../internal/errors.js';\nimport {\n resolveEffortTokenTable,\n type EffortTokenTable,\n} from '../internal/reasoningBudget.utils.js';\nimport { sdkRetryWarning } from '../internal/sdkRetries.js';\nimport { buildGeminiRequest } from './request.js';\nimport { toWireResponse } from './response.js';\nimport { toWireStreamChunks } from './stream.js';\n\nimport type { LLMClient } from '../../types/index.js';\nimport type { ModelCapabilityOverride } from '../internal/nativeStructuredOutput.js';\nimport type { GeminiClient, GeminiModels } from './types.js';\n\n/** Optional configuration for `fromGemini`. */\nexport interface GeminiAdapterOptions {\n /** Overrides the token count each `reasoningEffort` tier maps onto. Omitted tiers keep the default. */\n reasoningEffortTokens?: Partial<EffortTokenTable>;\n /**\n * Adds models that use `thinkingLevel` instead of `thinkingBudget`, on top\n * of the built in rule (Gemini 3 and later).\n */\n thinkingLevelModels?: ModelCapabilityOverride;\n}\n\n/** A client built by hand may leave `vertexai` unset, so no provider is claimed for it. */\nfunction geminiProvider(client: GeminiClient): { provider?: string } {\n if (client.vertexai === true) return { provider: 'gcp.vertex_ai' };\n if (client.vertexai === false) return { provider: 'gcp.gemini' };\n return {};\n}\n\n/**\n * Retries the client makes on its own. `@google/genai` only retries when\n * `httpOptions.retryOptions` is set, and then `attempts`, which counts the\n * first call, defaults to 5. The SDK types `httpOptions` as private, so it is\n * read structurally.\n */\nfunction geminiRetries(client: GeminiClient): number | undefined {\n const retryOptions = (client as { httpOptions?: { retryOptions?: { attempts?: unknown } } })\n .httpOptions?.retryOptions;\n if (!retryOptions || typeof retryOptions !== 'object') return undefined;\n\n // Mirrors the SDK's own `Math.max(1, attempts)`, so a numeric string from untyped config counts\n // the way the SDK counts it, and anything else becomes NaN, which never warns.\n return Math.max(1, Number(retryOptions.attempts ?? 5)) - 1;\n}\n\n/**\n * Wraps the top level `@google/genai` client as an `LLMClient`. `ai.models`\n * throws at construction, since only the top level client says whether it\n * talks to Vertex AI or the Gemini API. `responseSchema` and `tools` combine\n * natively.\n */\nexport function fromGemini(client: GeminiClient, options?: GeminiAdapterOptions): LLMClient {\n const effortTokenTable = resolveEffortTokenTable(options?.reasoningEffortTokens);\n const thinkingLevelModels = options?.thinkingLevelModels;\n // `ai.models` has generateContent itself and no `models`. Checked at runtime\n // since plain JS callers get no type error for it.\n const models: GeminiModels | undefined = client.models;\n if (!models && typeof (client as Partial<GeminiModels>).generateContent === 'function') {\n throw unsupportedCapability(\n 'fromGemini takes the top level client: pass ai (new GoogleGenAI(...)), not ai.models.',\n 'top_level_client',\n );\n }\n\n if (typeof models?.generateContent !== 'function') {\n throw unsupportedCapability(\n 'fromGemini requires a client with models.generateContent: pass ai (new GoogleGenAI(...)).',\n 'generateContent',\n );\n }\n\n const warnOnSdkRetries = sdkRetryWarning(\n 'gemini',\n () => geminiRetries(client),\n 'Remove httpOptions.retryOptions from the client, or set its attempts to 1,',\n );\n\n const generateContent = models.generateContent.bind(models);\n const generateContentStream =\n typeof models.generateContentStream === 'function'\n ? models.generateContentStream.bind(models)\n : undefined;\n\n return {\n adapter: { name: 'gemini', ...geminiProvider(client) },\n setLogger: warnOnSdkRetries,\n chat: {\n completions: {\n async create(params, options) {\n const request = buildGeminiRequest(params, effortTokenTable, thinkingLevelModels);\n request.config = { ...request.config, abortSignal: options.signal };\n\n const response = await generateContent(request);\n\n return toWireResponse(response);\n },\n\n async *createStream(params, options) {\n if (!generateContentStream) {\n throw unsupportedCapability(\n 'stream: true requires a Gemini client with generateContentStream',\n 'generateContentStream',\n );\n }\n\n const request = buildGeminiRequest(params, effortTokenTable, thinkingLevelModels);\n request.config = { ...request.config, abortSignal: options.signal };\n\n const stream = await generateContentStream(request);\n\n yield* toWireStreamChunks(stream);\n },\n },\n },\n };\n}\n","import { LLMError } from '../../types/errors.js';\n\n/**\n * Parses a Server-Sent-Events stream of bytes or text into each frame's\n * JSON `data:` payload, in order, over any transport. Multi-line data is\n * joined with `\\n`, comment-only frames yield `SSE_PING`, other fields are\n * ignored, and a `[DONE]` frame ends iteration. `\\r\\n` and bare `\\r` count\n * as line endings, including a `\\r\\n` split across two chunks. Malformed\n * JSON throws `LLMError('parse')`.\n */\nexport async function* parseSseStream(\n source: AsyncIterable<Uint8Array | string>,\n): AsyncGenerator<unknown> {\n // `fatal: true` makes invalid UTF-8 throw instead of silently decoding\n // to U+FFFD replacement characters, which could otherwise land inside a\n // JSON string and either corrupt it unnoticeably or, worse, still parse\n // as syntactically valid JSON with silently-wrong content.\n const decoder = new TextDecoder('utf-8', { fatal: true });\n const framer = createFrameSplitter();\n\n for await (const chunk of source) {\n let text: string;\n\n try {\n text = typeof chunk === 'string' ? chunk : decoder.decode(chunk, { stream: true });\n } catch (cause) {\n throw new LLMError('Invalid UTF-8 in SSE stream', 'parse', { cause });\n }\n\n for (const frame of framer.push(text)) {\n const event = parseSseFrame(frame);\n\n if (event === DONE) return;\n if (event !== NO_DATA) yield event;\n }\n }\n\n // Flush any bytes TextDecoder held back mid-decode, so a truncated\n // multi-byte char surfaces as a parse error instead of silently\n // vanishing (and possibly leaving behind valid-looking, wrong JSON).\n let tail: string;\n\n try {\n tail = decoder.decode();\n } catch (cause) {\n throw new LLMError('Invalid UTF-8 in SSE stream', 'parse', { cause });\n }\n\n const { frames, trailing } = framer.end(tail);\n\n for (const frame of frames) {\n const event = parseSseFrame(frame);\n\n if (event === DONE) return;\n if (event !== NO_DATA) yield event;\n }\n\n // Flush a final frame that arrived without a trailing blank line: some\n // servers close the connection right after the last `data:` line instead\n // of sending one more `\\n\\n` first.\n const rest = trailing.trim();\n\n if (rest) {\n const event = parseSseFrame(rest);\n\n if (event !== DONE && event !== NO_DATA) yield event;\n }\n}\n\n/**\n * Splits normalized SSE text into complete frames. Only newly arrived text\n * is normalized and scanned, and an incomplete frame is kept as a list of\n * pieces joined once when it completes, so a large frame spread over many\n * transport chunks costs linear time instead of rescanning the whole\n * buffer on every chunk.\n */\nfunction createFrameSplitter() {\n let parts: string[] = [];\n // Whether the incomplete frame ends in `\\n`, so a `\\n` at the start of\n // the next text completes a blank line boundary across the two pieces.\n let endsWithLf = false;\n // A trailing `\\r` is held back until more text arrives, since it may be\n // the first half of a `\\r\\n` pair split across two transport chunks.\n let heldCr = false;\n\n function split(raw: string): string[] {\n let text = heldCr ? `\\r${raw}` : raw;\n\n heldCr = text.endsWith('\\r');\n if (heldCr) text = text.slice(0, -1);\n\n text = text.replace(/\\r\\n?/g, '\\n');\n\n const frames: string[] = [];\n let pos = 0;\n\n if (endsWithLf && text.startsWith('\\n')) {\n frames.push(parts.join('').slice(0, -1));\n parts = [];\n endsWithLf = false;\n pos = 1;\n }\n\n let boundary = text.indexOf('\\n\\n', pos);\n\n while (boundary !== -1) {\n parts.push(text.slice(pos, boundary));\n frames.push(parts.join(''));\n parts = [];\n pos = boundary + 2;\n boundary = text.indexOf('\\n\\n', pos);\n }\n\n const rest = text.slice(pos);\n\n if (rest) {\n parts.push(rest);\n endsWithLf = rest.endsWith('\\n');\n } else if (pos > 0) {\n // A boundary emptied `parts`, so nothing is left to end in `\\n`.\n endsWithLf = false;\n }\n\n return frames;\n }\n\n return {\n push: split,\n /** The stream ended, so a held `\\r` can only be a bare CR line ending now. */\n end(tail: string): { frames: string[]; trailing: string } {\n const frames = split(tail);\n\n if (heldCr) {\n heldCr = false;\n frames.push(...split('\\n'));\n }\n\n return { frames, trailing: parts.join('') };\n },\n };\n}\n\nconst DONE = Symbol('sse-stream-done');\nconst NO_DATA = Symbol('sse-frame-no-data');\n\n/**\n * Yielded for a comment-only frame, the SSE keep-alive ping, so a consumer\n * can tell \"still alive\" apart from an empty frame.\n */\nexport const SSE_PING = Symbol('sse-frame-ping');\n\n/** Extracts and JSON-parses the `data:` payload of one SSE frame (the text between two blank lines). */\nfunction parseSseFrame(frame: string): unknown {\n const dataLines: string[] = [];\n let sawComment = false;\n\n for (const line of frame.split('\\n')) {\n if (line.startsWith(':')) {\n sawComment = true; // comment line, also used as a keep-alive ping\n continue;\n }\n if (!line.startsWith('data:')) continue; // ignore event:/id:/retry:/blank lines\n\n // A single space after the colon is stripped per the SSE spec; further\n // leading whitespace is preserved as part of the payload.\n dataLines.push(line.startsWith('data: ') ? line.slice(6) : line.slice(5));\n }\n\n if (!dataLines.length) return sawComment ? SSE_PING : NO_DATA;\n\n const data = dataLines.join('\\n');\n\n if (data === '[DONE]') return DONE;\n\n try {\n return JSON.parse(data);\n } catch (cause) {\n throw new LLMError(`Invalid JSON in SSE frame: ${data.slice(0, 200)}`, 'parse', {\n cause,\n code: 'stream_frame_invalid',\n });\n }\n}\n","import type { WireToolCall } from '../../types/index.js';\nimport type { FetchAdapterConfig } from './types.js';\n\ntype MappedUsage = NonNullable<ReturnType<FetchAdapterConfig['mapResponse']>['usage']>;\n\nfunction hasCacheCounts(usage: MappedUsage): boolean {\n return (\n usage.cacheReadTokens !== undefined ||\n usage.cacheWriteTokens !== undefined ||\n usage.cacheWriteTokensByTtl !== undefined\n );\n}\n\n/** Maps what `mapResponse` returned onto the wire response. */\nexport function toWireResponse(mapped: ReturnType<FetchAdapterConfig['mapResponse']>) {\n const { content, usage, toolCalls } = mapped;\n\n // An empty array means no tool calls, the same as undefined.\n const wireToolCalls: WireToolCall[] | undefined = toolCalls?.length\n ? toolCalls.map((tc) => ({\n id: tc.id,\n type: 'function' as const,\n function: { name: tc.name, arguments: tc.arguments },\n }))\n : undefined;\n\n return {\n choices: [\n {\n message: {\n content,\n ...(wireToolCalls ? { tool_calls: wireToolCalls } : {}),\n },\n },\n ],\n usage: usage\n ? {\n prompt_tokens: usage.promptTokens,\n completion_tokens: usage.completionTokens,\n total_tokens: usage.totalTokens,\n ...(hasCacheCounts(usage)\n ? {\n prompt_tokens_details: {\n cached_tokens: usage.cacheReadTokens,\n cache_write_tokens: usage.cacheWriteTokens,\n cache_write_tokens_by_ttl: usage.cacheWriteTokensByTtl,\n },\n }\n : {}),\n }\n : undefined,\n };\n}\n","import { SSE_PING } from '../internal/sse.js';\n\nimport type { WireStreamChunk } from '../../types/index.js';\nimport type { FetchAdapterConfig } from './types.js';\n\n/** Maps each parsed stream event through `mapStreamEvent`, skipping events it drops. */\nexport async function* toWireStreamChunks(\n events: AsyncIterable<unknown>,\n mapStreamEvent: NonNullable<FetchAdapterConfig['mapStreamEvent']>,\n): AsyncGenerator<WireStreamChunk> {\n for await (const event of events) {\n // Handled here so `mapStreamEvent` never needs to know SSE framing.\n if (event === SSE_PING) {\n yield { type: 'ping' };\n continue;\n }\n\n const wireChunks = mapStreamEvent(event);\n\n if (!wireChunks) continue;\n\n if (Array.isArray(wireChunks)) {\n yield* wireChunks;\n } else {\n yield wireChunks;\n }\n }\n}\n","import {\n parseOpenAIRateLimitHeaders,\n type ProviderRateLimitHint,\n} from '../../internal/utils/rate-limit/rateLimitHint.utils.js';\nimport { httpResponseError, unsupportedCapability } from '../internal/errors.js';\n\nimport type { ChatRequest, FetchAdapterConfig, ResponseLike } from './types.js';\n\n/**\n * Makes a `ReadableStream` iterable through `getReader()`, since native\n * `Symbol.asyncIterator` support varies across runtimes.\n */\nasync function* webStreamToAsyncIterable(\n stream: ReadableStream<Uint8Array>,\n): AsyncGenerator<Uint8Array> {\n const reader = stream.getReader();\n\n try {\n for (;;) {\n const { done, value } = await reader.read();\n\n if (done) return;\n if (value) yield value;\n }\n } finally {\n // Cancel before releasing the lock so a consumer that stops early still\n // tells the source to stop. An already-errored stream rejects cancel(),\n // which is of no use to the caller here.\n try {\n await reader.cancel();\n } catch {\n // Ignore: the stream may already be errored/closed.\n }\n\n reader.releaseLock();\n }\n}\n\n/**\n * The default streaming transport, native `fetch`, which also returns the\n * response headers for AIMD's proactive hint. A custom `requestStream` only\n * returns bytes, so it gets no proactive hint.\n */\nasync function defaultRequestStreamWithHeaders(\n url: string,\n init: { method: string; headers: Record<string, string>; body?: string; signal?: AbortSignal },\n): Promise<{ headers: ResponseLike['headers']; body: AsyncIterable<Uint8Array | string> }> {\n const res = await fetch(url, init);\n\n if (!res.ok) {\n const body = await res.text().catch(() => '');\n throw httpResponseError('Fetch adapter stream request failed', res, body);\n }\n\n if (!res.body) {\n throw new Error('Fetch adapter stream request received a response with no body.');\n }\n\n return { headers: res.headers, body: webStreamToAsyncIterable(res.body) };\n}\n\n/** Builds the shared `{ method, headers, body? }` request-init for both `create` and `createStream`. */\nasync function buildRequestInit(\n config: FetchAdapterConfig,\n params: ChatRequest,\n requestBody: unknown,\n): Promise<{ url: string; method: string; headers: Record<string, string>; body?: string }> {\n const url = typeof config.url === 'function' ? config.url(params) : config.url;\n const headers = typeof config.headers === 'function' ? await config.headers() : config.headers;\n const method = config.method ?? 'POST';\n\n // GET and HEAD can't carry a body, so neither it nor Content-Type is sent.\n const supportsBody = !['GET', 'HEAD'].includes(method.toUpperCase());\n\n return {\n url,\n method,\n headers: supportsBody ? { 'Content-Type': 'application/json', ...headers } : { ...headers },\n ...(supportsBody ? { body: JSON.stringify(requestBody) } : {}),\n };\n}\n\n/** Sends the request through `config.request`, native `fetch` by default, and throws on a non-2xx. */\nexport async function requestOnce(\n config: FetchAdapterConfig,\n params: ChatRequest,\n signal: AbortSignal,\n): Promise<ResponseLike> {\n const { url, method, headers, body } = await buildRequestInit(\n config,\n params,\n config.mapRequest(params),\n );\n const request = config.request ?? fetch;\n\n const res = await request(url, { method, headers, body, signal });\n\n if (!res.ok) {\n const responseBody = await res.text().catch(() => '');\n throw httpResponseError('Fetch adapter request failed', res, responseBody);\n }\n\n return res;\n}\n\n/**\n * Opens the streaming request, through `config.requestStream` or native\n * `fetch`. Only native `fetch` reports headers.\n */\nexport async function openStream(\n config: FetchAdapterConfig,\n params: ChatRequest,\n signal: AbortSignal,\n): Promise<{ headers?: ResponseLike['headers']; body: AsyncIterable<Uint8Array | string> }> {\n // Falling back to native fetch would quietly bypass whatever the custom\n // `request` is for (a proxy, auth, a test's mock), so this fails instead\n // of guessing.\n if (config.request && !config.requestStream) {\n throw unsupportedCapability(\n '`stream: true` requires `requestStream` to be configured on fromFetch when a ' +\n 'custom `request` transport is set. `requestStream` does not fall back to ' +\n \"`request` (it needs an async-iterable byte stream, which `RequestLike`'s \" +\n 'buffered `ResponseLike` has no way to provide), without it, `stream: true` ' +\n 'would silently use plain native `fetch` instead of your configured transport. ' +\n 'Add a `requestStream` that opens the same connection your `request` does, or ' +\n 'omit `request` if native `fetch` is fine for both.',\n 'requestStream',\n );\n }\n\n const { url, method, headers, body } = await buildRequestInit(\n config,\n params,\n config.mapRequest(params),\n );\n const init = { method, headers, body, signal };\n\n if (config.requestStream) return { body: await config.requestStream(url, init) };\n return defaultRequestStreamWithHeaders(url, init);\n}\n\n/**\n * AIMD's proactive hint from response headers, `undefined` without them. A\n * test double may omit `headers` despite `ResponseLike` declaring it.\n */\nexport function readRateLimitHint(\n config: FetchAdapterConfig,\n headers: ResponseLike['headers'] | undefined,\n): ProviderRateLimitHint | undefined {\n if (!headers || typeof headers.get !== 'function') return undefined;\n return (config.parseRateLimitHint ?? parseOpenAIRateLimitHeaders)(headers);\n}\n","import { attachRateLimitHint } from '../../internal/utils/rate-limit/rateLimitHint.utils.js';\nimport { unsupportedCapability } from '../internal/errors.js';\nimport { rateLimitHintChunk } from '../internal/rateLimitHeaders.js';\nimport { parseSseStream } from '../internal/sse.js';\nimport { toWireResponse } from './response.js';\nimport { toWireStreamChunks } from './stream.js';\nimport { openStream, readRateLimitHint, requestOnce } from './transport.js';\n\nimport type { LLMClient } from '../../types/index.js';\nimport type { FetchAdapterConfig } from './types.js';\n\n/**\n * A raw HTTP adapter for providers with no SDK: supply the URL, headers,\n * and the request and response mapping. A non-2xx response throws an error\n * carrying `status` and `headers`, so retries, `nonRetryableStatus` and\n * Retry-After all apply.\n */\nexport function fromFetch(config: FetchAdapterConfig): LLMClient {\n return {\n adapter: {\n name: 'fetch',\n ...(typeof config.provider === 'string' && config.provider.trim() !== ''\n ? { provider: config.provider }\n : {}),\n },\n chat: {\n completions: {\n async create(params, options) {\n const res = await requestOnce(config, params, options.signal);\n const result = toWireResponse(config.mapResponse(await res.json()));\n\n attachRateLimitHint(result, readRateLimitHint(config, res.headers));\n\n return result;\n },\n\n async *createStream(params, options) {\n const { mapStreamEvent } = config;\n\n if (!mapStreamEvent) {\n throw unsupportedCapability(\n 'stream: true requires mapStreamEvent to be configured on fromFetch',\n 'mapStreamEvent',\n );\n }\n\n const parseFrames = config.parseStreamFrames ?? parseSseStream;\n const opened = await openStream(config, params, options.signal);\n const hint = readRateLimitHint(config, opened.headers);\n const hintChunk = hint && rateLimitHintChunk(hint);\n\n if (hintChunk) yield hintChunk;\n\n yield* toWireStreamChunks(parseFrames(opened.body), mapStreamEvent);\n },\n },\n },\n };\n}\n","/** Hosts whose provider is unambiguous. A gateway or proxy host is never listed. */\nconst PROVIDER_BY_HOST: ReadonlyArray<[RegExp, string]> = [\n [/^api\\.openai\\.com$/, 'openai'],\n [/\\.openai\\.azure\\.com$/, 'azure.ai.openai'],\n [/^api\\.groq\\.com$/, 'groq'],\n [/^api\\.mistral\\.ai$/, 'mistral_ai'],\n [/^api\\.deepseek\\.com$/, 'deepseek'],\n [/^api\\.x\\.ai$/, 'x_ai'],\n [/^api\\.perplexity\\.ai$/, 'perplexity'],\n];\n\n/** The provider for an OpenAI compatible client, from the option or its `baseURL`. */\nexport function openAICompatibleProvider(\n client: unknown,\n provider: string | undefined,\n): string | undefined {\n if (typeof provider === 'string' && provider.trim() !== '') return provider;\n\n const baseURL = (client as { baseURL?: unknown }).baseURL;\n if (typeof baseURL !== 'string') return undefined;\n\n let host: string;\n try {\n host = new URL(baseURL).hostname.toLowerCase();\n } catch {\n return undefined;\n }\n\n return PROVIDER_BY_HOST.find(([pattern]) => pattern.test(host))?.[1];\n}\n","import { unsupportedCapability } from '../internal/errors.js';\nimport { budgetTokensToEffort, type EffortTokenTable } from '../internal/reasoningBudget.utils.js';\n\nimport type { Logger } from '../../logger.js';\nimport type { LLMClient } from '../../types/index.js';\nimport type { ModelCapabilityOverride } from '../internal/nativeStructuredOutput.js';\nimport type { OpenAIWireReasoningEffort } from './types.js';\n\n/**\n * Built in rule for models that only take `tools` on Chat Completions with\n * `reasoning_effort: \"none\"`: bare `gpt-` ids of major 6 and later, except\n * `-chat` ids. A gateway id is left alone, since the gateway decides what\n * it forwards.\n */\nfunction isDefaultNoReasoningToolModel(model: string): boolean {\n if (/-chat/.test(model)) return false;\n\n const gptMajor = /^gpt-(\\d+)/.exec(model)?.[1];\n return gptMajor !== undefined && Number(gptMajor) >= 6;\n}\n\n/** Whether `model` needs `reasoning_effort: \"none\"` to take tools. `override` replaces the built in rule. */\nfunction needsNoReasoningForTools(model: string, override?: ModelCapabilityOverride): boolean {\n if (!override) return isDefaultNoReasoningToolModel(model);\n\n return Array.isArray(override) ? override.includes(model) : override(model);\n}\n\n/**\n * Whether this request must go out with `reasoning_effort: \"none\"`. Reasoning\n * that was asked for, an instance default included, throws instead of being\n * dropped, since dropping it would change output quality with no signal.\n */\nexport function requiresNoReasoning(\n params: Parameters<LLMClient['chat']['completions']['create']>[0],\n override: ModelCapabilityOverride | undefined,\n): boolean {\n if (!params.tools?.length || !needsNoReasoningForTools(params.model, override)) return false;\n\n if (params.reasoning_effort !== undefined || params.budget_tokens !== undefined) {\n throw unsupportedCapability(\n `OpenAI model \"${params.model}\" only accepts tools on Chat Completions with ` +\n 'reasoning_effort \"none\", but this call asks for reasoning through reasoningEffort or ' +\n 'budgetTokens (an instance default counts). Pass reasoningEffort: null and budgetTokens: ' +\n 'null for this call, or use the Responses API for reasoning with tools.',\n 'tools_with_reasoning',\n );\n }\n\n return true;\n}\n\n/** Sets `reasoning_effort: \"none\"` when `apply` is true, logging it once for this request. */\nexport function withNoReasoning<P extends { model: string }>(\n params: P,\n apply: boolean,\n logger: Logger | undefined,\n): P & { reasoning_effort?: OpenAIWireReasoningEffort } {\n if (!apply) return params;\n\n logger?.debug(\n `[VernLLM] ${params.model}: sending reasoning_effort \"none\", required for tools on Chat Completions`,\n );\n return { ...params, reasoning_effort: 'none' };\n}\n\n/**\n * OpenAI only understands `reasoning_effort`, so a lone `budget_tokens` is\n * converted to the nearest tier and dropped from the request.\n */\nexport function applyReasoningBudget<\n P extends { reasoning_effort?: 'minimal' | 'low' | 'medium' | 'high'; budget_tokens?: number },\n>(params: P, effortTokenTable?: EffortTokenTable): P {\n if (params.budget_tokens === undefined) return params;\n\n const { budget_tokens, ...rest } = params;\n\n return rest.reasoning_effort !== undefined\n ? (rest as P)\n : ({ ...rest, reasoning_effort: budgetTokensToEffort(budget_tokens, effortTokenTable) } as P);\n}\n\n/**\n * Whether `model` is an OpenAI reasoning model: the o-series and every GPT\n * generation from 5 on, matched as a version threshold so later generations\n * need no change. `-chat` ids are excluded, and a gateway id is left for the\n * gateway to normalize, since many providers here still expect `max_tokens`.\n */\nfunction isOpenAIReasoningModel(model: string): boolean {\n if (/-chat/.test(model)) return false;\n if (/^o\\d/.test(model)) return true;\n\n const gptMajor = /^gpt-(\\d+)/.exec(model)?.[1];\n return gptMajor !== undefined && Number(gptMajor) >= 5;\n}\n\n/**\n * OpenAI reasoning models need `max_completion_tokens` instead of\n * `max_tokens` and reject a non-default `temperature`, which VernLLM always\n * sends, so both are rewritten.\n */\nexport function applyReasoningModelParams<\n P extends { model: string; max_tokens: number; temperature?: number },\n>(params: P): P {\n if (!isOpenAIReasoningModel(params.model)) return params;\n\n const { max_tokens, temperature: _temperature, ...rest } = params;\n\n return { ...rest, max_completion_tokens: max_tokens } as unknown as P;\n}\n","import { assertSupportedImageMimeType } from '../internal/imageFormat.js';\n\nimport type { ContentBlock, LLMClient } from '../../types/index.js';\nimport type { OpenAIContentPart } from './types.js';\n\n/** Translates `ContentBlock[]` into OpenAI content parts, images as inline `data:` URLs. */\nfunction toOpenAIContent(blocks: ContentBlock[]): OpenAIContentPart[] {\n return blocks.map((block) =>\n block.type === 'image'\n ? {\n type: 'image_url',\n image_url: {\n url: `data:${assertSupportedImageMimeType(block.mimeType)};base64,${block.data}`,\n },\n }\n : { type: 'text', text: block.text },\n );\n}\n\n/** Translates wire `messages` into OpenAI's shape, the one part of a request that isn't passed through. */\nexport function toOpenAIMessages(\n params: Parameters<LLMClient['chat']['completions']['create']>[0],\n): unknown[] {\n return params.messages.map((m) => {\n if (m.role === 'user' && Array.isArray(m.content)) {\n return { ...m, content: toOpenAIContent(m.content) };\n }\n\n if (m.role === 'tool') {\n const { is_error: isError, ...openAIToolMessage } = m;\n // OpenAI's tool message has no error field, so the failure is kept in\n // the content itself rather than dropped, or the model would read a\n // failed tool's output as a success.\n return isError\n ? { ...openAIToolMessage, content: `Error: ${openAIToolMessage.content}` }\n : openAIToolMessage;\n }\n\n // Only Claude understands reasoning blocks; OpenAI rejects unknown message fields.\n if (m.role === 'assistant' && m.thinking) {\n const { thinking: _thinking, ...openAIAssistantMessage } = m;\n return openAIAssistantMessage;\n }\n\n return m;\n });\n}\n\n/**\n * OpenAI rejects `json_object` unless a message mentions \"json\", and VernLLM\n * defaults `jsonMode` to `true`, so a short system instruction is prepended\n * when no message does.\n */\nexport function ensureJsonKeyword(\n messages: unknown[],\n responseFormat: Parameters<LLMClient['chat']['completions']['create']>[0]['response_format'],\n): unknown[] {\n if (responseFormat?.type !== 'json_object') return messages;\n\n // Only text is checked: base64 image data can contain \"json\" by chance,\n // which would skip the instruction while OpenAI still rejects the call.\n const mentionsJson = messages.some((m) => {\n const content = (m as { content?: unknown }).content;\n const parts = Array.isArray(content) ? content : [content];\n\n return parts.some((part) => {\n const text = typeof part === 'string' ? part : (part as { text?: unknown } | null)?.text;\n return typeof text === 'string' && /json/i.test(text);\n });\n });\n\n return mentionsJson\n ? messages\n : [{ role: 'system', content: 'Respond with a valid JSON object.' }, ...messages];\n}\n","import type { OpenAIUsage } from './types.js';\n\n/** Fills `cached_tokens` from DeepSeek's `prompt_cache_hit_tokens` when missing. */\nexport function normalizeUsage<T extends OpenAIUsage>(usage: T): T {\n const cached = usage.prompt_tokens_details?.cached_tokens ?? usage.prompt_cache_hit_tokens;\n\n if (cached === undefined) return usage;\n\n return {\n ...usage,\n prompt_tokens_details: { ...usage.prompt_tokens_details, cached_tokens: cached },\n };\n}\n","import { normalizeUsage } from './usage.js';\n\nimport type { WireStreamChunk } from '../../types/index.js';\nimport type { OpenAIStreamChunk } from './types.js';\n\n/**\n * Translates one stream chunk. OpenAI's per-call `index` on tool call deltas\n * matches `tool_call_delta.index`, so it passes straight through.\n */\nexport function* toWireStreamChunks(chunk: OpenAIStreamChunk): Generator<WireStreamChunk> {\n const delta = chunk.choices?.[0]?.delta;\n\n if (delta?.content) {\n yield { type: 'text-delta', delta: delta.content };\n }\n\n if (delta?.tool_calls?.length) {\n for (const toolCall of delta.tool_calls) {\n yield {\n type: 'tool_call_delta',\n index: toolCall.index,\n id: toolCall.id,\n name: toolCall.function?.name,\n argumentsDelta: toolCall.function?.arguments,\n };\n }\n }\n\n if (chunk.usage) {\n yield { type: 'usage', usage: normalizeUsage(chunk.usage) };\n }\n}\n","import {\n attachRateLimitHint,\n parseOpenAIRateLimitHeaders,\n} from '../../internal/utils/rate-limit/rateLimitHint.utils.js';\nimport { rateLimitHintChunk, sendWithHeaders } from '../internal/rateLimitHeaders.js';\nimport {\n resolveEffortTokenTable,\n type EffortTokenTable,\n} from '../internal/reasoningBudget.utils.js';\nimport { readMaxRetries, sdkRetryWarning } from '../internal/sdkRetries.js';\nimport { openAICompatibleProvider } from './provider.js';\nimport {\n applyReasoningBudget,\n applyReasoningModelParams,\n requiresNoReasoning,\n withNoReasoning,\n} from './reasoning.js';\nimport { ensureJsonKeyword, toOpenAIMessages } from './request.js';\nimport { toWireStreamChunks } from './stream.js';\nimport { normalizeUsage } from './usage.js';\n\nimport type { Logger } from '../../logger.js';\nimport type { LLMClient } from '../../types/index.js';\nimport type { ModelCapabilityOverride } from '../internal/nativeStructuredOutput.js';\nimport type { OpenAIStreamChunk } from './types.js';\n\ntype WireRequest = Parameters<LLMClient['chat']['completions']['create']>[0];\ntype WireResponse = Awaited<ReturnType<LLMClient['chat']['completions']['create']>>;\n\n/** Optional configuration for `fromOpenAICompatible`. */\nexport interface OpenAICompatibleAdapterOptions {\n /**\n * Whether the provider accepts `stream_options.include_usage`. Default\n * `true`. With `false`, `stream_options` is omitted and streams report no\n * usage.\n */\n supportsStreamUsage?: boolean;\n /**\n * Overrides the token counts `budgetTokens` buckets into when\n * `reasoningEffort` isn't set. Omitted tiers keep the default.\n */\n reasoningEffortTokens?: Partial<EffortTokenTable>;\n /**\n * Whether the client supports `.withResponse()`, which AIMD's proactive\n * path needs. Default `false`, since the client can't be verified.\n */\n supportsWithResponse?: boolean;\n /**\n * The provider, in the OpenTelemetry `gen_ai.provider.name` vocabulary,\n * reported on `AttemptContext.adapter`. When omitted it is read off a well\n * known `baseURL` host, and left unset otherwise.\n */\n provider?: string;\n /**\n * Models that only take `tools` on Chat Completions with\n * `reasoning_effort: \"none\"`, replacing the built in rule (bare `gpt-` ids\n * of major 6 and later, except `-chat` ids). With tools, `\"none\"` is sent,\n * or the call throws `unsupported_capability` when reasoning was asked for.\n */\n noReasoningToolModels?: ModelCapabilityOverride;\n}\n\n/**\n * Adapter for any client whose `chat.completions.create` speaks the OpenAI\n * wire format. Requests pass through, except for message translation and\n * the model specific rewrites above. The client is `unknown` because SDK\n * types drift from `LLMClient`; the wire format is the contract.\n */\nexport function fromOpenAICompatible(\n client: unknown,\n options: OpenAICompatibleAdapterOptions = {},\n): LLMClient {\n const raw = client as LLMClient;\n const { supportsStreamUsage = true, supportsWithResponse = false } = options;\n const effortTokenTable = resolveEffortTokenTable(options.reasoningEffortTokens);\n const provider = openAICompatibleProvider(client, options.provider);\n let logger: Logger | undefined;\n const warnOnSdkRetries = sdkRetryWarning(\n 'openai-compatible',\n () => readMaxRetries(client),\n 'Pass maxRetries: 0 to the client',\n );\n\n // `extra` carries the stream fields, which VernLLM's own wire type, like\n // `reasoning_effort: 'none'`, doesn't list, hence the cast on the way out.\n const buildRequest = (params: WireRequest, extra: object = {}) => {\n const noReasoning = requiresNoReasoning(params, options.noReasoningToolModels);\n const messages = ensureJsonKeyword(toOpenAIMessages(params), params.response_format);\n\n return withNoReasoning(\n applyReasoningModelParams(\n applyReasoningBudget({ ...params, messages, ...extra }, effortTokenTable),\n ),\n noReasoning,\n logger,\n ) as WireRequest;\n };\n\n const send = <T>(request: WireRequest, signal: { signal: AbortSignal }) =>\n sendWithHeaders<T>(() => raw.chat.completions.create(request, signal), supportsWithResponse);\n\n return {\n adapter: { name: 'openai-compatible', ...(provider ? { provider } : {}) },\n setLogger(next) {\n logger = next;\n warnOnSdkRetries(next);\n },\n chat: {\n completions: {\n async create(params, requestOptions) {\n const { data, headers } = await send<WireResponse>(buildRequest(params), requestOptions);\n\n // Normalized before the hint is attached: the hint is a non enumerable symbol property,\n // which the copy would drop.\n const result = data?.usage ? { ...data, usage: normalizeUsage(data.usage) } : data;\n\n if (headers && result && typeof result === 'object') {\n attachRateLimitHint(result, parseOpenAIRateLimitHeaders(headers));\n }\n\n return result;\n },\n\n async *createStream(params, requestOptions) {\n const request = buildRequest(params, {\n stream: true,\n ...(supportsStreamUsage ? { stream_options: { include_usage: true } } : {}),\n });\n const { data: stream, headers } = await send<AsyncIterable<OpenAIStreamChunk>>(\n request,\n requestOptions,\n );\n\n // Headers arrive before the body, so the hint precedes content.\n if (headers) {\n const hint = rateLimitHintChunk(parseOpenAIRateLimitHeaders(headers));\n if (hint) yield hint;\n }\n\n for await (const chunk of stream) {\n yield* toWireStreamChunks(chunk);\n }\n },\n },\n },\n };\n}\n","import { fromOpenAICompatible } from './openaiCompatible.js';\n\n/**\n * The OpenAI SDK. Wrap it rather than passing it directly, since newer SDK\n * content-part types no longer typecheck against `LLMClient`.\n */\nexport const fromOpenAI = fromOpenAICompatible;\n\n/** Groqs SDK matches the OpenAI wire format */\nexport const fromGroq = fromOpenAICompatible;\n\n/** Mistral's OpenAI-compatible endpoint, which accepts `stream_options.include_usage`. */\nexport const fromMistral = fromOpenAICompatible;\n\n/** DeepSeeks API is OpenAI-compatible */\nexport const fromDeepSeek = fromOpenAICompatible;\n\n/** Cerebras inference API is OpenAI-compatible */\nexport const fromCerebras = fromOpenAICompatible;\n\n/** Together AIs API is OpenAI-compatible */\nexport const fromTogether = fromOpenAICompatible;\n\n/** Fireworks AIs API is OpenAI-compatible */\nexport const fromFireworks = fromOpenAICompatible;\n\n/** Ollama's OpenAI-compatible `/v1/chat/completions` endpoint, not its native `/api/chat`. */\nexport const fromOllama = fromOpenAICompatible;\n\n/** OpenRouter's API is OpenAI-compatible */\nexport const fromOpenRouter = fromOpenAICompatible;\n\n/** Perplexity's API is OpenAI-compatible */\nexport const fromPerplexity = fromOpenAICompatible;\n\n/** DeepInfra's API is OpenAI-compatible */\nexport const fromDeepInfra = fromOpenAICompatible;\n\n/** Novita's API is OpenAI-compatible */\nexport const fromNovita = fromOpenAICompatible;\n\n/** Hyperbolic's API is OpenAI-compatible */\nexport const fromHyperbolic = fromOpenAICompatible;\n\n/** Moonshot's (Kimi) API is OpenAI-compatible */\nexport const fromMoonshot = fromOpenAICompatible;\n\n/** Zhipu's (GLM) API is OpenAI-compatible */\nexport const fromZhipu = fromOpenAICompatible;\n\n/**\n * LM Studio exposes an OpenAI-compatible endpoint at `/v1/chat/completions`.\n * Point an OpenAI SDK instance's `baseURL` at your local LM Studio server.\n */\nexport const fromLMStudio = fromOpenAICompatible;\n\n/**\n * vLLM's OpenAI-compatible server mode exposes `/v1/chat/completions`.\n * Point an OpenAI SDK instance's `baseURL` at your vLLM server.\n */\nexport const fromVLLM = fromOpenAICompatible;\n\n/** xAI's Grok API is OpenAI-compatible */\nexport const fromXAI = fromOpenAICompatible;\n\n/** NVIDIA NIM's hosted and self-hosted endpoints are OpenAI-compatible */\nexport const fromNvidiaNIM = fromOpenAICompatible;\n\n/** Vercel AI Gateway is OpenAI-compatible */\nexport const fromVercelAIGateway = fromOpenAICompatible;\n\n/** Cloudflare Workers AI exposes an OpenAI-compatible endpoint */\nexport const fromCloudflareWorkersAI = fromOpenAICompatible;\n\n/** Nebius AI Studio is OpenAI-compatible */\nexport const fromNebius = fromOpenAICompatible;\n\n/** SambaNova Cloud's API is OpenAI-compatible */\nexport const fromSambaNova = fromOpenAICompatible;\n\n/** Baseten's model hosting exposes an OpenAI-compatible endpoint */\nexport const fromBaseten = fromOpenAICompatible;\n\n/** Featherless AI's API is OpenAI-compatible */\nexport const fromFeatherless = fromOpenAICompatible;\n\n/** Friendli AI's serving endpoint is OpenAI-compatible */\nexport const fromFriendli = fromOpenAICompatible;\n\n/** SiliconFlow's API is OpenAI-compatible */\nexport const fromSiliconFlow = fromOpenAICompatible;\n\n/** Parasail's inference API is OpenAI-compatible */\nexport const fromParasail = fromOpenAICompatible;\n\n/** StepFun's API is OpenAI-compatible */\nexport const fromStepFun = fromOpenAICompatible;\n\n/** MiniMax's API is OpenAI-compatible */\nexport const fromMiniMax = fromOpenAICompatible;\n\n/** Lambda Labs' Inference API is OpenAI-compatible */\nexport const fromLambdaLabs = fromOpenAICompatible;\n\n/** Snowflake Cortex's LLM endpoint is OpenAI-compatible */\nexport const fromSnowflakeCortex = fromOpenAICompatible;\n\n/** Anyscale Endpoints' API is OpenAI-compatible */\nexport const fromAnyscale = fromOpenAICompatible;\n\n/** Lepton AI's inference API is OpenAI-compatible */\nexport const fromLepton = fromOpenAICompatible;\n\n/** Inference.net's API is OpenAI-compatible */\nexport const fromInferenceNet = fromOpenAICompatible;\n\n/** Infermatic's API is OpenAI-compatible */\nexport const fromInfermatic = fromOpenAICompatible;\n\n/** AtlasCloud's inference API is OpenAI-compatible */\nexport const fromAtlasCloud = fromOpenAICompatible;\n\n/** 01.AI's (Yi models) API is OpenAI-compatible */\nexport const from01AI = fromOpenAICompatible;\n"],"mappings":"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"}