@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 +5 -4
- package/dist/adapters/ai-sdk.js +87 -78
- package/dist/adapters/anthropic-sdk.d.ts +13 -0
- package/dist/adapters/anthropic-sdk.js +115 -102
- package/dist/adapters/langchain.js +67 -58
- package/dist/adapters/mastra.js +80 -71
- package/dist/gateway/bin.js +749 -754
- package/dist/index.d.ts +86 -1253
- package/dist/index.js +1441 -1447
- package/package.json +1 -1
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
|
-
|
|
125
|
-
`BVSALA_GATEWAY_MODELO_HERMANO`)
|
|
126
|
-
|
|
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.
|
|
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
|
|
package/dist/adapters/ai-sdk.js
CHANGED
|
@@ -1,84 +1,93 @@
|
|
|
1
|
-
import {createSavingsLayer,LicenseError
|
|
2
|
-
nothing more was sent.",
|
|
3
|
-
completada:false,...{}}}async function
|
|
4
|
-
t)===
|
|
5
|
-
function
|
|
6
|
-
async generate(a,
|
|
7
|
-
text",delta:
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
let u=n.run(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
|
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
|
|
22
|
-
"string"?t.value:
|
|
23
|
-
return
|
|
24
|
-
system",content:typeof n.content=="string"?n.content:
|
|
25
|
-
map(
|
|
26
|
-
tool":for(let a of r)a.type==="tool-result"&&e.push({role:"tool",content:
|
|
27
|
-
{}});break}}return e}var
|
|
28
|
-
entries(t))if(!(n==="toolCallId"||n==="id")&&!(n==="text"&&t.type==="text")){if(n==="providerOptions"||n==="providerMetadata"){e[n]=
|
|
29
|
-
t:[]).map(e=>
|
|
30
|
-
if(!
|
|
31
|
-
entries(t))n==="prompt"||n==="abortSignal"||n==="headers"||n==="providerOptions"||(e[n]=r);return e.prompt=
|
|
32
|
-
responseFormat;if(
|
|
33
|
-
void 0}function
|
|
34
|
-
outputTokens:g??0,complete:false}}let
|
|
35
|
-
void 0?{cacheWriteInputTokens:
|
|
36
|
-
g")return t.unified}function
|
|
37
|
-
|
|
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:
|
|
40
|
-
-end":
|
|
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=
|
|
42
|
-
text:this.texto,...this.toolCalls.length>0?{toolCalls:this.toolCalls}:{},...
|
|
43
|
-
t.content:[])
|
|
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
|
|
45
|
-
return {unified:(t.toolCalls?.length??0)>0?"tool-calls":"stop",raw:void 0}}function
|
|
46
|
-
response-metadata",...n.response}),t.forEach((a,
|
|
47
|
-
xt-start",id:o,...
|
|
48
|
-
{providerMetadata:a.providerMetadata}:{};r.push({type:"reasoning-start",id:o,...
|
|
49
|
-
id:o,...
|
|
50
|
-
{pull(n){e<t.length?n.enqueue(t[e++]):n.close();}})}function
|
|
51
|
-
return typeof t.provider=="string"&&t.provider.toLowerCase().startsWith("mock")}function
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
o}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
o
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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:
|
|
84
|
-
object"||typeof n.requestId!="string"))return n}export{
|
|
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
|
|