@bivelio/savings-layer 0.4.26 → 0.4.29

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
@@ -256,6 +256,19 @@ exists, as for Anthropic models), and `"unmeasured"` when the provider returned
256
256
  usage. Only `measured` and `reference` figures reach your invoice; estimated ones
257
257
  never do.
258
258
 
259
+ A repeat is valued by reference only when the call that ran reached the provider's
260
+ own API (`https://api.openai.com`, `https://api.anthropic.com` or
261
+ `https://generativelanguage.googleapis.com`), because the list price it is valued at
262
+ is the invoice only there. When `OpenAICompatibleProvider` or `AnthropicProvider`
263
+ points anywhere else — a proxy such as LiteLLM, a gateway, Azure, Bedrock, Vertex —
264
+ or when the Anthropic SDK or LangChain adapter reads that its client does, that call
265
+ leaves no reference: its repeats stay `estimated`, and the `reference` trace of the
266
+ call that ran says `unofficial-origin`. When the layer cannot tell where the call
267
+ went (a provider of your own, the AI SDK and Mastra adapters, a LangChain model that
268
+ does not expose its base URL), the rule applies as it always has. The layer reads the
269
+ configured base URL, not the wire: a custom `fetch` that sends the request elsewhere
270
+ is not seen.
271
+
259
272
  **Streaming.** `generateStream()` takes the same request and hands you the answer as
260
273
  the provider writes it, then the same `SavingsReport`:
261
274
 
