@bivelio/savings-layer 0.4.36 → 0.5.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -121,9 +121,10 @@ bvsala gateway # Anthropic, the default, on 8402
121
121
 
122
122
  Flags and environment variables are in English (`--port`, `--project`, `--force`,
123
123
  `BVSALA_GATEWAY_EFFORT`, `BVSALA_GATEWAY_SIBLING_MODEL`). The Spanish spellings from
124
- earlier versions (`--puerto`, `--proyecto`, `--forzar`, `BVSALA_GATEWAY_ESFUERZO`,
125
- `BVSALA_GATEWAY_MODELO_HERMANO`) keep working until 0.5 and print a deprecation
126
- notice; `BVSALA_SILENCE_DEPRECATIONS=1` silences it. `bvsala --help` lists them all.
124
+ 0.4.x (`--puerto`, `--proyecto`, `--forzar`, `BVSALA_GATEWAY_ESFUERZO`,
125
+ `BVSALA_GATEWAY_MODELO_HERMANO`) were removed in 0.5: using one is an error that
126
+ names the English spelling, and the gateway does not start. `bvsala --help` lists
127
+ them all.
127
128
 
128
129
  ```python
129
130
  from openai import OpenAI
@@ -560,7 +561,7 @@ report.nativeSavings;
560
561
  ```
561
562
 
562
563
  It is present only when a call ran and the provider reported cache reads or writes;
563
- a cache hit or a coalesced request never carries it. It is not in `cost.netSavings`,
564
+ a cache hit or a coalesced request never carries it. It is not in `cost.netSavingsRatio`,
564
565
  not in `cost.baselineEstimate`, and never in the commission base. Your dashboard shows
565
566
  it as its own card, **Native savings unlocked**, next to the credited savings.
566
567
 
