@bivelio/savings-layer 0.4.31 → 0.4.32

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
@@ -211,7 +211,8 @@ import { createSavingsLayer, OpenAICompatibleProvider } from "@bivelio/savings-l
211
211
  // Your provider. LLM traffic goes straight to it — the SDK never proxies it.
212
212
  // Any OpenAI-compatible endpoint works: OpenAI, Azure, vLLM, SGLang, a gateway.
213
213
  // Model ids are qualified (`openai/gpt-4o-mini`); the prefix is stripped on the
214
- // wire for OpenAI and Azure and kept for gateways — see `stripProviderPrefix`.
214
+ // wire for OpenAI, Azure and Google's Gemini API and kept for gateways — see
215
+ // `stripProviderPrefix`.
215
216
  const provider = new OpenAICompatibleProvider({
216
217
  baseUrl: "https://api.openai.com/v1",
217
218
  apiKey: process.env.OPENAI_API_KEY,
@@ -286,16 +287,41 @@ Most refusals carry no signal from the API: the model writes "I can't help with
286
287
  as ordinary text and ends with `end_turn` or `stop`. The layer also looks for these,
287
288
  with a conservative text heuristic. It checks only the opening of the answer, or the
288
289
  whole answer when it is short, and it needs a real refusal clause, such as "I'm sorry,
289
- but I can't help with that", "I cannot assist" or "As an AI, I cannot provide". A
290
- single word is not enough. It covers English, Spanish, Catalan, French, German,
291
- Italian and Portuguese. A match is measured and served as usual. It is not written to
292
- the exact or semantic cache, and it is not replayed by reference. A concurrent
293
- identical request served from it is `estimated`. The trace says why
294
- (`skipReason: "text_refusal"`). A refusal already stored by an earlier version is not
295
- served either. In the gateway, the coalesced twin of such a response is `estimated`
296
- (`primary-text-refusal`). A false positive costs one cache hit. A normal answer that
297
- starts with "Sorry for the delay, here is…", or has "I can't" later on, is cached as
298
- before.
290
+ but I can't help with that", "I cannot assist", "I can't determine…" or "As an AI, I
291
+ cannot provide". After an apology, any verb counts ("I'm sorry, but I can't
292
+ determine…"), and so does a stated reason with no "I can't" ("I'm sorry, but
293
+ accessing … is illegal", "… would be a violation of…"). When the answer opens with
294
+ the refusal itself ("I can't", "I won't", "I'm not going to", "I'm unable to", and
295
+ "No puedo", "Je ne peux pas", "Ich kann … nicht"…), any verb counts too ("I can't
296
+ argue that…"), except for a tested list of idioms that are not refusals ("I can't
297
+ wait", "I won't lie", "I can't find any issues", "I can't be sure, but…").
298
+ A single word is not enough.
299
+ An answer that opens with empathy and, in its first two sentences, sends the user to
300
+ a mental health professional, a crisis line, emergency services or someone they
301
+ trust, instead of answering, counts too (rule `redirection`). It covers English,
302
+ Spanish, Catalan, French, German, Italian and Portuguese. A match is measured and
303
+ served as usual. It is not written to the exact or semantic cache, and it is not
304
+ replayed by reference. A concurrent identical request served from it is `estimated`.
305
+ The trace says why (`skipReason: "text_refusal"`, with the `rule`). A refusal
306
+ already stored by an earlier version is not served either. In the gateway, the
307
+ coalesced twin of such a response is `estimated` (`primary-text-refusal`). A false
308
+ positive costs one cache hit. A normal answer that starts with "Sorry for the delay,
309
+ here is…", praises with "I can't recommend this enough", has "I can't" later on, or
310
+ offers empathy with practical help and no referral ("I'm sorry to hear about your
311
+ flight; here are three options…") is cached as before.
312
+
313
+ **Sensitive topics.** A request whose user turns touch self-harm or suicide, a mental
314
+ health crisis or a medical emergency ("How do I commit suicide?", "I'm having a panic
315
+ attack", "my friend is not breathing") is never read from or written to the exact or
316
+ semantic cache, even when the answer is useful, and leaves no reference record. It is
317
+ measured and served as usual; a concurrent identical request served from it is
318
+ `estimated`. The `policy` and `cache-write` traces say why
319
+ (`skipReason: "sensitive_topic"`, with the `category`). The check is lexical and
320
+ conservative: phrases, not single words ("kill a Python process", "Suicide Squad" and
321
+ "cut my hair" do not count). It covers the same twelve languages as the freshness
322
+ and personalization checks, with shorter lists outside English, Spanish, Catalan,
323
+ French, German, Italian and Portuguese. In the gateway, the coalesced twin of such a
324
+ request is `estimated` (`sensitive-topic`). A false positive costs one cache hit.
299
325
 
300
326
  **Streaming.** `generateStream()` takes the same request and hands you the answer as
301
327
  the provider writes it, then the same `SavingsReport`:
@@ -453,6 +479,45 @@ It runs once per HTTP attempt, inside the SDK's retries: an attempt the provider
453
479
  rejects reaches the SDK unchanged and is not recorded. Only message creation goes
454
480
  through the layer; `countTokens`, batches, models and files pass untouched.
455
481
 
482
+ The middleware forwards your request body unchanged, history included, so it never
483
+ edits a turn before a thinking block. It also does not remove parameters the model
484
+ rejects. On Claude Sonnet 5.5, Opus 5.5, Fable 5.1 and Mythos 5.1 a forced
485
+ `tool_choice` (`any` or `tool`) returns a 400. On those models, and on Opus 4.7/4.8,
486
+ Opus 5, Sonnet 5 and Fable 5, so does a non-default `temperature`, `top_p` or `top_k`.
487
+ The middleware warns once per model and cause (`silenceWarnings` turns it off) and
488
+ the API's 400 reaches you unchanged.
489
+
490
+ <details>
491
+ <summary><b>Claude Sonnet 5.5, Opus 5.5, Fable 5.1: what <code>AnthropicProvider</code> sends instead</b></summary>
492
+
493
+ These models reject some request parameters with a 400 ([forcing tool
494
+ use](https://platform.claude.com/docs/en/agents-and-tools/tool-use/define-tools#forcing-tool-use),
495
+ [Sonnet 5.5](https://platform.claude.com/docs/en/models/sonnet-5-5/overview)).
496
+ `AnthropicProvider` sends a request they accept instead of failing:
497
+
498
+ - **Output contract.** A forced `tool_choice` returns a 400 on these models, with or
499
+ without thinking. When your schema meets `strict` mode, the contract travels as
500
+ structured output (`output_config.format`). Without your tools, the provider still
501
+ enforces the contract. With your tools, they stay callable with `tool_choice: auto`
502
+ and the final text answer comes back in the contract's shape. When your schema does
503
+ not meet `strict`, the contract travels as a tool the model is not forced to call,
504
+ with one sentence in the system prompt that tells it to answer through that tool.
505
+ Models that support forced tool use (Opus 5, Sonnet 5 and the 4.x models) get the
506
+ same request as before.
507
+ - **`temperature`.** A non-default value is dropped, with one warning per model,
508
+ because it can only return a 400. The answer is then sampled, not deterministic.
509
+ `temperature: 1`, the API default, is sent as is.
510
+ - **A model the table does not list** (a new model or a gateway alias): when the API
511
+ rejects either parameter, the provider repeats the request once without it and
512
+ remembers the model for later requests. A 400 is not billed, so the retry is not
513
+ counted in `retries`.
514
+ - **Thinking blocks.** `ChatMessage` does not carry thinking blocks, so this adapter
515
+ never sends one. The preserved-thinking check, which returns a 400 when a turn
516
+ before a thinking block has been edited, has nothing to check on its requests, even
517
+ when the levers that rewrite history are on.
518
+
519
+ </details>
520
+
456
521
  ## What you get on every request
457
522
 
458
523
  A `SavingsReport` with the numbers behind every claim, kept in **four separate
@@ -681,7 +746,16 @@ const agentLayer = createSavingsLayer({
681
746
 
682
747
  By default the layer writes the provider's prompt cache at two fixed places: the end
683
748
  of the system header and the end of the history before your last user message, and
684
- stops marking a prefix whose measured hit rate does not pay the write premium.
749
+ stops marking a prefix whose measured hit rate does not pay the write premium. On
750
+ Anthropic, where a write costs 1.25x, the history and a tool catalogue sent without a
751
+ system header are marked only when the request itself shows they will be sent again:
752
+ a tool-loop step after your last user message, or a conversation already past its
753
+ second turn. The first follow-up of a conversation (`[question, answer, question]`)
754
+ marks only the system header, so two-turn chats pay no premium that nothing reads.
755
+ In an agent loop with no system header, the end of the tool list is marked once the
756
+ catalogue reaches the model's minimum cacheable size (512 tokens on Claude Sonnet 5.5
757
+ and Opus 5.5, 1,024 on Sonnet 5, 4,096 on Haiku 4.5). That discount is the provider's
758
+ cache on your bytes: it is never credited as the layer's saving.
685
759
 
686
760
  `cacheBreakpoints: "auto"` places them from what your traffic actually does. The layer
687
761
  compares each request's prefix with the ones it sent before, per model, tool set and
@@ -846,6 +920,25 @@ request is repeated once with the other one (nothing was generated, so nothing i
846
920
  billed twice) and the model is remembered. To choose the field yourself:
847
921
  `new OpenAICompatibleProvider({ baseUrl, maxTokensParam: "max_completion_tokens" })`.
848
922
 
923
+ **OpenAI-compatible endpoints that are not OpenAI** (Gemini's
924
+ `generativelanguage.googleapis.com/v1beta/openai`, LiteLLM, vLLM, Ollama, a router).
925
+ `prompt_cache_key`, OpenAI's prefix-cache routing hint, goes only to OpenAI's own API:
926
+ Gemini answers 400 to a field it does not know, and up to 0.4.31 every request with a
927
+ cached prefix failed there. A proxy in front of OpenAI that forwards it can opt in with
928
+ `sendPromptCacheKey: true`. Any optional field an endpoint still rejects by name
929
+ (`prompt_cache_key`, `service_tier`, `seed`, `reasoning_effort`) is dropped, the request
930
+ repeated once and the model remembered; `reasoning_effort` is never dropped on OpenAI's
931
+ own API, where its 400 is the answer. Gemini leaves its thinking tokens out of
932
+ `completion_tokens` and bills them as output, so the layer counts output as
933
+ `total_tokens − prompt_tokens` whenever the total is larger (and reports the difference
934
+ as reasoning); on OpenAI's API `completion_tokens` already include reasoning and nothing
935
+ is added. Gemini stops a filtered answer with `finish_reason: "content_filter: OTHER"`
936
+ (or another reason): it is `finishReason: "content_filter"` (the adapter keeps the
937
+ reason in `finishReasonDetail` and the report's cache trace names it), and like every
938
+ provider refusal it is measured, never
939
+ cached and never credited. Google does not document that such refusals are free, so
940
+ they are costed from their `usage` like any call.
941
+
849
942
  The cap is yours, not a saving: it is never credited as output avoided. An answer
850
943
  it cut (`finishReason: "length"`) is not cached, and
851
944
  `report.qualityLedger.truncation` says the limit was yours.
@@ -904,6 +997,18 @@ console.log(res.text);
904
997
  the SDK warns once.
905
998
  - **Errors.** When a tool fails, put the error in `content` and set `isError: true`.
906
999
  Anthropic receives it as `is_error`; providers without such a flag get the text.
1000
+ - **Gemini 3's thought signature.** Through its OpenAI-compatible endpoint Gemini
1001
+ returns each call with `extra_content.google.thought_signature` and rejects the next
1002
+ turn with a 400 if the call comes back without it. It arrives in `call.extraContent`;
1003
+ pushing `res.toolCalls` back as they came (as above) sends it back untouched. It is
1004
+ opaque and not part of any cache key.
1005
+ - **gpt-5.6-sol, gpt-5.6-terra and gpt-5.6-luna with tools need `reasoningEffort: "none"`.**
1006
+ On Chat Completions OpenAI rejects function tools for these models unless
1007
+ `reasoning_effort` is `"none"` («Function tools with reasoning_effort are not supported for gpt-5.6-sol in
1008
+ /v1/chat/completions»). Declare it on the request:
1009
+ `layer.generate({ model: "openai/gpt-5.6-sol", messages, tools, reasoningEffort: "none" })`.
1010
+ The layer never picks an effort itself: without the field nothing is sent. It is part
1011
+ of the cache key, like `temperature` and `seed`.
907
1012
 
908
1013
  A tool‑call turn is never served from cache and never counted as an avoided call:
909
1014
  an action that has not run yet cannot be a saving. The answer that follows a tool loop
@@ -1,67 +1,73 @@
1
1
  import {createSavingsLayer,LicenseError,sha256,stableStringify}from'@bivelio/savings-layer';import {AsyncLocalStorage}from'async_hooks';var x=t=>typeof t=="number"&&Number.isFinite(t)&&t>0?t:0;function J(t){if(!Array.isArray(t))return null;let e={input:0,output:0,cacheRead:0,cacheWrite:0,cacheWrite1h:0,iteraciones:0};for(let n of t){if(n===
2
2
  null||typeof n!="object")continue;let r=n;if(r.type!=="compaction")continue;e.iteraciones++,e.input+=x(r.input_tokens),e.output+=x(r.output_tokens),e.cacheRead+=x(r.cache_read_input_tokens);let o=r.cache_creation,
3
3
  s=x(o?.ephemeral_5m_input_tokens),a=x(o?.ephemeral_1h_input_tokens),i=typeof r.cache_creation_input_tokens=="number"?x(r.cache_creation_input_tokens):s+a;e.cacheWrite+=i,e.cacheWrite1h+=Math.min(a,i);}
4
- return e.iteraciones>0?e:null}function B(t,e,n){let r=t??{},o=J(r.iterations),s=W(r.cache_read_input_tokens,o?.cacheRead),a=W(r.cache_creation_input_tokens,o?.cacheWrite),i=r.cache_creation?.ephemeral_1h_input_tokens,u=typeof i=="\
4
+ return e.iteraciones>0?e:null}function W(t,e,n){let r=t??{},o=J(r.iterations),s=F(r.cache_read_input_tokens,o?.cacheRead),a=F(r.cache_creation_input_tokens,o?.cacheWrite),i=r.cache_creation?.ephemeral_1h_input_tokens,l=typeof i=="\
5
5
  number"||(o?.cacheWrite1h??0)>0?Math.min(Math.max(0,(typeof i=="number"?i:0)+(o?.cacheWrite1h??0)),a??0):void 0,d=(r.input_tokens??0)+(o?.input??0)+(a??0)+(s??0),g=(e??0)+(o?.output??0),m=typeof r.input_tokens!=
6
- "number",h=typeof e!="number";return {usage:{inputTokens:d,outputTokens:g,...s!=null?{cachedInputTokens:s}:{},...a!=null?{cacheWriteInputTokens:a}:{},...u!==void 0?{cacheWrite1hInputTokens:u}:{},...n||
7
- h||o?{}:{reasoningTokens:0},...m||h?{complete:false}:{}},entradaAusente:m,salidaAusente:h}}function W(t,e){return e?(t??0)+e:t}function F(t){let e=t?.service_tier;return typeof e=="string"&&e!==""?e:void 0}
6
+ "number",h=typeof e!="number";return {usage:{inputTokens:d,outputTokens:g,...s!=null?{cachedInputTokens:s}:{},...a!=null?{cacheWriteInputTokens:a}:{},...l!==void 0?{cacheWrite1hInputTokens:l}:{},...n||
7
+ h||o?{}:{reasoningTokens:0},...m||h?{complete:false}:{}},entradaAusente:m,salidaAusente:h}}function F(t,e){return e?(t??0)+e:t}function B(t){let e=t?.service_tier;return typeof e=="string"&&e!==""?e:void 0}
8
8
  function q(t,e){let n=Object.fromEntries(Object.entries(e??{}).filter(([,o])=>o!=null)),r=t?.cache_creation||e?.cache_creation?{...t?.cache_creation??{},...e?.cache_creation??{}}:void 0;return {...t??{},
9
9
  ...n,...r?{cache_creation:r}:{}}}function V(t){return t==="thinking"||t==="redacted_thinking"}function G(t){switch(t){case "end_turn":return "stop";case "max_tokens":return "length";case "tool_use":return "\
10
- tool_calls";case "refusal":return "content_filter";default:return t}}var ye=new Set([null,"cyber","general_harms"]);function H(t){if(t.stopReason!=="refusal")return false;let e=t.stopDetails;if(e===null||typeof e!=
11
- "object"||Array.isArray(e))return false;let n=e;if(n.type!=="refusal"||!("category"in n))return false;let r=n.category;return !(r!==null&&typeof r!="string"||!ye.has(r)||t.bloques!==0||t.outputTokens!==0||Array.
12
- isArray(t.iterations)&&t.iterations.length>1)}var ve={"api.anthropic.com":"anthropic","api.openai.com":"openai","generativelanguage.googleapis.com":"google"};function be(t){if(typeof t!="string")return null;try{let e=new URL(t);return e.protocol!==
13
- "https:"||e.port!==""?null:ve[e.hostname.toLowerCase()]??null}catch{return null}}function K(t){return be(t)!==null?"oficial":"no-oficial"}var Z=Symbol.for("@bivelio/savings-layer:provider-origin");var L=class{decoder;resto="";crPendiente=false;alPrincipio=true;datos="";evento="";ultimoId;push(e){let n=typeof e=="string"?e:(this.decoder??=new TextDecoder("utf-8")).decode(e,{stream:true});return this.procesar(
10
+ tool_calls";case "refusal":return "content_filter";default:return t}}var be=new Set([null,"cyber","general_harms"]);function H(t){if(t.stopReason!=="refusal")return false;let e=t.stopDetails;if(e===null||typeof e!=
11
+ "object"||Array.isArray(e))return false;let n=e;if(n.type!=="refusal"||!("category"in n))return false;let r=n.category;return !(r!==null&&typeof r!="string"||!be.has(r)||t.bloques!==0||t.outputTokens!==0||Array.
12
+ isArray(t.iterations)&&t.iterations.length>1)}var Re=["claude-opus-5-5","claude-sonnet-5-5","claude-fable-5-1","claude-mythos-5-1"],we=["claude-opus-4-7","claude-opus-4-8","claude-opus-5","claude-sonnet-5","claude-fable-5","claude-mythos-5"];function Se(t){return /claude-[a-z]+-\d[a-z0-9-]*/.exec(t.toLowerCase())?.[0]}function K(t,e){let n=Se(t);return n===void 0?false:e.some(r=>n===r||n.startsWith(`${r}-`))}function Z(t){return K(t,Re)}function Q(t){
13
+ return K(t,we)}var xe={"api.anthropic.com":"anthropic","api.openai.com":"openai","generativelanguage.googleapis.com":"google"};function Ae(t){if(typeof t!="string")return null;try{let e=new URL(t);return e.protocol!==
14
+ "https:"||e.port!==""?null:xe[e.hostname.toLowerCase()]??null}catch{return null}}function X(t){return Ae(t)!==null?"oficial":"no-oficial"}var Y=Symbol.for("@bivelio/savings-layer:provider-origin");var O=class{decoder;resto="";crPendiente=false;alPrincipio=true;datos="";evento="";ultimoId;push(e){let n=typeof e=="string"?e:(this.decoder??=new TextDecoder("utf-8")).decode(e,{stream:true});return this.procesar(
14
15
  n)}end(){let e=[];if(this.decoder){let n=this.decoder.decode();n!==""&&e.push(...this.procesar(n));}return this.resto!==""&&(this.linea(this.resto,e),this.resto=""),this.despachar(e),this.crPendiente=false,
15
16
  e}procesar(e){let n=[];if(e==="")return n;let r=e;if(this.alPrincipio&&(this.alPrincipio=false,r.charCodeAt(0)===65279&&(r=r.slice(1)),r===""))return n;let o=0;this.crPendiente&&(this.crPendiente=false,r.charCodeAt(
16
17
  0)===10&&(o=1));let s=o;for(;o<r.length;){let a=r.charCodeAt(o);if(a!==10&&a!==13){o++;continue}this.linea(this.resto+r.slice(s,o),n),this.resto="",a===13&&(o+1<r.length?r.charCodeAt(o+1)===10&&o++:this.
17
18
  crPendiente=true),o++,s=o;}return this.resto+=r.slice(s),n}linea(e,n){if(e===""){this.despachar(n);return}if(e.charCodeAt(0)===58)return;let r=e.indexOf(":"),o,s;switch(r===-1?(o=e,s=""):(o=e.slice(0,r),
18
19
  s=e.slice(r+1),s.charCodeAt(0)===32&&(s=s.slice(1))),o){case "data":this.datos+=s+`
19
20
  `;break;case "event":this.evento=s;break;case "id":s.includes("\0")||(this.ultimoId=s);break;}}despachar(e){if(this.datos===""){this.evento="";return}e.push({event:this.evento===""?"message":
20
- this.evento,data:this.datos.slice(0,-1),...this.ultimoId!==void 0?{id:this.ultimoId}:{}}),this.datos="",this.evento="";}};var Q=new Set;function X(t,e,n){t===true||Q.has(e)||(Q.add(e),console.warn(n));}var Re="[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;\
21
- nothing more was sent.",we="[bvsala] internal: the layer called the model outside a framework call; nothing was sent.";function U(t,e,n,r){return {renderizado:t,generar:e,...n?{transmitir:n}:{},invocada:false,
22
- completada:false,...r!==void 0?{origen:r}:{}}}function xe(t,e){if(t===e)return true;try{return stableStringify(t)===stableStringify(e)}catch{return false}}function ee(t,e){let n=t??[],r=e??[];return n.length===r.length&&n.every((o,s)=>xe(o,r[s]))}function Ae(t,e){return t.model===
23
- e.model&&ee(t.messages,e.messages)&&ee(t.tools,e.tools)}function te(t,e){let n=o=>{let s=e.getStore();if(!s)throw new Error(we);if(s.invocada)throw new Error(Se);if(!Ae(o,s.renderizado))throw new Error(
24
- Re);return s.invocada=true,s},r={id:`bivelio-adapter:${t}`,async generate(o,s){return n(o).generar(s?.signal)},async*generateStream(o,s){let a=n(o);if(a.transmitir){yield*a.transmitir(s?.signal);return}
25
- let i=await a.generar(s?.signal);i.text!==""&&(yield {type:"text",delta:i.text}),yield {type:"done",response:i};}};return Object.defineProperty(r,Z,{value:()=>e.getStore()?.origen}),r}function ne(){return new AsyncLocalStorage}var Ce=["licenseKey","licenseServerUrl","serviceAccountKey","licenseRefresh","licenseRevocation","licensePollIntervalSeconds","licenseFetch","metering","meteringUrl","meteringFetch","costModels","defa\
26
- ultCostModel","exactCache","exactCacheTtlMs","resolvers","exactTokenizer","silenceWarnings","failOpen"];function re(t,e){return e instanceof LicenseError||t.errorDelMarco&&t.errorDelMarco.error===e?false:t.invocada&&
27
- t.completada}var oe="[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 se(t,e){
28
- let n=ne(),r={};for(let a of Ce)e[a]!==void 0&&(r[a]=e[a]);let o=createSavingsLayer({...r,provider:te(t,n)}),s=(a,i)=>X(e.silenceWarnings,`${t}:${a}`,i);return {ejecutar(a,i){return n.run(i,()=>o.generate(a))},async generar(a,i){
29
- try{let u=await n.run(i,()=>o.generate(a));return i.invocada?{tipo:"vivo",result:u}:{tipo:"atajo",result:u}}catch(u){if(re(i,u))return s("sin-informe",oe),{tipo:"sin-informe"};throw u}},async transmitir(a,i,u){
30
- let g=n.run(i,()=>o.generateStream(a,u?{signal:u}:{})).result;i.resultado=g,g.catch(()=>{});let m;try{m=await Promise.race([i.abierta.then(()=>"abierta"),g.then(()=>"resuelta")]);}catch(_){if(re(i,_))return s(
31
- "sin-informe",oe),{tipo:"sin-informe"};throw _}if(m==="abierta")return {tipo:"abierto"};let h=await g;return i.invocada?{tipo:"entero",result:h}:{tipo:"atajo",result:h}},informe(a){let i=JSON.parse(JSON.
32
- stringify(a));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(){o.close();}}}function ae(){
21
+ this.evento,data:this.datos.slice(0,-1),...this.ultimoId!==void 0?{id:this.ultimoId}:{}}),this.datos="",this.evento="";}};var ee=new Set;function te(t,e,n){t===true||ee.has(e)||(ee.add(e),console.warn(n));}var De="[bvsala] internal: the layer changed a request this adapter must forward unchanged; nothing was sent.",Ce="[bvsala] internal: the layer asked for a second model call within one framework call;\
22
+ nothing more was sent.",Pe="[bvsala] internal: the layer called the model outside a framework call; nothing was sent.";function I(t,e,n,r){return {renderizado:t,generar:e,...n?{transmitir:n}:{},invocada:false,
23
+ completada:false,...r!==void 0?{origen:r}:{}}}function Oe(t,e){if(t===e)return true;try{return stableStringify(t)===stableStringify(e)}catch{return false}}function re(t,e){let n=t??[],r=e??[];return n.length===r.length&&n.every((o,s)=>Oe(o,r[s]))}function Te(t,e){return t.model===
24
+ e.model&&re(t.messages,e.messages)&&re(t.tools,e.tools)}function oe(t,e){let n=o=>{let s=e.getStore();if(!s)throw new Error(Pe);if(s.invocada)throw new Error(Ce);if(!Te(o,s.renderizado))throw new Error(
25
+ De);return s.invocada=true,s},r={id:`bivelio-adapter:${t}`,async generate(o,s){return n(o).generar(s?.signal)},async*generateStream(o,s){let a=n(o);if(a.transmitir){yield*a.transmitir(s?.signal);return}
26
+ let i=await a.generar(s?.signal);i.text!==""&&(yield {type:"text",delta:i.text}),yield {type:"done",response:i};}};return Object.defineProperty(r,Y,{value:()=>e.getStore()?.origen}),r}function se(){return new AsyncLocalStorage}var Le=["licenseKey","licenseServerUrl","serviceAccountKey","licenseRefresh","licenseRevocation","licensePollIntervalSeconds","licenseFetch","metering","meteringUrl","meteringFetch","costModels","defa\
27
+ ultCostModel","exactCache","exactCacheTtlMs","resolvers","exactTokenizer","silenceWarnings","failOpen"];function ae(t,e){return e instanceof LicenseError||t.errorDelMarco&&t.errorDelMarco.error===e?false:t.invocada&&
28
+ t.completada}var ie="[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 ce(t,e){
29
+ let n=se(),r={};for(let a of Le)e[a]!==void 0&&(r[a]=e[a]);let o=createSavingsLayer({...r,provider:oe(t,n)}),s=(a,i)=>te(e.silenceWarnings,`${t}:${a}`,i);return {ejecutar(a,i){return n.run(i,()=>o.generate(a))},async generar(a,i){
30
+ try{let l=await n.run(i,()=>o.generate(a));return i.invocada?{tipo:"vivo",result:l}:{tipo:"atajo",result:l}}catch(l){if(ae(i,l))return s("sin-informe",ie),{tipo:"sin-informe"};throw l}},async transmitir(a,i,l){
31
+ let g=n.run(i,()=>o.generateStream(a,l?{signal:l}:{})).result;i.resultado=g,g.catch(()=>{});let m;try{m=await Promise.race([i.abierta.then(()=>"abierta"),g.then(()=>"resuelta")]);}catch(b){if(ae(i,b))return s(
32
+ "sin-informe",ie),{tipo:"sin-informe"};throw b}if(m==="abierta")return {tipo:"abierto"};let h=await g;return i.invocada?{tipo:"entero",result:h}:{tipo:"atajo",result:h}},informe(a){let i=JSON.parse(JSON.
33
+ stringify(a));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(){o.close();}}}function le(){
33
34
  let t;return {abierta:new Promise(n=>{t=n;}),abrir:t}}var C=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.
34
35
  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||
35
36
  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](){
36
37
  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(
37
- (e,n)=>{this.esperando={resolver:e,rechazar:n};}),return:()=>(this.terminada=true,this.pendientes.length=0,Promise.resolve({value:void 0,done:true}))}}};var Le={router:false,compression:false,elision:false,serialization:false,toolDiscovery:false,modelCascade:"off",outputCodebook:false,deferrable:false,semanticCache:false,verification:false};
38
- function Me(t,e,n={}){let r=o=>t?.[o]!==false&&e?.[o]!==false;return {...Le,exactCache:r("exactCache")&&n.sinReutilizar!==true,singleflight:r("singleflight")&&n.sinReutilizar!==true,deterministicResolvers:r("det\
39
- erministicResolvers")&&n.sinResolvers!==true}}function Oe(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 ce(t,e){
40
- let n=e.delProveedor!==true&&Oe(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}:{},
38
+ (e,n)=>{this.esperando={resolver:e,rechazar:n};}),return:()=>(this.terminada=true,this.pendientes.length=0,Promise.resolve({value:void 0,done:true}))}}};var qe={router:false,compression:false,elision:false,serialization:false,toolDiscovery:false,modelCascade:"off",outputCodebook:false,deferrable:false,semanticCache:false,verification:false};
39
+ function Ie(t,e,n={}){let r=o=>t?.[o]!==false&&e?.[o]!==false;return {...qe,exactCache:r("exactCache")&&n.sinReutilizar!==true,singleflight:r("singleflight")&&n.sinReutilizar!==true,deterministicResolvers:r("det\
40
+ erministicResolvers")&&n.sinResolvers!==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 de(t,e){
41
+ let n=e.delProveedor!==true&&Ue(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}:{},
41
42
  ...typeof e.descripcion=="string"?{description:e.descripcion}:{}}}function P(t,e,n){if(t===null)return null;switch(typeof t){case "string":case "boolean":return t;case "number":return Number.isFinite(t)?
42
43
  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)
43
44
  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};
44
45
  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(s=>{let a=P(s,e,n);return a===void 0?null:
45
46
  a});if(r instanceof Map)return {$map:[...r.entries()].map(s=>P(s,e,n))};if(r instanceof Set)return {$set:[...r.values()].map(s=>P(s,e,n))};let o={};for(let s of Object.keys(r).sort()){let a=P(r[s],e,n);
46
- a!==void 0&&(o[s]=a);}return o}finally{n.delete(r);}}async function ie(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(
47
- 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 Te(t){try{let e=[],n=JSON.stringify(P(t,e,new WeakSet))??"null",r=await Promise.
48
- all(e.map(ie)),o=new TextEncoder().encode(`${n}|${r.join(",")}`);return await ie(o)}catch{return null}}async function ue(t,e){let n=await Te(e.proyeccion),r=`${e.context?.authorizationScope??"default"}\
47
+ a!==void 0&&(o[s]=a);}return o}finally{n.delete(r);}}async function ue(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(
48
+ 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 ze(t){try{let e=[],n=JSON.stringify(P(t,e,new WeakSet))??"null",r=await Promise.
49
+ all(e.map(ue)),o=new TextEncoder().encode(`${n}|${r.join(",")}`);return await ue(o)}catch{return null}}async function pe(t,e){let n=await ze(e.proyeccion),r=`${e.context?.authorizationScope??"default"}\
49
50
  |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"?
50
- {seed:e.seed}:{},context:{...e.context??{},authorizationScope:r},savings:Me(t.savings,e.savings,{...e.restricciones,...n===null?{sinReutilizar:true}:{}})}}function le(t,e){if(!(!t&&!e))return {...t??{},...e??
51
- {}}}function de(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 I="[bvsala] could not read the request body; nothing was sent.";function p(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function Ee(t){if((t.method??"GET").toUpperCase()!=="POST")return false;
52
- try{return new URL(t.url).pathname.replace(/\/+$/,"").endsWith("/v1/messages")}catch{return false}}function A(t){return typeof t=="string"?[{type:"text",text:t}]:Array.isArray(t)?t.filter(p):[]}function M(t){
51
+ {seed:e.seed}:{},context:{...e.context??{},authorizationScope:r},savings:Ie(t.savings,e.savings,{...e.restricciones,...n===null?{sinReutilizar:true}:{}})}}function fe(t,e){if(!(!t&&!e))return {...t??{},...e??
52
+ {}}}function ge(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 U="[bvsala] could not read the request body; nothing was sent.";function p(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function Ne(t){if((t.method??"GET").toUpperCase()!=="POST")return false;
53
+ try{return new URL(t.url).pathname.replace(/\/+$/,"").endsWith("/v1/messages")}catch{return false}}function A(t){return typeof t=="string"?[{type:"text",text:t}]:Array.isArray(t)?t.filter(p):[]}function T(t){
53
54
  return t.filter(e=>e.type==="text"&&typeof e.text=="string").map(e=>e.text).join(`
54
- `)}function me(t){if(typeof t=="string")return t;try{return JSON.stringify(t??{})}catch{return "{}"}}function je(t){let e=[],n=t.system;(typeof n=="string"?n!=="":Array.isArray(n))&&e.push({role:"syste\
55
- m",content:typeof n=="string"?n:M(A(n))});for(let r of Array.isArray(t.messages)?t.messages:[]){if(!p(r))continue;let o=A(r.content);if(r.role==="assistant"){let a=o.filter(i=>i.type==="tool_use").map(
56
- i=>({...typeof i.id=="string"?{id:i.id}:{},name:String(i.name??""),arguments:me(i.input)}));e.push({role:"assistant",content:M(o),...a.length>0?{toolCalls:a}:{}});continue}for(let a of o)a.type==="too\
57
- l_result"&&e.push({role:"tool",content:typeof a.content=="string"?a.content:M(A(a.content)),...typeof a.tool_use_id=="string"?{toolCallId:a.tool_use_id}:{}});let s=M(o);(s!==""||!o.some(a=>a.type==="t\
58
- ool_result"))&&e.push({role:"user",content:s});}return e}function pe(t){let e={};for(let[n,r]of Object.entries(t))n==="id"||n==="tool_use_id"||n==="text"&&t.type==="text"||(e[n]=r);return e}function qe(t,e){
59
- let n={};for(let[r,o]of Object.entries(t))r==="stream"||r==="metadata"||r==="messages"||r==="system"||(n[r]=o);return n.system=typeof t.system=="string"?"$text":A(t.system).map(pe),n.messages=(Array.isArray(
60
- t.messages)?t.messages:[]).filter(p).map(r=>({role:r.role,content:A(r.content).map(pe)})),e&&(n["anthropic-beta"]=e),n}function Ue(t){let e=t.tool_choice;return p(e)&&(e.type==="any"||e.type==="tool")||
61
- p(t.output_config)&&t.output_config.format!==void 0?true:t.output_format!==void 0}var O=class{id;texto="";razono=false;reproducible=true;parada;detallesDeParada;bloquesVistos=0;usoInicio;usoDelta;vioDelta=false;vioStop=false;error;herramientas=new Map;toolCallsJson=[];bloque(e){
55
+ `)}function ve(t){if(typeof t=="string")return t;try{return JSON.stringify(t??{})}catch{return "{}"}}function Je(t){let e=[],n=t.system;(typeof n=="string"?n!=="":Array.isArray(n))&&e.push({role:"syste\
56
+ m",content:typeof n=="string"?n:T(A(n))});for(let r of Array.isArray(t.messages)?t.messages:[]){if(!p(r))continue;let o=A(r.content);if(r.role==="assistant"){let a=o.filter(i=>i.type==="tool_use").map(
57
+ i=>({...typeof i.id=="string"?{id:i.id}:{},name:String(i.name??""),arguments:ve(i.input)}));e.push({role:"assistant",content:T(o),...a.length>0?{toolCalls:a}:{}});continue}for(let a of o)a.type==="too\
58
+ l_result"&&e.push({role:"tool",content:typeof a.content=="string"?a.content:T(A(a.content)),...typeof a.tool_use_id=="string"?{toolCallId:a.tool_use_id}:{}});let s=T(o);(s!==""||!o.some(a=>a.type==="t\
59
+ ool_result"))&&e.push({role:"user",content:s});}return e}function me(t){let e={};for(let[n,r]of Object.entries(t))n==="id"||n==="tool_use_id"||n==="text"&&t.type==="text"||(e[n]=r);return e}function Fe(t,e){
60
+ let n={};for(let[r,o]of Object.entries(t))r==="stream"||r==="metadata"||r==="messages"||r==="system"||(n[r]=o);return n.system=typeof t.system=="string"?"$text":A(t.system).map(me),n.messages=(Array.isArray(
61
+ t.messages)?t.messages:[]).filter(p).map(r=>({role:r.role,content:A(r.content).map(me)})),e&&(n["anthropic-beta"]=e),n}function We(t){let e=t.tool_choice;return p(e)&&(e.type==="any"||e.type==="tool")||
62
+ p(t.output_config)&&t.output_config.format!==void 0?true:t.output_format!==void 0}function Be(t){let e=typeof t.model=="string"?t.model:"";if(e==="")return [];let n=[],r=t.tool_choice;p(r)&&(r.type==="an\
63
+ y"||r.type==="tool")&&Z(e)&&n.push({clave:`tool-choice-forzado:${e}`,mensaje:`[bvsala] Model "${e}" rejects a forced \`tool_choice\` (\`any\` or \`tool\`) with a 400, with or without thinking. This adapter \
64
+ forwards your request unchanged, so the API will reject it: use \`tool_choice: {type: "auto"}\` with \`strict: true\` tools, or \`output_config.format\` for a fixed JSON shape. See https://platform.claude.c\
65
+ om/docs/en/agents-and-tools/tool-use/define-tools#forcing-tool-use`});let o=["temperature","top_p","top_k"].filter(s=>typeof t[s]=="number"&&!(s==="temperature"&&t[s]===1));return o.length>0&&Q(e)&&n.
66
+ push({clave:`muestreo:${e}`,mensaje:`[bvsala] Model "${e}" rejects a non-default ${o.map(s=>`\`${s}\``).join(", ")} with a 400. This adapter forwards your request unchanged, so the API will reject it:\
67
+ drop the parameter for this model. See https://platform.claude.com/docs/en/models/sonnet-5-5/overview`}),n}var M=class{id;texto="";razono=false;reproducible=true;parada;detallesDeParada;bloquesVistos=0;usoInicio;usoDelta;vioDelta=false;vioStop=false;error;herramientas=new Map;toolCallsJson=[];bloque(e){
62
68
  this.bloquesVistos+=1,V(e.type)?(this.razono=true,this.reproducible=false):e.type==="text"?Array.isArray(e.citations)&&e.citations.length>0&&(this.reproducible=false):e.type!=="tool_use"&&(this.reproducible=false);}json(e){
63
69
  this.id=typeof e.id=="string"?e.id:void 0;for(let n of A(e.content))this.bloque(n),n.type==="text"&&typeof n.text=="string"&&(this.texto+=n.text),n.type==="tool_use"&&this.toolCallsJson.push({...typeof n.
64
- id=="string"?{id:n.id}:{},name:String(n.name??""),arguments:me(n.input)});this.parada=typeof e.stop_reason=="string"?e.stop_reason:void 0,this.detallesDeParada=e.stop_details,this.usoInicio=p(e.usage)?
70
+ id=="string"?{id:n.id}:{},name:String(n.name??""),arguments:ve(n.input)});this.parada=typeof e.stop_reason=="string"?e.stop_reason:void 0,this.detallesDeParada=e.stop_details,this.usoInicio=p(e.usage)?
65
71
  e.usage:void 0,this.usoDelta=this.usoInicio,this.vioDelta=true,this.vioStop=true;}evento(e){let n;try{n=JSON.parse(e.data);}catch{return}if(!p(n))return;switch(e.event!=="message"?e.event:String(n.type??e.event)){case "\
66
72
  message_start":{let o=p(n.message)?n.message:{};typeof o.id=="string"&&(this.id=o.id),p(o.usage)&&(this.usoInicio=o.usage);return}case "content_block_start":{let o=p(n.content_block)?n.content_block:{};
67
73
  this.bloque(o),o.type==="tool_use"&&typeof n.index=="number"&&this.herramientas.set(n.index,{...typeof o.id=="string"?{id:o.id}:{},name:String(o.name??""),json:""});return}case "content_block_delta":{let o=p(
@@ -69,36 +75,36 @@ n.delta)?n.delta:{};if(o.type==="text_delta"&&typeof o.text=="string")return thi
69
75
  "number"){let s=this.herramientas.get(n.index);s&&(s.json+=o.partial_json);}o.type==="citations_delta"&&(this.reproducible=false);return}case "message_delta":{this.vioDelta=true;let o=p(n.delta)?n.delta:{};typeof o.
70
76
  stop_reason=="string"&&(this.parada=o.stop_reason),"stop_details"in o&&(this.detallesDeParada=o.stop_details),p(n.usage)&&(this.usoDelta=q(this.usoDelta,n.usage));return}case "message_stop":this.vioStop=
71
77
  true;return;case "error":{let o=p(n.error)?n.error:{};this.error=`${String(o.type??"error")}: ${String(o.message??"")}`;return}default:return}}get toolCalls(){return this.toolCallsJson.length>0?this.toolCallsJson:
72
- [...this.herramientas.entries()].sort((e,n)=>e[0]-n[0]).map(([,e])=>({...e.id?{id:e.id}:{},name:e.name,arguments:Ie(e.json)})).filter(e=>e.name!=="")}respuesta(){let e=q(this.usoInicio,this.usoDelta),
73
- n=this.vioDelta?B(e,this.usoDelta?.output_tokens,this.razono).usage:{inputTokens:0,outputTokens:0,complete:false},r=e.iterations;Array.isArray(r)&&r.length>1&&(n.complete=false);let o=this.toolCalls,s=F(e);
78
+ [...this.herramientas.entries()].sort((e,n)=>e[0]-n[0]).map(([,e])=>({...e.id?{id:e.id}:{},name:e.name,arguments:Ve(e.json)})).filter(e=>e.name!=="")}respuesta(){let e=q(this.usoInicio,this.usoDelta),
79
+ n=this.vioDelta?W(e,this.usoDelta?.output_tokens,this.razono).usage:{inputTokens:0,outputTokens:0,complete:false},r=e.iterations;Array.isArray(r)&&r.length>1&&(n.complete=false);let o=this.toolCalls,s=B(e);
74
80
  return {text:this.texto,...o.length>0?{toolCalls:o}:{},...this.parada?{finishReason:G(this.parada)}:{},...this.vioDelta&&H({stopReason:this.parada,stopDetails:this.detallesDeParada,bloques:this.bloquesVistos,
75
- outputTokens:this.usoDelta?.output_tokens,iterations:r})?{unbilledRefusal:true}:{},...s?{servedServiceTier:s}:{},usage:n,...this.reproducible&&this.parada==="end_turn"?{}:{replayable:false}}}};function Ie(t){
76
- try{return JSON.stringify(JSON.parse(t===""?"{}":t))}catch{return t}}function ze(t,e){let n=[];return t.text!==""&&n.push({type:"text",text:t.text}),(t.toolCalls??[]).forEach((r,o)=>{let s={};try{s=JSON.
81
+ outputTokens:this.usoDelta?.output_tokens,iterations:r})?{unbilledRefusal:true}:{},...s?{servedServiceTier:s}:{},usage:n,...this.reproducible&&this.parada==="end_turn"?{}:{replayable:false}}}};function Ve(t){
82
+ try{return JSON.stringify(JSON.parse(t===""?"{}":t))}catch{return t}}function Ge(t,e){let n=[];return t.text!==""&&n.push({type:"text",text:t.text}),(t.toolCalls??[]).forEach((r,o)=>{let s={};try{s=JSON.
77
83
  parse(r.arguments||"{}");}catch{s={};}n.push({type:"tool_use",id:r.id??`toolu_bvsala_${t.requestId}_${o}`,name:r.name,input:s});}),{id:`msg_bvsala_${t.requestId}`,type:"message",role:"assistant",model:e,
78
- content:n,stop_reason:(t.toolCalls?.length??0)>0?"tool_use":"end_turn",stop_sequence:null,usage:{input_tokens:0,output_tokens:0}}}function fe(t,e,n){let r=ze(t,e),o={"request-id":`bvsala_${t.requestId}`};
79
- if(!n)return new Response(JSON.stringify(r),{status:200,headers:{...o,"content-type":"application/json"}});let s=(i,u)=>`event: ${i}
80
- data: ${JSON.stringify(u)}
84
+ content:n,stop_reason:(t.toolCalls?.length??0)>0?"tool_use":"end_turn",stop_sequence:null,usage:{input_tokens:0,output_tokens:0}}}function he(t,e,n){let r=Ge(t,e),o={"request-id":`bvsala_${t.requestId}`};
85
+ if(!n)return new Response(JSON.stringify(r),{status:200,headers:{...o,"content-type":"application/json"}});let s=(i,l)=>`event: ${i}
86
+ data: ${JSON.stringify(l)}
81
87
 
82
- `,a=s("message_start",{type:"message_start",message:{...r,content:[],stop_reason:null,stop_sequence:null}});return r.content.forEach((i,u)=>{i.type==="text"?(a+=s("content_block_start",{type:"content_\
83
- block_start",index:u,content_block:{type:"text",text:""}}),a+=s("content_block_delta",{type:"content_block_delta",index:u,delta:{type:"text_delta",text:i.text}})):(a+=s("content_block_start",{type:"co\
84
- ntent_block_start",index:u,content_block:{type:"tool_use",id:i.id,name:i.name,input:{}}}),a+=s("content_block_delta",{type:"content_block_delta",index:u,delta:{type:"input_json_delta",partial_json:JSON.
85
- stringify(i.input)}})),a+=s("content_block_stop",{type:"content_block_stop",index:u});}),a+=s("message_delta",{type:"message_delta",delta:{stop_reason:r.stop_reason,stop_sequence:null},usage:{output_tokens:0}}),
86
- a+=s("message_stop",{type:"message_stop"}),new Response(a,{status:200,headers:{...o,"content-type":"text/event-stream"}})}var T=class extends Error{constructor(n){super(`[bvsala] provider responded ${n.
87
- status}`);this.respuesta=n;}respuesta};function lt(t){let e=se("anthropic-sdk",t),n=Math.max(1,Math.floor(t.reportCacheSize??1e3)),r=new Map,o=(a,i)=>{if(a)for(r.delete(a),r.set(a,i);r.size>n;)r.delete(
88
- r.keys().next().value);};return {middleware:async(a,i,u)=>{if(!Ee(a))return i(a);if(typeof a.body!="string")throw new Error(I);let d;try{let c=JSON.parse(a.body);if(!p(c))throw new Error(I);d=c;}catch{throw new Error(
89
- I)}let g=u.options,m=de(g?.bivelio),h=t.context?.({body:d,requestOptions:g}),_=(Array.isArray(d.tools)?d.tools:[]).filter(p).map(c=>ce(t,{nombre:String(c.name??""),descripcion:typeof c.description=="s\
90
- tring"?c.description:void 0,parametros:c.input_schema,delProveedor:c.input_schema===void 0&&typeof c.type=="string"&&c.type!=="custom"})),l=await ue(t,{model:`anthropic/${String(d.model??"")}`,messages:je(
91
- d),tools:_,temperature:typeof d.temperature=="number"?d.temperature:void 0,context:le(h,m.context),savings:m.savings,proyeccion:qe(d,a.headers.get("anthropic-beta")),restricciones:{sinResolvers:Ue(d)}}),
92
- v={model:l.model,messages:l.messages,...l.tools?{tools:l.tools}:{}},b=K(a.url),R=async c=>{let f;try{f=await i(a);}catch(y){throw c.errorDelMarco={error:y},y}if(!f.ok){let y=new T(f);throw c.errorDelMarco=
93
- {error:y},y}return c.completada=true,f},z=c=>{if(c instanceof T)return c.respuesta;throw c};if(d.stream!==true){let c,f,y=U(v,async()=>{c=await R(y);let D=new O;return D.json(await c.clone().json()),f=D.id,
94
- D.respuesta()},void 0,b),w;try{w=await e.generar(l,y);}catch(D){return z(D)}if(w.tipo==="sin-informe")return c;let N=e.informe(w.result.report);return w.tipo==="atajo"?(o(`msg_bvsala_${w.result.requestId}`,
95
- N),fe(w.result,d.model,false)):(o(f,N),c)}let{abierta:he,abrir:$}=ae(),E,j,k=Object.assign(U(v,async()=>{let c=await R(k),f=new C;j=ge(c,f,e,k,o),$();for await(let y of f)if(y.type==="done")return y.response;
96
- throw new Error("[bvsala] the model stream ended before completion; nothing was measured.")},()=>{let c=new C;return R(k).then(f=>{E=ge(f,c,e,k,o),$();},f=>c.fail(f)),c},b),{abierta:he}),S;try{S=await e.
97
- transmitir(l,k,a.signal??void 0);}catch(c){return z(c)}if(S.tipo==="abierto")return E??j;if(S.tipo==="atajo"){let c=e.informe(S.result.report);return o(`msg_bvsala_${S.result.requestId}`,c),fe(S.result,
98
- d.model,true)}return E??j},reportFor(a){let i=typeof a=="string"?a:a?.id;return typeof i=="string"?r.get(i):void 0},close(){e.close();}}}function ge(t,e,n,r,o){let s=new O,a,i=async()=>{try{let l=await r.
99
- resultado;o(s.id,n.informe(l.report));}catch{}},u=()=>{e.cerrada||(s.error?e.fail(new Error(`[bvsala] provider stream error: ${s.error}`)):s.vioDelta||s.vioStop?(e.push({type:"done",response:s.respuesta()}),
100
- e.end(),a=i()):e.fail(new Error("[bvsala] the model stream ended before completion; nothing was measured.")));};if((t.headers.get("content-type")??"").includes("application/json"))return t.clone().json().
101
- then(l=>{s.json(p(l)?l:{}),s.texto!==""&&e.push({type:"text",delta:s.texto}),u();},l=>e.fail(l)),t;let d=t.body;if(!d)return e.fail(new Error("[bvsala] the model stream had no body; nothing was measure\
102
- d.")),t;let g=d.getReader(),m=new L,h=l=>{for(let v of l){let b=s.evento(v);b!==void 0&&e.push({type:"text",delta:b}),(s.vioStop||s.error)&&u();}},_=new ReadableStream({async pull(l){let v;try{v=await g.
103
- read();}catch(R){e.fail(R),l.error(R);return}if(v.done){h(m.end()),u(),await a,l.close();return}let b=v.value;l.enqueue(b),h(m.push(b));},cancel(l){return e.fail(new Error("[bvsala] the stream was cance\
104
- lled by its reader; nothing was measured.")),g.cancel(l)}});return new Response(_,{status:t.status,statusText:t.statusText,headers:t.headers})}export{lt as anthropicSavings};
88
+ `,a=s("message_start",{type:"message_start",message:{...r,content:[],stop_reason:null,stop_sequence:null}});return r.content.forEach((i,l)=>{i.type==="text"?(a+=s("content_block_start",{type:"content_\
89
+ block_start",index:l,content_block:{type:"text",text:""}}),a+=s("content_block_delta",{type:"content_block_delta",index:l,delta:{type:"text_delta",text:i.text}})):(a+=s("content_block_start",{type:"co\
90
+ ntent_block_start",index:l,content_block:{type:"tool_use",id:i.id,name:i.name,input:{}}}),a+=s("content_block_delta",{type:"content_block_delta",index:l,delta:{type:"input_json_delta",partial_json:JSON.
91
+ stringify(i.input)}})),a+=s("content_block_stop",{type:"content_block_stop",index:l});}),a+=s("message_delta",{type:"message_delta",delta:{stop_reason:r.stop_reason,stop_sequence:null},usage:{output_tokens:0}}),
92
+ a+=s("message_stop",{type:"message_stop"}),new Response(a,{status:200,headers:{...o,"content-type":"text/event-stream"}})}var E=class extends Error{constructor(n){super(`[bvsala] provider responded ${n.
93
+ status}`);this.respuesta=n;}respuesta};function bt(t){let e=ce("anthropic-sdk",t),n=Math.max(1,Math.floor(t.reportCacheSize??1e3)),r=new Map,o=(a,i)=>{if(a)for(r.delete(a),r.set(a,i);r.size>n;)r.delete(
94
+ r.keys().next().value);};return {middleware:async(a,i,l)=>{if(!Ne(a))return i(a);if(typeof a.body!="string")throw new Error(U);let d;try{let c=JSON.parse(a.body);if(!p(c))throw new Error(U);d=c;}catch{throw new Error(
95
+ U)}for(let c of Be(d))e.avisar(c.clave,c.mensaje);let g=l.options,m=ge(g?.bivelio),h=t.context?.({body:d,requestOptions:g}),b=(Array.isArray(d.tools)?d.tools:[]).filter(p).map(c=>de(t,{nombre:String(c.
96
+ name??""),descripcion:typeof c.description=="string"?c.description:void 0,parametros:c.input_schema,delProveedor:c.input_schema===void 0&&typeof c.type=="string"&&c.type!=="custom"})),u=await pe(t,{model:`\
97
+ anthropic/${String(d.model??"")}`,messages:Je(d),tools:b,temperature:typeof d.temperature=="number"?d.temperature:void 0,context:fe(h,m.context),savings:m.savings,proyeccion:Fe(d,a.headers.get("anthro\
98
+ pic-beta")),restricciones:{sinResolvers:We(d)}}),v={model:u.model,messages:u.messages,...u.tools?{tools:u.tools}:{}},_=X(a.url),R=async c=>{let f;try{f=await i(a);}catch(y){throw c.errorDelMarco={error:y},
99
+ y}if(!f.ok){let y=new E(f);throw c.errorDelMarco={error:y},y}return c.completada=true,f},z=c=>{if(c instanceof E)return c.respuesta;throw c};if(d.stream!==true){let c,f,y=I(v,async()=>{c=await R(y);let D=new M;
100
+ return D.json(await c.clone().json()),f=D.id,D.respuesta()},void 0,_),S;try{S=await e.generar(u,y);}catch(D){return z(D)}if(S.tipo==="sin-informe")return c;let N=e.informe(S.result.report);return S.tipo===
101
+ "atajo"?(o(`msg_bvsala_${S.result.requestId}`,N),he(S.result,d.model,false)):(o(f,N),c)}let{abierta:_e,abrir:$}=le(),L,j,k=Object.assign(I(v,async()=>{let c=await R(k),f=new C;j=ye(c,f,e,k,o),$();for await(let y of f)
102
+ if(y.type==="done")return y.response;throw new Error("[bvsala] the model stream ended before completion; nothing was measured.")},()=>{let c=new C;return R(k).then(f=>{L=ye(f,c,e,k,o),$();},f=>c.fail(f)),
103
+ c},_),{abierta:_e}),w;try{w=await e.transmitir(u,k,a.signal??void 0);}catch(c){return z(c)}if(w.tipo==="abierto")return L??j;if(w.tipo==="atajo"){let c=e.informe(w.result.report);return o(`msg_bvsala_${w.
104
+ result.requestId}`,c),he(w.result,d.model,true)}return L??j},reportFor(a){let i=typeof a=="string"?a:a?.id;return typeof i=="string"?r.get(i):void 0},close(){e.close();}}}function ye(t,e,n,r,o){let s=new M,
105
+ a,i=async()=>{try{let u=await r.resultado;o(s.id,n.informe(u.report));}catch{}},l=()=>{e.cerrada||(s.error?e.fail(new Error(`[bvsala] provider stream error: ${s.error}`)):s.vioDelta||s.vioStop?(e.push(
106
+ {type:"done",response:s.respuesta()}),e.end(),a=i()):e.fail(new Error("[bvsala] the model stream ended before completion; nothing was measured.")));};if((t.headers.get("content-type")??"").includes("ap\
107
+ plication/json"))return t.clone().json().then(u=>{s.json(p(u)?u:{}),s.texto!==""&&e.push({type:"text",delta:s.texto}),l();},u=>e.fail(u)),t;let d=t.body;if(!d)return e.fail(new Error("[bvsala] the mode\
108
+ l stream had no body; nothing was measured.")),t;let g=d.getReader(),m=new O,h=u=>{for(let v of u){let _=s.evento(v);_!==void 0&&e.push({type:"text",delta:_}),(s.vioStop||s.error)&&l();}},b=new ReadableStream(
109
+ {async pull(u){let v;try{v=await g.read();}catch(R){e.fail(R),u.error(R);return}if(v.done){h(m.end()),l(),await a,u.close();return}let _=v.value;u.enqueue(_),h(m.push(_));},cancel(u){return e.fail(new Error(
110
+ "[bvsala] the stream was cancelled by its reader; nothing was measured.")),g.cancel(u)}});return new Response(b,{status:t.status,statusText:t.statusText,headers:t.headers})}export{bt as anthropicSavings};