@@ -679,6 +692,77 @@ const placedLayer = createSavingsLayer({
679
692
 
680
693
  </details>
681
694
 
695
+ <details>
696
+ <summary><b>Serverless: keep what the layer learns between instances</b></summary>
697
+
698
+ Calibrated reuse and `cacheBreakpoints: "auto"` learn from your traffic, and by default
699
+ what they learn lives in the process. On serverless platforms (Vercel Functions, AWS
700
+ Lambda) an instance may serve one request or live a few minutes, so neither would ever
701
+ get past its starting point. Give each one somewhere to keep it:
702
+
703
+ ```ts
704
+ import { InMemorySemanticCache } from "@bivelio/savings-layer";
705
+
706
+ // Any key-value client your instances share, such as Redis.
707
+ type SharedKeyValue = {
708
+ get(key: string): Promise<unknown>;
709
+ set(key: string, value: string, options?: { px: number }): Promise<unknown>;
710
+ };
711
+
712
+ async function serverlessLayer(kv: SharedKeyValue) {
713
+ const semanticCache = new InMemorySemanticCache({ calibration: { maxErrorRate: 0.02 } });
714
+ const saved = await kv.get("bvsala:semantic-calibration");
715
+ if (saved) semanticCache.importCalibration(saved); // the object or its JSON text
716
+
717
+ const layer = createSavingsLayer({
718
+ provider,
719
+ licenseKey: process.env.BIVELIO_LICENSE_KEY,
720
+ semanticCache,
721
+ cacheBreakpoints: "auto",
722
+ cacheBreakpointStore: {
723
+ get: (key) => kv.get(key),
724
+ set: (key, value, ttlMs) => kv.set(key, value, { px: ttlMs }),
725
+ },
726
+ });
727
+
728
+ // After handling requests with `layer`, save the calibration:
729
+ const save = async () => {
730
+ await semanticCache.settled();
731
+ await kv.set("bvsala:semantic-calibration", JSON.stringify(semanticCache.exportCalibration()));
732
+ };
733
+ return { layer, save };
734
+ }
735
+ ```
736
+
737
+ - **Breakpoint placement.** The store holds prompt-prefix fingerprints, timestamps and
738
+ counts, one key per traffic class, never prompt text. The layer reads it before
739
+ placing breakpoints and reads and rewrites it after the provider answers, so every
740
+ instance extends the same measurement. If the store fails, that request is placed as
741
+ a fresh instance would place it and nothing is written over what others learned.
742
+ Without a store nothing changes.
743
+ - **Calibration.** The saved state is the whole experiment: both halves of the labels,
744
+ how many tests have already drawn on the confidence budget, and the floor in force.
745
+ Restoring it continues the same calibration, so the bound keeps holding across
746
+ restarts; it never starts the budget over. A state recorded under another embedder,
747
+ verifier, judge or configuration is refused with `CalibrationStateError`. If you pass
748
+ your own `embed`, `verify` or `judge`, name them (`embedderId`, `verifierId`,
749
+ `calibration.judgeId`) so a state can say what it was recorded with.
750
+ - **One line of history.** The bound holds along one line: restore the latest state and
751
+ save from where it went. Instances that continue the same state at the same time
752
+ each spend its remaining confidence again, and the last one to save overwrites the
753
+ others' labels. For one bound across many concurrent instances, calibrate in a single
754
+ long-lived process, or offline with `calibrateSemanticFloor()`, and give every
755
+ instance the certified floor as `acceptThreshold`. The cached answers themselves
756
+ still live in each instance's memory.
757
+ - **Why a predicted cache read did not happen** (Anthropic's own API). With
758
+ `cacheMissDiagnostics: true`, the layer asks Anthropic to compare each marked request
759
+ with the one whose cache entry it expected to read, and puts the provider's
760
+ `cache_miss_reason` in `report.traces` when that read does not arrive. Anthropic
761
+ keeps a short-lived fingerprint (hashes and token-count estimates) of each request
762
+ that opts in; check that against your data-retention terms first.
763
+
764
+ </details>
765
+
682
766
  <details>
683
767
  <summary><b>Structured output — validated <code>data</code>, not just text</b></summary>
684
768
 
@@ -710,10 +794,11 @@ console.log(data.answer); // 8
710
794
 
711
795
  When you pass `tools` and the model asks to invoke one, the reply is not the final
712
796
  answer: `text` is empty by design and the request is in `toolCalls`. Execute it,
713
- append the result to `messages`, and call `generate()` again.
797
+ append the assistant turn and one `role: "tool"` message per call to `messages`, and
798
+ call `generate()` again.
714
799
 
715
800
  ```ts
716
- import type { ToolDescriptor } from "@bivelio/savings-layer";
801
+ import type { ChatMessage, ToolDescriptor } from "@bivelio/savings-layer";
717
802
 
718
803
  const tools: ToolDescriptor[] = [
719
804
  {
@@ -730,25 +815,39 @@ const tools: ToolDescriptor[] = [
730
815
  },
731
816
  ];
732
817
 
733
- const res = await layer.generate({
734
- model: "openai/gpt-4o-mini",
735
- messages: [{ role: "user", content: "What's the weather in Madrid?" }],
736
- tools,
737
- });
818
+ // ← your tool
819
+ const getWeather = async (city: string): Promise<string> => `${city}: 21 °C, clear`;
738
820
 
739
- if (res.toolCalls?.length) {
740
- // res.finishReason === "tool_calls"
821
+ const messages: ChatMessage[] = [{ role: "user", content: "What's the weather in Madrid?" }];
822
+ let res = await layer.generate({ model: "openai/gpt-4o-mini", messages, tools });
823
+
824
+ while (res.toolCalls?.length) {
825
+ // res.finishReason === "tool_calls". Send the calls back as they came, ids included.
826
+ messages.push({ role: "assistant", content: res.text, toolCalls: res.toolCalls });
741
827
  for (const call of res.toolCalls) {
742
828
  const args = JSON.parse(call.arguments) as { city: string };
743
- console.log(call.name, args); // ← run your tool here, then append its result
829
+ const output = await getWeather(args.city);
830
+ messages.push({ role: "tool", toolCallId: call.id, name: call.name, content: output });
744
831
  }
745
- } else {
746
- console.log(res.text);
832
+ res = await layer.generate({ model: "openai/gpt-4o-mini", messages, tools });
747
833
  }
834
+ console.log(res.text);
748
835
  ```
749
836
 
837
+ - **Ids.** Each result carries the `toolCallId` of the call it answers, and every call
838
+ of a turn gets its result before the next user or assistant message. On Anthropic
839
+ that is what lets the turn travel as `tool_use`/`tool_result` blocks (with the tool
840
+ still in that request's `tools`); otherwise it is sent as plain text, as before, and
841
+ the SDK warns once.
842
+ - **Errors.** When a tool fails, put the error in `content` and set `isError: true`.
843
+ Anthropic receives it as `is_error`; providers without such a flag get the text.
844
+
750
845
  A tool‑call turn is never served from cache and never counted as an avoided call:
751
- an action that has not run yet cannot be a saving.
846
+ an action that has not run yet cannot be a saving. The answer that follows a tool loop
847
+ can be, and its cache key covers the loop: each call's name and arguments, which call
848
+ each result answers and its `isError`. Two conversations that differ only there never
849
+ share a cached answer; the fresh call ids of a new run of the same loop are not a
850
+ difference.
752
851
 
753
852
  **Large catalogues: let the provider search them (opt‑in).** With hundreds of tools
754
853
  (several MCP servers, say), `savings: { toolSearch: "auto" }` sends every tool deferred
@@ -767,6 +866,12 @@ cached prompt prefix stays the same from one question to the next.
767
866
  search on every request even with a warm prompt cache. `"always"` skips those checks
768
867
  (for example behind a proxy that forwards the search blocks). Requests with an output
769
868
  contract, or with the model cascade on, keep the selector.
869
+ - **Across turns.** Append the assistant turn with its `toolCalls` (ids as returned)
870
+ before the tool results, as in any tool conversation. The Anthropic adapter then sends
871
+ the earlier search results back in that turn, so the model calls the tools it already
872
+ found without searching again. It keeps them in memory, per adapter instance and
873
+ bounded; a turn it no longer remembers (another process, say) goes out as before and
874
+ the model searches again.
770
875
  - **Whose saving.** The provider's. Your usage counter shows it; the layer credits
771
876
  nothing for it and charges no commission on it.
772
877
 
@@ -1,84 +1,84 @@
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 ae="[bvsala] internal: the layer changed a request this adapter must forward unchanged; no\
2
- thing was sent.",se="[bvsala] internal: the layer asked for a second model call within one framework call; nothing more was sent.",ie="[bvsala] internal: the layer called the model outside a framework\
3
- call; nothing was sent.";function C(t,e,n){return {renderizado:t,generar:e,...n?{transmitir:n}:{},invocada:false,completada:false}}async function x(t,e){try{let n=await e();return t.completada=!0,n}catch(n){
4
- throw t.errorDelMarco={error:n},n}}function de(t,e){if(t===e)return true;try{return stableStringify(t)===stableStringify(e)}catch{return false}}function N(t,e){let n=t??[],r=e??[];return n.length===r.length&&n.every((o,i)=>de(o,r[i]))}
5
- function ue(t,e){return t.model===e.model&&N(t.messages,e.messages)&&N(t.tools,e.tools)}function G(t,e){let n=r=>{let o=e.getStore();if(!o)throw new Error(ie);if(o.invocada)throw new Error(se);if(!ue(
6
- r,o.renderizado))throw new Error(ae);return o.invocada=true,o};return {id:`bivelio-adapter:${t}`,async generate(r,o){return n(r).generar(o?.signal)},async*generateStream(r,o){let i=n(r);if(i.transmitir){
7
- yield*i.transmitir(o?.signal);return}let a=await i.generar(o?.signal);a.text!==""&&(yield {type:"text",delta:a.text}),yield {type:"done",response:a};}}}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 _(t,e){return e instanceof LicenseError||t.errorDelMarco&&t.errorDelMarco.error===e?false:t.invocada&&
9
- t.completada}var F="[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 a of fe)e[a]!==void 0&&(r[a]=e[a]);let o=createSavingsLayer({...r,provider:G(t,n)}),i=(a,s)=>$(e.silenceWarnings,`${t}:${a}`,s);return {ejecutar(a,s){return n.run(s,()=>o.generate(a))},async generar(a,s){
11
- try{let d=await n.run(s,()=>o.generate(a));return s.invocada?{tipo:"vivo",result:d}:{tipo:"atajo",result:d}}catch(d){if(_(s,d))return i("sin-informe",F),{tipo:"sin-informe"};throw d}},async transmitir(a,s,d){
12
- let u=n.run(s,()=>o.generateStream(a,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(_(s,l))return i(
13
- "sin-informe",F),{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(a){let s=JSON.parse(JSON.
14
- stringify(a));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(){o.close();}}}function B(){
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
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.
16
16
  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
17
  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
18
  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 p(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(p):[]}function D(t){return t.filter(e=>e.type===
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
20
  "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 pe(t){if(!p(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 D(e(t.value));default:
23
- return v(t)}function e(n){return Array.isArray(n)?n.filter(p):[]}}function V(t){let e=[];for(let n of Array.isArray(t)?t:[]){if(!p(n))continue;let r=J(n.content);switch(n.role){case "system":e.push({role:"\
24
- system",content:typeof n.content=="string"?n.content:D(r)});break;case "user":e.push({role:"user",content:D(r)});break;case "assistant":{let o=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:D(r),...o.length>0?{toolCalls:o}:{}});break}case "\
26
- tool":for(let o of r)o.type==="tool-result"&&e.push({role:"tool",content:pe(o.output??o.result),...typeof o.toolCallId=="string"?{toolCallId:o.toolCallId}:{},...typeof o.toolName=="string"?{name:o.toolName}:
27
- {}});break}}return e}var ge=new Set(["bivelio","mastra"]);function k(t){if(!p(t))return t;let e={};for(let[n,r]of Object.entries(t))ge.has(n)||(e[n]=r);return e}function me(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]=k(r);continue}e[n]=r;}return e}function ve(t){return (Array.isArray(t)?
29
- t:[]).map(e=>p(e)?{role:e.role,content:typeof e.content=="string"?"$text":J(e.content).map(me),providerOptions:k(e.providerOptions)}:e)}var ye=new Set(["anthropic-beta","openai-beta"]);function he(t){
30
- if(!p(t))return;let e={};for(let[n,r]of Object.entries(t))ye.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=ve(t.prompt),e.headers=he(t.headers),e.providerOptions=k(t.providerOptions),e}function H(t){let e=t.
32
- responseFormat;if(p(e)&&e.type==="json")return true;let n=t.toolChoice;return p(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 Re(t,e){let n=p(t)?t:{},r=p(n.inputTokens)?n.inputTokens:void 0,o=p(n.outputTokens)?n.outputTokens:void 0;if(!r||!o){let c=m(n.inputTokens),g=m(n.outputTokens);return {inputTokens:c??0,
34
- outputTokens:g??0,complete:false}}let i=m(r.total),a=m(r.cacheRead),s=m(r.cacheWrite),d=m(o.total),f=m(o.reasoning);return {inputTokens:i??0,outputTokens:d??0,...a!==void 0?{cachedInputTokens:a}:{},...s!==
35
- void 0?{cacheWriteInputTokens:s}:{},...f!==void 0?{reasoningTokens:f}:{},...i!==void 0&&d!==void 0&&!e?{}:{complete:false}}}function we(t){if(typeof t=="string")return t;if(p(t)&&typeof t.unified=="strin\
36
- g")return t.unified}function Se(t){switch(t){case void 0:return;case "tool-calls":return "tool_calls";case "content-filter":return "content_filter";default:return t}}function xe(t){return p(t)&&Object.keys(
37
- k(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:
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:
38
38
  "";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
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":xe(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 o=we(n),i=Se(o),a=this.reproducible&&o==="stop";return {
42
- text:this.texto,...this.toolCalls.length>0?{toolCalls:this.toolCalls}:{},...i?{finishReason:i}:{},usage:Re(e,r),...a?{}:{replayable:false}}}};function P(t,e){let n=new R;for(let r of Array.isArray(t.content)?
43
- t.content:[])p(r)&&n.anadir(r);return n.respuesta(t.usage,t.finishReason,e)}var T={inputTokens:{total:0,noCache:0,cacheRead:0,cacheWrite:0},outputTokens:{total:0,text:0,reasoning:0}};function I(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 L(t){
45
- return {unified:(t.toolCalls?.length??0)>0?"tool-calls":"stop",raw:void 0}}function O(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((o,i)=>{if(!p(o))return;let a=`bvsala-${i}`;if(o.type==="text"){let s=o.providerMetadata!==void 0?{providerMetadata:o.providerMetadata}:{};r.push({type:"te\
47
- xt-start",id:a,...s}),typeof o.text=="string"&&o.text!==""&&r.push({type:"text-delta",id:a,delta:o.text}),r.push({type:"text-end",id:a,...s});}else if(o.type==="reasoning"){let s=o.providerMetadata!==void 0?
48
- {providerMetadata:o.providerMetadata}:{};r.push({type:"reasoning-start",id:a,...s}),typeof o.text=="string"&&o.text!==""&&r.push({type:"reasoning-delta",id:a,delta:o.text}),r.push({type:"reasoning-end",
49
- id:a,...s});}else r.push(o);}),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 Z(t){let e=String(t.modelId??"");if(e.includes("/"))return e;let n=String(t.provider??"").split(".")[0]??"";return n!==""?`${n}/${e}`:e}function Q(t){
51
- return typeof t.provider=="string"&&t.provider.toLowerCase().startsWith("mock")}function y(t,e){return {...p(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=o=>t?.[o]!==false&&e?.[o]!==false;return {...De,exactCache:r("exactCache")&&n.sinReutilizar!==true,singleflight:r("singleflight")&&n.sinReutilizar!==true,deterministicResolvers:r("det\
53
- erministicResolvers")&&n.sinResolvers!==true}}function Ae(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 Y(t,e){
54
- let n=e.delProveedor!==true&&Ae(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}:{},
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
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
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
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 a=w(i,e,n);return a===void 0?null:
59
- a});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 o={};for(let i of Object.keys(r).sort()){let a=w(r[i],e,n);
60
- a!==void 0&&(o[i]=a);}return o}finally{n.delete(r);}}async function X(t){let e=globalThis.crypto?.subtle;if(e){let r=new Uint8Array(await e.digest("SHA-256",t));return Array.from(r,o=>o.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 Me(t){try{let e=[],n=JSON.stringify(w(t,e,new WeakSet))??"null",r=await Promise.
62
- all(e.map(X)),o=new TextEncoder().encode(`${n}|${r.join(",")}`);return await X(o)}catch{return null}}async function ee(t,e){let n=await Me(e.proyeccion),r=`${e.context?.authorizationScope??"default"}|\
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
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 te(t,e){if(!(!t&&!e))return {...t??{},...e??
65
- {}}}function ne(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 Ce="[bvsala] a streamed call finished but its savings report could not be produced; the model answer was delivered unchanged.";function He(t){let e=W("ai-sdk",t),n=t.reportInMetadata!==false;async function r(a,s){
66
- let d=ne(a.providerOptions?.bivelio),f;t.context&&(f=t.context({provider:s.provider,modelId:s.modelId,params:a}));let u=t.modelId?t.modelId({provider:s.provider,modelId:s.modelId}):Z(s),c=(Array.isArray(
67
- a.tools)?a.tools:[]).map(l=>Y(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 ee(t,{model:u,messages:V(a.prompt),tools:c,temperature:typeof a.temperature=="number"?a.temperature:void 0,seed:typeof a.seed=="number"?a.seed:void 0,context:te(
69
- f,d.context),savings:d.savings,proyeccion:{modelo:u,parametros:K(a)},restricciones:{sinResolvers:H(a)}}),simulado:Q(s)}}function o(a){return {model:a.model,messages:a.messages,...a.tools?{tools:a.tools}:
70
- {}}}return {specificationVersion:"v3",async wrapGenerate(a){let{req:s,simulado:d}=await r(a.params,a.model),f,u=C(o(s),async()=>(f=await x(u,()=>a.doGenerate()),P(f,d))),c=await e.generar(s,u);if(c.tipo===
71
- "sin-informe")return f;let g=e.informe(c.result.report);if(c.tipo==="vivo"){let l=f;return n?{...l,providerMetadata:y(l.providerMetadata,g)}:l}return Te(c.result,n?g:void 0,a.model)},async wrapStream(a){
72
- let{req:s,simulado:d}=await r(a.params,a.model),{abierta:f,abrir:u}=B(),c,g,l=Object.assign(C(o(s),async()=>(c=await x(l,()=>a.doGenerate()),P(c,d)),()=>{let M=new b;return x(l,()=>a.doStream()).then(
73
- S=>{g={...S,stream:Pe(S.stream,M,e,l,d,n)},u();},S=>M.fail(S)),M}),{abierta:f}),A=a.params.abortSignal instanceof AbortSignal?a.params.abortSignal:void 0,h=await e.transmitir(s,l,A);if(h.tipo==="abiert\
74
- o")return g;if(h.tipo==="sin-informe")return re(c,void 0);let q=e.informe(h.result.report);return h.tipo==="entero"?re(c,n?q:void 0):Ie(h.result,n?q:void 0,a.model)},close(){e.close();}}}function Pe(t,e,n,r,o,i){
75
- let a=t.getReader(),s=new R;return new ReadableStream({async pull(d){let f;try{f=await a.read();}catch(l){e.fail(l),d.error(l);return}if(f.done){e.fail(new Error("[bvsala] the model stream ended withou\
76
- t a finish part; nothing was measured.")),d.close();return}let u=f.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,o)}),e.end();let g=u;try{let l=await r.resultado,
78
- A=n.informe(l.report);i&&(g={...u,providerMetadata:y(u.providerMetadata,A)});}catch{n.avisar("informe-del-stream",Ce);}d.enqueue(g);},cancel(d){return e.fail(new Error("[bvsala] the stream was cancelled \
79
- by its reader; nothing was measured.")),a.cancel(d)}})}function Te(t,e,n){return {content:I(t),finishReason:L(t),usage:T,...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=O(I(t),{usage:T,finishReason:L(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 re(t,e){let n=t.response,r=O(Array.isArray(t.content)?t.content:[],{usage:t.usage,finishReason:t.finishReason,...e?{providerMetadata:y(t.providerMetadata,
82
- e)}:t.providerMetadata!==void 0?{providerMetadata:t.providerMetadata}:{}},{warnings:t.warnings,response:n?Object.fromEntries(Object.entries(n).filter(([o])=>o!=="headers"&&o!=="body")):void 0});return {
83
- stream:E(r),...t.request!==void 0?{request:t.request}:{},...n?.headers!==void 0?{response:{headers:n.headers}}:{}}}function Ze(t){let n=t?.providerMetadata?.bivelio?.savingsReport;if(!(!n||typeof n!="\
84
- object"||typeof n.requestId!="string"))return n}export{Ze as getSavingsReport,He as savingsMiddleware};
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,
82
+ 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};