@@ -1,84 +1,93 @@
1
- import {createSavingsLayer,LicenseError,sha256,stableStringify}from'@bivelio/savings-layer';import {AsyncLocalStorage}from'async_hooks';var j=new Set;function $(t,e,n){t===true||j.has(e)||(j.add(e),console.warn(n));}var N=Symbol.for("@bivelio/savings-layer:provider-origin");var ie="[bvsala] internal: the layer changed a request this adapter must forward unchanged; nothing was sent.",se="[bvsala] internal: the layer asked for a second model call within one framework call;\
2
- nothing more was sent.",de="[bvsala] internal: the layer called the model outside a framework call; nothing was sent.";function C(t,e,n,r){return {renderizado:t,generar:e,...n?{transmitir:n}:{},invocada:false,
3
- completada:false,...{}}}async function x(t,e){try{let n=await e();return t.completada=!0,n}catch(n){throw t.errorDelMarco={error:n},n}}function ue(t,e){if(t===e)return true;try{return stableStringify(
4
- t)===stableStringify(e)}catch{return false}}function G(t,e){let n=t??[],r=e??[];return n.length===r.length&&n.every((a,i)=>ue(a,r[i]))}function le(t,e){return t.model===e.model&&G(t.messages,e.messages)&&G(t.tools,e.tools)}
5
- function _(t,e){let n=a=>{let i=e.getStore();if(!i)throw new Error(de);if(i.invocada)throw new Error(se);if(!le(a,i.renderizado))throw new Error(ie);return i.invocada=true,i},r={id:`bivelio-adapter:${t}`,
6
- async generate(a,i){return n(a).generar(i?.signal)},async*generateStream(a,i){let o=n(a);if(o.transmitir){yield*o.transmitir(i?.signal);return}let s=await o.generar(i?.signal);s.text!==""&&(yield {type:"\
7
- text",delta:s.text}),yield {type:"done",response:s};}};return Object.defineProperty(r,N,{value:()=>e.getStore()?.origen}),r}function U(){return new AsyncLocalStorage}var fe=["licenseKey","licenseServerUrl","serviceAccountKey","licenseRefresh","licenseRevocation","licensePollIntervalSeconds","licenseFetch","metering","meteringUrl","meteringFetch","costModels","defa\
8
- ultCostModel","exactCache","exactCacheTtlMs","resolvers","exactTokenizer","silenceWarnings","failOpen"];function F(t,e){return e instanceof LicenseError||t.errorDelMarco&&t.errorDelMarco.error===e?false:t.invocada&&
9
- t.completada}var V="[bvsala] the model answered, but the savings layer failed while accounting for it; the answer is returned unchanged, without a savings report and without a usage record.";function W(t,e){
10
- let n=U(),r={};for(let o of fe)e[o]!==void 0&&(r[o]=e[o]);let a=createSavingsLayer({...r,provider:_(t,n)}),i=(o,s)=>$(e.silenceWarnings,`${t}:${o}`,s);return {ejecutar(o,s){return n.run(s,()=>a.generate(o))},async generar(o,s){
11
- try{let d=await n.run(s,()=>a.generate(o));return s.invocada?{tipo:"vivo",result:d}:{tipo:"atajo",result:d}}catch(d){if(F(s,d))return i("sin-informe",V),{tipo:"sin-informe"};throw d}},async transmitir(o,s,d){
12
- let u=n.run(s,()=>a.generateStream(o,d?{signal:d}:{})).result;s.resultado=u,u.catch(()=>{});let c;try{c=await Promise.race([s.abierta.then(()=>"abierta"),u.then(()=>"resuelta")]);}catch(l){if(F(s,l))return i(
13
- "sin-informe",V),{tipo:"sin-informe"};throw l}if(c==="abierta")return {tipo:"abierto"};let g=await u;return s.invocada?{tipo:"entero",result:g}:{tipo:"atajo",result:g}},informe(o){let s=JSON.parse(JSON.
14
- stringify(o));if(e.onReport)try{e.onReport(s);}catch{i("onreport","[bvsala] `onReport` threw; the error was caught and the model call was not affected.");}return s},avisar:i,close(){a.close();}}}function B(){
15
- let t;return {abierta:new Promise(n=>{t=n;}),abrir:t}}var b=class{pendientes=[];esperando;terminada=false;fallo;push(e){if(this.terminada||this.fallo)return;let n=this.esperando;if(n){this.esperando=void 0,n.resolver({value:e,done:false});return}this.pendientes.
1
+ import {createSavingsLayer,LicenseError}from'@bivelio/savings-layer';import {AsyncLocalStorage}from'async_hooks';var _=new Set;function F(t,e,n){t===true||_.has(e)||(_.add(e),console.warn(n));}var V=Symbol.for("@bivelio/savings-layer:provider-origin");var me="[bvsala] internal: the layer changed a request this adapter must forward unchanged; nothing was sent.",ve="[bvsala] internal: the layer asked for a second model call within one framework call;\
2
+ nothing more was sent.",ye="[bvsala] internal: the layer called the model outside a framework call; nothing was sent.";function j(t,e,n,r){return {renderizado:t,generar:e,...n?{transmitir:n}:{},invocada:false,
3
+ completada:false,...{}}}async function P(t,e){try{let n=await e();return t.completada=!0,n}catch(n){throw t.errorDelMarco={error:n},n}}function he(t,e){if(t===e)return true;try{return W(
4
+ t)===W(e)}catch{return false}}function J(t,e){let n=t??[],r=e??[];return n.length===r.length&&n.every((a,s)=>he(a,r[s]))}function xe(t,e){return t.model===e.model&&J(t.messages,e.messages)&&J(t.tools,e.tools)}
5
+ function B(t,e){let n=a=>{let s=e.getStore();if(!s)throw new Error(ye);if(s.invocada)throw new Error(ve);if(!xe(a,s.renderizado))throw new Error(me);return s.invocada=true,s},r={id:`bivelio-adapter:${t}`,
6
+ async generate(a,s){return n(a).generar(s?.signal)},async*generateStream(a,s){let o=n(a);if(o.transmitir){yield*o.transmitir(s?.signal);return}let i=await o.generar(s?.signal);i.text!==""&&(yield {type:"\
7
+ text",delta:i.text}),yield {type:"done",response:i};}};return Object.defineProperty(r,V,{value:()=>e.getStore()?.origen}),r}function K(){return new AsyncLocalStorage}function W(t){return JSON.stringify(E(t))}function E(t){
8
+ if(Array.isArray(t))return t.map(E);if(t&&typeof t=="object"){let e={};for(let n of Object.keys(t).sort())e[n]=E(t[n]);return e}return t}var we=["licenseKey","licenseServerUrl","serviceAccountKey","licenseRefresh","licenseRevocation","licensePollIntervalSeconds","licenseFetch","metering","meteringUrl","meteringFetch","costModels","defa\
9
+ ultCostModel","exactCache","exactCacheTtlMs","resolvers","exactTokenizer","silenceWarnings","failOpen"];function H(t,e){return e instanceof LicenseError||t.errorDelMarco&&t.errorDelMarco.error===e?false:t.invocada&&
10
+ t.completada}var Z="[bvsala] the model answered, but the savings layer failed while accounting for it; the answer is returned unchanged, without a savings report and without a usage record.";function Q(t,e){
11
+ let n=K(),r={};for(let o of we)e[o]!==void 0&&(r[o]=e[o]);let a=createSavingsLayer({...r,provider:B(t,n)}),s=(o,i)=>F(e.silenceWarnings,`${t}:${o}`,i);return {ejecutar(o,i){return n.run(i,()=>a.generate(o))},async generar(o,i){
12
+ try{let u=await n.run(i,()=>a.generate(o));return i.invocada?{tipo:"vivo",result:u}:{tipo:"atajo",result:u}}catch(u){if(H(i,u))return s("sin-informe",Z),{tipo:"sin-informe"};throw u}},async transmitir(o,i,u){
13
+ let d=n.run(i,()=>a.generateStream(o,u?{signal:u}:{})).result;i.resultado=d,d.catch(()=>{});let f;try{f=await Promise.race([i.abierta.then(()=>"abierta"),d.then(()=>"resuelta")]);}catch(l){if(H(i,l))return s(
14
+ "sin-informe",Z),{tipo:"sin-informe"};throw l}if(f==="abierta")return {tipo:"abierto"};let g=await d;return i.invocada?{tipo:"entero",result:g}:{tipo:"atajo",result:g}},informe(o){let i=JSON.parse(JSON.
15
+ stringify(o));if(e.onReport)try{e.onReport(i);}catch{s("onreport","[bvsala] `onReport` threw; the error was caught and the model call was not affected.");}return i},avisar:s,close(){a.close();}}}function X(){
16
+ let t;return {abierta:new Promise(n=>{t=n;}),abrir:t}}var L=class{pendientes=[];esperando;terminada=false;fallo;push(e){if(this.terminada||this.fallo)return;let n=this.esperando;if(n){this.esperando=void 0,n.resolver({value:e,done:false});return}this.pendientes.
16
17
  push(e);}end(){if(this.terminada||this.fallo)return;this.terminada=true;let e=this.esperando;e&&this.pendientes.length===0&&(this.esperando=void 0,e.resolver({value:void 0,done:true}));}fail(e){if(this.terminada||
17
18
  this.fallo)return;this.fallo={error:e};let n=this.esperando;n&&this.pendientes.length===0&&(this.esperando=void 0,n.rechazar(e));}get cerrada(){return this.terminada||this.fallo!==void 0}[Symbol.asyncIterator](){
18
19
  return {next:()=>this.pendientes.length>0?Promise.resolve({value:this.pendientes.shift(),done:false}):this.fallo?Promise.reject(this.fallo.error):this.terminada?Promise.resolve({value:void 0,done:true}):new Promise(
19
- (e,n)=>{this.esperando={resolver:e,rechazar:n};}),return:()=>(this.terminada=true,this.pendientes.length=0,Promise.resolve({value:void 0,done:true}))}}};function f(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function J(t){return typeof t=="string"?[{type:"text",text:t}]:Array.isArray(t)?t.filter(f):[]}function A(t){return t.filter(e=>e.type===
20
+ (e,n)=>{this.esperando={resolver:e,rechazar:n};}),return:()=>(this.terminada=true,this.pendientes.length=0,Promise.resolve({value:void 0,done:true}))}}};function m(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function Y(t){return typeof t=="string"?[{type:"text",text:t}]:Array.isArray(t)?t.filter(m):[]}function O(t){return t.filter(e=>e.type===
20
21
  "text"&&typeof e.text=="string").map(e=>e.text).join(`
21
- `)}function v(t){if(typeof t=="string")return t;try{return JSON.stringify(t??{})}catch{return "{}"}}function ge(t){if(!f(t))return v(t);switch(t.type){case "text":case "error-text":return typeof t.value==
22
- "string"?t.value:v(t.value);case "json":case "error-json":return v(t.value);case "execution-denied":return `execution denied${typeof t.reason=="string"?`: ${t.reason}`:""}`;case "content":return A(e(t.value));default:
23
- return v(t)}function e(n){return Array.isArray(n)?n.filter(f):[]}}function H(t){let e=[];for(let n of Array.isArray(t)?t:[]){if(!f(n))continue;let r=J(n.content);switch(n.role){case "system":e.push({role:"\
24
- system",content:typeof n.content=="string"?n.content:A(r)});break;case "user":e.push({role:"user",content:A(r)});break;case "assistant":{let a=r.filter(i=>i.type==="tool-call"&&i.providerExecuted!==true).
25
- map(i=>({...typeof i.toolCallId=="string"?{id:i.toolCallId}:{},name:String(i.toolName??""),arguments:v(i.input??i.args)}));e.push({role:"assistant",content:A(r),...a.length>0?{toolCalls:a}:{}});break}case "\
26
- tool":for(let a of r)a.type==="tool-result"&&e.push({role:"tool",content:ge(a.output??a.result),...typeof a.toolCallId=="string"?{toolCallId:a.toolCallId}:{},...typeof a.toolName=="string"?{name:a.toolName}:
27
- {}});break}}return e}var me=new Set(["bivelio","mastra"]);function D(t){if(!f(t))return t;let e={};for(let[n,r]of Object.entries(t))me.has(n)||(e[n]=r);return e}function ve(t){let e={};for(let[n,r]of Object.
28
- entries(t))if(!(n==="toolCallId"||n==="id")&&!(n==="text"&&t.type==="text")){if(n==="providerOptions"||n==="providerMetadata"){e[n]=D(r);continue}e[n]=r;}return e}function ye(t){return (Array.isArray(t)?
29
- t:[]).map(e=>f(e)?{role:e.role,content:typeof e.content=="string"?"$text":J(e.content).map(ve),providerOptions:D(e.providerOptions)}:e)}var he=new Set(["anthropic-beta","openai-beta"]);function Re(t){
30
- if(!f(t))return;let e={};for(let[n,r]of Object.entries(t))he.has(n.toLowerCase())&&r!==void 0&&(e[n.toLowerCase()]=r);return Object.keys(e).length>0?e:void 0}function K(t){let e={};for(let[n,r]of Object.
31
- entries(t))n==="prompt"||n==="abortSignal"||n==="headers"||n==="providerOptions"||(e[n]=r);return e.prompt=ye(t.prompt),e.headers=Re(t.headers),e.providerOptions=D(t.providerOptions),e}function Z(t){let e=t.
32
- responseFormat;if(f(e)&&e.type==="json")return true;let n=t.toolChoice;return f(n)&&(n.type==="required"||n.type==="tool")?true:n==="required"}function m(t){return typeof t=="number"&&Number.isFinite(t)?t:
33
- void 0}function we(t,e){let n=f(t)?t:{},r=f(n.inputTokens)?n.inputTokens:void 0,a=f(n.outputTokens)?n.outputTokens:void 0;if(!r||!a){let c=m(n.inputTokens),g=m(n.outputTokens);return {inputTokens:c??0,
34
- outputTokens:g??0,complete:false}}let i=m(r.total),o=m(r.cacheRead),s=m(r.cacheWrite),d=m(a.total),p=m(a.reasoning);return {inputTokens:i??0,outputTokens:d??0,...o!==void 0?{cachedInputTokens:o}:{},...s!==
35
- void 0?{cacheWriteInputTokens:s}:{},...p!==void 0?{reasoningTokens:p}:{},...i!==void 0&&d!==void 0&&!e?{}:{complete:false}}}function Se(t){if(typeof t=="string")return t;if(f(t)&&typeof t.unified=="strin\
36
- g")return t.unified}function xe(t){switch(t){case void 0:return;case "tool-calls":return "tool_calls";case "content-filter":return "content_filter";default:return t}}function be(t){return f(t)&&Object.keys(
37
- D(t)).length>0}var R=class{texto="";toolCalls=[];reproducible=true;finish;error;anadir(e){switch(e.type){case "text-delta":{let n=typeof e.delta=="string"?e.delta:typeof e.textDelta=="string"?e.textDelta:
22
+ `)}function w(t){if(typeof t=="string")return t;try{return JSON.stringify(t??{})}catch{return "{}"}}function Se(t){if(!m(t))return w(t);switch(t.type){case "text":case "error-text":return typeof t.value==
23
+ "string"?t.value:w(t.value);case "json":case "error-json":return w(t.value);case "execution-denied":return `execution denied${typeof t.reason=="string"?`: ${t.reason}`:""}`;case "content":return O(e(t.value));default:
24
+ return w(t)}function e(n){return Array.isArray(n)?n.filter(m):[]}}function ee(t){let e=[];for(let n of Array.isArray(t)?t:[]){if(!m(n))continue;let r=Y(n.content);switch(n.role){case "system":e.push({role:"\
25
+ system",content:typeof n.content=="string"?n.content:O(r)});break;case "user":e.push({role:"user",content:O(r)});break;case "assistant":{let a=r.filter(s=>s.type==="tool-call"&&s.providerExecuted!==true).
26
+ map(s=>({...typeof s.toolCallId=="string"?{id:s.toolCallId}:{},name:String(s.toolName??""),arguments:w(s.input??s.args)}));e.push({role:"assistant",content:O(r),...a.length>0?{toolCalls:a}:{}});break}case "\
27
+ tool":for(let a of r)a.type==="tool-result"&&e.push({role:"tool",content:Se(a.output??a.result),...typeof a.toolCallId=="string"?{toolCallId:a.toolCallId}:{},...typeof a.toolName=="string"?{name:a.toolName}:
28
+ {}});break}}return e}var Ae=new Set(["bivelio","mastra"]);function T(t){if(!m(t))return t;let e={};for(let[n,r]of Object.entries(t))Ae.has(n)||(e[n]=r);return e}function ke(t){let e={};for(let[n,r]of Object.
29
+ entries(t))if(!(n==="toolCallId"||n==="id")&&!(n==="text"&&t.type==="text")){if(n==="providerOptions"||n==="providerMetadata"){e[n]=T(r);continue}e[n]=r;}return e}function De(t){return (Array.isArray(t)?
30
+ t:[]).map(e=>m(e)?{role:e.role,content:typeof e.content=="string"?"$text":Y(e.content).map(ke),providerOptions:T(e.providerOptions)}:e)}var Me=new Set(["anthropic-beta","openai-beta"]);function Ce(t){
31
+ if(!m(t))return;let e={};for(let[n,r]of Object.entries(t))Me.has(n.toLowerCase())&&r!==void 0&&(e[n.toLowerCase()]=r);return Object.keys(e).length>0?e:void 0}function te(t){let e={};for(let[n,r]of Object.
32
+ entries(t))n==="prompt"||n==="abortSignal"||n==="headers"||n==="providerOptions"||(e[n]=r);return e.prompt=De(t.prompt),e.headers=Ce(t.headers),e.providerOptions=T(t.providerOptions),e}function ne(t){
33
+ let e=t.responseFormat;if(m(e)&&e.type==="json")return true;let n=t.toolChoice;return m(n)&&(n.type==="required"||n.type==="tool")?true:n==="required"}function b(t){return typeof t=="number"&&Number.isFinite(
34
+ t)?t:void 0}function Pe(t,e){let n=m(t)?t:{},r=m(n.inputTokens)?n.inputTokens:void 0,a=m(n.outputTokens)?n.outputTokens:void 0;if(!r||!a){let f=b(n.inputTokens),g=b(n.outputTokens);return {inputTokens:f??
35
+ 0,outputTokens:g??0,complete:false}}let s=b(r.total),o=b(r.cacheRead),i=b(r.cacheWrite),u=b(a.total),c=b(a.reasoning);return {inputTokens:s??0,outputTokens:u??0,...o!==void 0?{cachedInputTokens:o}:{},...i!==
36
+ void 0?{cacheWriteInputTokens:i}:{},...c!==void 0?{reasoningTokens:c}:{},...s!==void 0&&u!==void 0&&!e?{}:{complete:false}}}function Le(t){if(typeof t=="string")return t;if(m(t)&&typeof t.unified=="strin\
37
+ g")return t.unified}function Oe(t){switch(t){case void 0:return;case "tool-calls":return "tool_calls";case "content-filter":return "content_filter";default:return t}}function Te(t){return m(t)&&Object.keys(
38
+ T(t)).length>0}var D=class{texto="";toolCalls=[];reproducible=true;finish;error;anadir(e){switch(e.type){case "text-delta":{let n=typeof e.delta=="string"?e.delta:typeof e.textDelta=="string"?e.textDelta:
38
39
  "";return this.texto+=n,n===""?void 0:n}case "text":{let n=typeof e.text=="string"?e.text:"";return this.texto+=n,n===""?void 0:n}case "tool-call":e.providerExecuted===true?this.reproducible=false:this.toolCalls.
39
- push({...typeof e.toolCallId=="string"?{id:e.toolCallId}:{},name:String(e.toolName??""),arguments:v(e.input??e.args)});return;case "reasoning":case "reasoning-start":case "reasoning-delta":case "reasoning\
40
- -end":be(e.providerMetadata)&&(this.reproducible=false);return;case "text-start":case "text-end":case "tool-input-start":case "tool-input-delta":case "tool-input-end":case "stream-start":case "response-metadata":case "\
41
- raw":return;case "finish":this.finish=e;return;case "error":this.error={error:e.error};return;default:this.reproducible=false;return}}respuesta(e,n,r){let a=Se(n),i=xe(a),o=this.reproducible&&a==="stop";return {
42
- text:this.texto,...this.toolCalls.length>0?{toolCalls:this.toolCalls}:{},...i?{finishReason:i}:{},usage:we(e,r),...o?{}:{replayable:false}}}};function P(t,e){let n=new R;for(let r of Array.isArray(t.content)?
43
- t.content:[])f(r)&&n.anadir(r);return n.respuesta(t.usage,t.finishReason,e)}var L={inputTokens:{total:0,noCache:0,cacheRead:0,cacheWrite:0},outputTokens:{total:0,text:0,reasoning:0}};function O(t){let e=[];
44
- return t.text!==""&&e.push({type:"text",text:t.text}),(t.toolCalls??[]).forEach((n,r)=>{e.push({type:"tool-call",toolCallId:n.id??`bvsala-${t.requestId}-${r}`,toolName:n.name,input:n.arguments});}),e}function I(t){
45
- return {unified:(t.toolCalls?.length??0)>0?"tool-calls":"stop",raw:void 0}}function T(t,e,n){let r=[{type:"stream-start",warnings:Array.isArray(n.warnings)?n.warnings:[]}];return n.response&&r.push({type:"\
46
- response-metadata",...n.response}),t.forEach((a,i)=>{if(!f(a))return;let o=`bvsala-${i}`;if(a.type==="text"){let s=a.providerMetadata!==void 0?{providerMetadata:a.providerMetadata}:{};r.push({type:"te\
47
- xt-start",id:o,...s}),typeof a.text=="string"&&a.text!==""&&r.push({type:"text-delta",id:o,delta:a.text}),r.push({type:"text-end",id:o,...s});}else if(a.type==="reasoning"){let s=a.providerMetadata!==void 0?
48
- {providerMetadata:a.providerMetadata}:{};r.push({type:"reasoning-start",id:o,...s}),typeof a.text=="string"&&a.text!==""&&r.push({type:"reasoning-delta",id:o,delta:a.text}),r.push({type:"reasoning-end",
49
- id:o,...s});}else r.push(a);}),r.push({type:"finish",usage:e.usage,finishReason:e.finishReason,...e.providerMetadata!==void 0?{providerMetadata:e.providerMetadata}:{}}),r}function E(t){let e=0;return new ReadableStream(
50
- {pull(n){e<t.length?n.enqueue(t[e++]):n.close();}})}function Q(t){let e=String(t.modelId??"");if(e.includes("/"))return e;let n=String(t.provider??"").split(".")[0]??"";return n!==""?`${n}/${e}`:e}function X(t){
51
- return typeof t.provider=="string"&&t.provider.toLowerCase().startsWith("mock")}function y(t,e){return {...f(t)?t:{},bivelio:{savingsReport:e}}}var De={router:false,compression:false,elision:false,serialization:false,toolDiscovery:false,modelCascade:"off",outputCodebook:false,deferrable:false,semanticCache:false,verification:false};
52
- function ke(t,e,n={}){let r=a=>t?.[a]!==false&&e?.[a]!==false;return {...De,exactCache:r("exactCache")&&n.sinReutilizar!==true,singleflight:r("singleflight")&&n.sinReutilizar!==true,deterministicResolvers:r("det\
53
- erministicResolvers")&&n.sinResolvers!==true}}function Me(t,e){let n=t.readOnlyTools;if(typeof n=="function")try{return n(e)===!0}catch{return false}return Array.isArray(n)?n.includes(e):false}function ee(t,e){
54
- let n=e.delProveedor!==true&&Me(t,e.nombre);return {id:e.nombre,intents:[],risk:n?"read":"write",...e.parametros!==void 0&&e.parametros!==null&&typeof e.parametros=="object"?{parameters:e.parametros}:{},
55
- ...typeof e.descripcion=="string"?{description:e.descripcion}:{}}}function w(t,e,n){if(t===null)return null;switch(typeof t){case "string":case "boolean":return t;case "number":return Number.isFinite(t)?
56
- t:String(t);case "bigint":return `${t.toString()}n`;case "undefined":case "function":case "symbol":return}let r=t;if(r instanceof Uint8Array)return e.push(r),{$bytes:e.length-1};if(r instanceof ArrayBuffer)
57
- return e.push(new Uint8Array(r)),{$bytes:e.length-1};if(ArrayBuffer.isView(r))return e.push(new Uint8Array(r.buffer,r.byteOffset,r.byteLength)),{$bytes:e.length-1};if(r instanceof URL)return {$url:r.href};
58
- if(r instanceof Date)return {$date:Number.isNaN(r.getTime())?"invalid":r.toISOString()};if(n.has(r))return "$cycle";n.add(r);try{if(Array.isArray(r))return r.map(i=>{let o=w(i,e,n);return o===void 0?null:
59
- o});if(r instanceof Map)return {$map:[...r.entries()].map(i=>w(i,e,n))};if(r instanceof Set)return {$set:[...r.values()].map(i=>w(i,e,n))};let a={};for(let i of Object.keys(r).sort()){let o=w(r[i],e,n);
60
- o!==void 0&&(a[i]=o);}return a}finally{n.delete(r);}}async function Y(t){let e=globalThis.crypto?.subtle;if(e){let r=new Uint8Array(await e.digest("SHA-256",t));return Array.from(r,a=>a.toString(16).padStart(
61
- 2,"0")).join("")}let n="";for(let r=0;r<t.length;r+=32768)n+=String.fromCharCode(...t.subarray(r,r+32768));return sha256(n)}async function Ce(t){try{let e=[],n=JSON.stringify(w(t,e,new WeakSet))??"null",r=await Promise.
62
- all(e.map(Y)),a=new TextEncoder().encode(`${n}|${r.join(",")}`);return await Y(a)}catch{return null}}async function te(t,e){let n=await Ce(e.proyeccion),r=`${e.context?.authorizationScope??"default"}|\
63
- bvsala-adapter:${n??"none"}`;return {model:e.model,messages:e.messages,...e.tools.length>0?{tools:e.tools}:{},...typeof e.temperature=="number"?{temperature:e.temperature}:{},...typeof e.seed=="number"?
64
- {seed:e.seed}:{},context:{...e.context??{},authorizationScope:r},savings:ke(t.savings,e.savings,{...e.restricciones,...n===null?{sinReutilizar:true}:{}})}}function ne(t,e){if(!(!t&&!e))return {...t??{},...e??
65
- {}}}function re(t){if(!t||typeof t!="object")return {};let e=t,n={};return e.context&&typeof e.context=="object"&&(n.context=e.context),e.savings&&typeof e.savings=="object"&&(n.savings=e.savings),n}var Pe="[bvsala] a streamed call finished but its savings report could not be produced; the model answer was delivered unchanged.";function Xe(t){let e=W("ai-sdk",t),n=t.reportInMetadata!==false;async function r(o,s){
66
- let d=re(o.providerOptions?.bivelio),p;t.context&&(p=t.context({provider:s.provider,modelId:s.modelId,params:o}));let u=t.modelId?t.modelId({provider:s.provider,modelId:s.modelId}):Q(s),c=(Array.isArray(
67
- o.tools)?o.tools:[]).map(l=>ee(t,{nombre:String(l.name??l.id??""),descripcion:typeof l.description=="string"?l.description:void 0,parametros:l.inputSchema??l.parameters,delProveedor:l.type==="provider"||
68
- l.type==="provider-defined"}));return {req:await te(t,{model:u,messages:H(o.prompt),tools:c,temperature:typeof o.temperature=="number"?o.temperature:void 0,seed:typeof o.seed=="number"?o.seed:void 0,context:ne(
69
- p,d.context),savings:d.savings,proyeccion:{modelo:u,parametros:K(o)},restricciones:{sinResolvers:Z(o)}}),simulado:X(s)}}function a(o){return {model:o.model,messages:o.messages,...o.tools?{tools:o.tools}:
70
- {}}}return {specificationVersion:"v3",async wrapGenerate(o){let{req:s,simulado:d}=await r(o.params,o.model),p,u=C(a(s),async()=>(p=await x(u,()=>o.doGenerate()),P(p,d))),c=await e.generar(s,u);if(c.tipo===
71
- "sin-informe")return p;let g=e.informe(c.result.report);if(c.tipo==="vivo"){let l=p;return n?{...l,providerMetadata:y(l.providerMetadata,g)}:l}return Oe(c.result,n?g:void 0,o.model)},async wrapStream(o){
72
- let{req:s,simulado:d}=await r(o.params,o.model),{abierta:p,abrir:u}=B(),c,g,l=Object.assign(C(a(s),async()=>(c=await x(l,()=>o.doGenerate()),P(c,d)),()=>{let M=new b;return x(l,()=>o.doStream()).then(
73
- S=>{g={...S,stream:Le(S.stream,M,e,l,d,n)},u();},S=>M.fail(S)),M}),{abierta:p}),k=o.params.abortSignal instanceof AbortSignal?o.params.abortSignal:void 0,h=await e.transmitir(s,l,k);if(h.tipo==="abiert\
74
- o")return g;if(h.tipo==="sin-informe")return oe(c,void 0);let q=e.informe(h.result.report);return h.tipo==="entero"?oe(c,n?q:void 0):Ie(h.result,n?q:void 0,o.model)},close(){e.close();}}}function Le(t,e,n,r,a,i){
75
- let o=t.getReader(),s=new R;return new ReadableStream({async pull(d){let p;try{p=await o.read();}catch(l){e.fail(l),d.error(l);return}if(p.done){e.fail(new Error("[bvsala] the model stream ended withou\
76
- t a finish part; nothing was measured.")),d.close();return}let u=p.value,c=s.anadir(u);if(u.type==="error"){e.fail(u.error??new Error("[bvsala] the model stream reported an error")),d.enqueue(u);return}
77
- if(c!==void 0&&e.push({type:"text",delta:c}),u.type!=="finish"||e.cerrada){d.enqueue(u);return}e.push({type:"done",response:s.respuesta(u.usage,u.finishReason,a)}),e.end();let g=u;try{let l=await r.resultado,
78
- k=n.informe(l.report);i&&(g={...u,providerMetadata:y(u.providerMetadata,k)});}catch{n.avisar("informe-del-stream",Pe);}d.enqueue(g);},cancel(d){return e.fail(new Error("[bvsala] the stream was cancelled \
79
- by its reader; nothing was measured.")),o.cancel(d)}})}function Oe(t,e,n){return {content:O(t),finishReason:I(t),usage:L,...e?{providerMetadata:y(void 0,e)}:{},response:{id:`bvsala-${t.requestId}`,modelId:n.
80
- modelId,timestamp:new Date},warnings:[]}}function Ie(t,e,n){let r=T(O(t),{usage:L,finishReason:I(t),...e?{providerMetadata:y(void 0,e)}:{}},{warnings:[],response:{id:`bvsala-${t.requestId}`,modelId:n.
81
- modelId,timestamp:new Date}});return {stream:E(r)}}function oe(t,e){let n=t.response,r=T(Array.isArray(t.content)?t.content:[],{usage:t.usage,finishReason:t.finishReason,...e?{providerMetadata:y(t.providerMetadata,
40
+ push({...typeof e.toolCallId=="string"?{id:e.toolCallId}:{},name:String(e.toolName??""),arguments:w(e.input??e.args)});return;case "reasoning":case "reasoning-start":case "reasoning-delta":case "reasoning\
41
+ -end":Te(e.providerMetadata)&&(this.reproducible=false);return;case "text-start":case "text-end":case "tool-input-start":case "tool-input-delta":case "tool-input-end":case "stream-start":case "response-metadata":case "\
42
+ raw":return;case "finish":this.finish=e;return;case "error":this.error={error:e.error};return;default:this.reproducible=false;return}}respuesta(e,n,r){let a=Le(n),s=Oe(a),o=this.reproducible&&a==="stop";return {
43
+ text:this.texto,...this.toolCalls.length>0?{toolCalls:this.toolCalls}:{},...s?{finishReason:s}:{},usage:Pe(e,r),...o?{}:{replayable:false}}}};function q(t,e){let n=new D;for(let r of Array.isArray(t.content)?
44
+ t.content:[])m(r)&&n.anadir(r);return n.respuesta(t.usage,t.finishReason,e)}var U={inputTokens:{total:0,noCache:0,cacheRead:0,cacheWrite:0},outputTokens:{total:0,text:0,reasoning:0}};function N(t){let e=[];
45
+ return t.text!==""&&e.push({type:"text",text:t.text}),(t.toolCalls??[]).forEach((n,r)=>{e.push({type:"tool-call",toolCallId:n.id??`bvsala-${t.requestId}-${r}`,toolName:n.name,input:n.arguments});}),e}function $(t){
46
+ return {unified:(t.toolCalls?.length??0)>0?"tool-calls":"stop",raw:void 0}}function z(t,e,n){let r=[{type:"stream-start",warnings:Array.isArray(n.warnings)?n.warnings:[]}];return n.response&&r.push({type:"\
47
+ response-metadata",...n.response}),t.forEach((a,s)=>{if(!m(a))return;let o=`bvsala-${s}`;if(a.type==="text"){let i=a.providerMetadata!==void 0?{providerMetadata:a.providerMetadata}:{};r.push({type:"te\
48
+ xt-start",id:o,...i}),typeof a.text=="string"&&a.text!==""&&r.push({type:"text-delta",id:o,delta:a.text}),r.push({type:"text-end",id:o,...i});}else if(a.type==="reasoning"){let i=a.providerMetadata!==void 0?
49
+ {providerMetadata:a.providerMetadata}:{};r.push({type:"reasoning-start",id:o,...i}),typeof a.text=="string"&&a.text!==""&&r.push({type:"reasoning-delta",id:o,delta:a.text}),r.push({type:"reasoning-end",
50
+ id:o,...i});}else r.push(a);}),r.push({type:"finish",usage:e.usage,finishReason:e.finishReason,...e.providerMetadata!==void 0?{providerMetadata:e.providerMetadata}:{}}),r}function G(t){let e=0;return new ReadableStream(
51
+ {pull(n){e<t.length?n.enqueue(t[e++]):n.close();}})}function re(t){let e=String(t.modelId??"");if(e.includes("/"))return e;let n=String(t.provider??"").split(".")[0]??"";return n!==""?`${n}/${e}`:e}function oe(t){
52
+ return typeof t.provider=="string"&&t.provider.toLowerCase().startsWith("mock")}function S(t,e){return {...m(t)?t:{},bivelio:{savingsReport:e}}}var Ie=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,
53
+ 4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,
54
+ 1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,
55
+ 1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),Ee=new TextEncoder;function h(t,e){return t>>>e|t<<32-e}function ae(t){let e=Ee.encode(t),n=e.length*
56
+ 8,r=(e.length+8>>6)+1,a=new Uint8Array(r*64);a.set(e),a[e.length]=128;let s=new DataView(a.buffer);s.setUint32(a.length-8,Math.floor(n/4294967296)),s.setUint32(a.length-4,n>>>0);let o=new Uint32Array(
57
+ [1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),i=new Uint32Array(64);for(let c=0;c<a.length;c+=64){for(let p=0;p<16;p++)i[p]=s.getUint32(c+p*4);for(let p=16;p<
58
+ 64;p++){let A=i[p-15],k=i[p-2],C=h(A,7)^h(A,18)^A>>>3,I=h(k,17)^h(k,19)^k>>>10;i[p]=i[p-16]+C+i[p-7]+I|0;}let d=o[0],f=o[1],g=o[2],l=o[3],v=o[4],y=o[5],x=o[6],R=o[7];for(let p=0;p<64;p++){let A=h(v,6)^
59
+ h(v,11)^h(v,25),k=v&y^~v&x,C=R+A+k+Ie[p]+i[p]|0,I=h(d,2)^h(d,13)^h(d,22),fe=d&f^d&g^f&g,pe=I+fe|0;R=x,x=y,y=v,v=l+C|0,l=g,g=f,f=d,d=C+pe|0;}o[0]=o[0]+d|0,o[1]=o[1]+f|0,o[2]=o[2]+g|0,o[3]=o[3]+l|0,o[4]=
60
+ o[4]+v|0,o[5]=o[5]+y|0,o[6]=o[6]+x|0,o[7]=o[7]+R|0;}let u="";for(let c=0;c<8;c++)u+=(o[c]>>>0).toString(16).padStart(8,"0");return u}var je={router:false,compression:false,elision:false,serialization:false,toolDiscovery:false,modelCascade:"off",outputCodebook:false,deferrable:false,semanticCache:false,verification:false};function qe(t,e,n={}){let r=a=>t?.[a]!==
61
+ false&&e?.[a]!==false;return {...je,exactCache:r("exactCache")&&n.sinReutilizar!==true,singleflight:r("singleflight")&&n.sinReutilizar!==true,deterministicResolvers:r("deterministicResolvers")&&n.sinResolvers!==
62
+ true}}function Ue(t,e){let n=t.readOnlyTools;if(typeof n=="function")try{return n(e)===!0}catch{return false}return Array.isArray(n)?n.includes(e):false}function se(t,e){let n=e.delProveedor!==true&&Ue(t,e.nombre);
63
+ return {id:e.nombre,intents:[],risk:n?"read":"write",...e.parametros!==void 0&&e.parametros!==null&&typeof e.parametros=="object"?{parameters:e.parametros}:{},...typeof e.descripcion=="string"?{description:e.
64
+ descripcion}:{}}}function M(t,e,n){if(t===null)return null;switch(typeof t){case "string":case "boolean":return t;case "number":return Number.isFinite(t)?t:String(t);case "bigint":return `${t.toString()}n`;case "\
65
+ undefined":case "function":case "symbol":return}let r=t;if(r instanceof Uint8Array)return e.push(r),{$bytes:e.length-1};if(r instanceof ArrayBuffer)return e.push(new Uint8Array(r)),{$bytes:e.length-1};if(ArrayBuffer.
66
+ isView(r))return e.push(new Uint8Array(r.buffer,r.byteOffset,r.byteLength)),{$bytes:e.length-1};if(r instanceof URL)return {$url:r.href};if(r instanceof Date)return {$date:Number.isNaN(r.getTime())?"inv\
67
+ alid":r.toISOString()};if(n.has(r))return "$cycle";n.add(r);try{if(Array.isArray(r))return r.map(s=>{let o=M(s,e,n);return o===void 0?null:o});if(r instanceof Map)return {$map:[...r.entries()].map(s=>M(
68
+ s,e,n))};if(r instanceof Set)return {$set:[...r.values()].map(s=>M(s,e,n))};let a={};for(let s of Object.keys(r).sort()){let o=M(r[s],e,n);o!==void 0&&(a[s]=o);}return a}finally{n.delete(r);}}async function ie(t){
69
+ let e=globalThis.crypto?.subtle;if(e){let r=new Uint8Array(await e.digest("SHA-256",t));return Array.from(r,a=>a.toString(16).padStart(2,"0")).join("")}let n="";for(let r=0;r<t.length;r+=32768)n+=String.
70
+ fromCharCode(...t.subarray(r,r+32768));return ae(n)}async function Ne(t){try{let e=[],n=JSON.stringify(M(t,e,new WeakSet))??"null",r=await Promise.all(e.map(ie)),a=new TextEncoder().encode(`${n}|${r.join(
71
+ ",")}`);return await ie(a)}catch{return null}}async function de(t,e){let n=await Ne(e.proyeccion),r=`${e.context?.authorizationScope??"default"}|bvsala-adapter:${n??"none"}`;return {model:e.model,messages:e.
72
+ messages,...e.tools.length>0?{tools:e.tools}:{},...typeof e.temperature=="number"?{temperature:e.temperature}:{},...typeof e.seed=="number"?{seed:e.seed}:{},context:{...e.context??{},authorizationScope:r},
73
+ savings:qe(t.savings,e.savings,{...e.restricciones,...n===null?{sinReutilizar:true}:{}})}}function ue(t,e){if(!(!t&&!e))return {...t??{},...e??{}}}function le(t){if(!t||typeof t!="object")return {};let e=t,
74
+ n={};return e.context&&typeof e.context=="object"&&(n.context=e.context),e.savings&&typeof e.savings=="object"&&(n.savings=e.savings),n}var $e="[bvsala] a streamed call finished but its savings report could not be produced; the model answer was delivered unchanged.";function dt(t){let e=Q("ai-sdk",t),n=t.reportInMetadata!==false;async function r(o,i){
75
+ let u=le(o.providerOptions?.bivelio),c;t.context&&(c=t.context({provider:i.provider,modelId:i.modelId,params:o}));let d=t.modelId?t.modelId({provider:i.provider,modelId:i.modelId}):re(i),f=(Array.isArray(
76
+ o.tools)?o.tools:[]).map(l=>se(t,{nombre:String(l.name??l.id??""),descripcion:typeof l.description=="string"?l.description:void 0,parametros:l.inputSchema??l.parameters,delProveedor:l.type==="provider"||
77
+ l.type==="provider-defined"}));return {req:await de(t,{model:d,messages:ee(o.prompt),tools:f,temperature:typeof o.temperature=="number"?o.temperature:void 0,seed:typeof o.seed=="number"?o.seed:void 0,context:ue(
78
+ c,u.context),savings:u.savings,proyeccion:{modelo:d,parametros:te(o)},restricciones:{sinResolvers:ne(o)}}),simulado:oe(i)}}function a(o){return {model:o.model,messages:o.messages,...o.tools?{tools:o.tools}:
79
+ {}}}return {specificationVersion:"v3",async wrapGenerate(o){let{req:i,simulado:u}=await r(o.params,o.model),c,d=j(a(i),async()=>(c=await P(d,()=>o.doGenerate()),q(c,u))),f=await e.generar(i,d);if(f.tipo===
80
+ "sin-informe")return c;let g=e.informe(f.result.report);if(f.tipo==="vivo"){let l=c;return n?{...l,providerMetadata:S(l.providerMetadata,g)}:l}return Ge(f.result,n?g:void 0,o.model)},async wrapStream(o){
81
+ let{req:i,simulado:u}=await r(o.params,o.model),{abierta:c,abrir:d}=X(),f,g,l=Object.assign(j(a(i),async()=>(f=await P(l,()=>o.doGenerate()),q(f,u)),()=>{let R=new L;return P(l,()=>o.doStream()).then(
82
+ p=>{g={...p,stream:ze(p.stream,R,e,l,u,n)},d();},p=>R.fail(p)),R}),{abierta:c}),v=o.params.abortSignal instanceof AbortSignal?o.params.abortSignal:void 0,y=await e.transmitir(i,l,v);if(y.tipo==="abiert\
83
+ o")return g;if(y.tipo==="sin-informe")return ce(f,void 0);let x=e.informe(y.result.report);return y.tipo==="entero"?ce(f,n?x:void 0):_e(y.result,n?x:void 0,o.model)},close(){e.close();}}}function ze(t,e,n,r,a,s){
84
+ let o=t.getReader(),i=new D;return new ReadableStream({async pull(u){let c;try{c=await o.read();}catch(l){e.fail(l),u.error(l);return}if(c.done){e.fail(new Error("[bvsala] the model stream ended withou\
85
+ t a finish part; nothing was measured.")),u.close();return}let d=c.value,f=i.anadir(d);if(d.type==="error"){e.fail(d.error??new Error("[bvsala] the model stream reported an error")),u.enqueue(d);return}
86
+ if(f!==void 0&&e.push({type:"text",delta:f}),d.type!=="finish"||e.cerrada){u.enqueue(d);return}e.push({type:"done",response:i.respuesta(d.usage,d.finishReason,a)}),e.end();let g=d;try{let l=await r.resultado,
87
+ v=n.informe(l.report);s&&(g={...d,providerMetadata:S(d.providerMetadata,v)});}catch{n.avisar("informe-del-stream",$e);}u.enqueue(g);},cancel(u){return e.fail(new Error("[bvsala] the stream was cancelled \
88
+ by its reader; nothing was measured.")),o.cancel(u)}})}function Ge(t,e,n){return {content:N(t),finishReason:$(t),usage:U,...e?{providerMetadata:S(void 0,e)}:{},response:{id:`bvsala-${t.requestId}`,modelId:n.
89
+ modelId,timestamp:new Date},warnings:[]}}function _e(t,e,n){let r=z(N(t),{usage:U,finishReason:$(t),...e?{providerMetadata:S(void 0,e)}:{}},{warnings:[],response:{id:`bvsala-${t.requestId}`,modelId:n.
90
+ modelId,timestamp:new Date}});return {stream:G(r)}}function ce(t,e){let n=t.response,r=z(Array.isArray(t.content)?t.content:[],{usage:t.usage,finishReason:t.finishReason,...e?{providerMetadata:S(t.providerMetadata,
82
91
  e)}:t.providerMetadata!==void 0?{providerMetadata:t.providerMetadata}:{}},{warnings:t.warnings,response:n?Object.fromEntries(Object.entries(n).filter(([a])=>a!=="headers"&&a!=="body")):void 0});return {
83
- stream:E(r),...t.request!==void 0?{request:t.request}:{},...n?.headers!==void 0?{response:{headers:n.headers}}:{}}}function Ye(t){let n=t?.providerMetadata?.bivelio?.savingsReport;if(!(!n||typeof n!="\
84
- object"||typeof n.requestId!="string"))return n}export{Ye as getSavingsReport,Xe as savingsMiddleware};
92
+ stream:G(r),...t.request!==void 0?{request:t.request}:{},...n?.headers!==void 0?{response:{headers:n.headers}}:{}}}function ut(t){let n=t?.providerMetadata?.bivelio?.savingsReport;if(!(!n||typeof n!="\
93
+ object"||typeof n.requestId!="string"))return n}export{ut as getSavingsReport,dt as savingsMiddleware};
@@ -29,6 +29,19 @@ interface AnthropicSavings {
29
29
  /**
30
30
  * The savings layer as an Anthropic SDK middleware:
31
31
  * `new Anthropic({ middleware: [savings.middleware] })`, last in the list.
32
+ *
33
+ * **Stop reasons.** The middleware speaks the official SDK's protocol to your
34
+ * code, so the `Message` you get keeps Anthropic's own `stop_reason`
35
+ * (`end_turn`, `max_tokens`, `stop_sequence`, `tool_use`, `pause_turn`,
36
+ * `refusal`, `model_context_window_exceeded`…) and `stop_details`, exactly as
37
+ * Anthropic sent them, in JSON and in stream. That is the SDK's contract and the
38
+ * layer does not rewrite it. An answer the layer served without calling
39
+ * Anthropic (from its cache or a local resolver) comes back as `end_turn`, or
40
+ * `tool_use` when it carries tool calls. What the layer normalises is its own report:
41
+ * {@link AnthropicSavings.reportFor} gives `qualityLedger.truncation.finishReason`
42
+ * in the closed set of 0.5 (`stop`, `length`, `tool_calls`, `content_filter`,
43
+ * `other`) and Anthropic's value, when it adds something, in
44
+ * `truncation.finishReasonDetail`.
32
45
  */
33
46
  declare function anthropicSavings(options: AnthropicSavingsOptions): AnthropicSavings;
34
47