@bivelio/savings-layer 0.4.14 → 0.4.16

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.
@@ -1,32 +1,39 @@
1
1
  #!/usr/bin/env node
2
- import {spawn}from'child_process';import {existsSync,readFileSync,mkdirSync,writeFileSync}from'fs';import {homedir}from'os';import {join,dirname,delimiter}from'path';import {fileURLToPath}from'url';import {createServer}from'http';import {randomUUID,createHash}from'crypto';import*as A from'zlib';var $e=new Set;function E(e,t){$e.has(e)||($e.add(e),console.warn(t));}var z=class{options;now;flushIntervalMs;maxBatch;maxBuffer;buffer=[];seatId;ci;timer;inflight=null;fallosSeguidos=0;constructor(t){this.options=t,this.now=t.now??(()=>Date.now()),this.flushIntervalMs=
2
+ import {spawn}from'child_process';import {existsSync,readFileSync,mkdirSync,writeFileSync}from'fs';import {homedir}from'os';import {join,dirname,delimiter}from'path';import {fileURLToPath}from'url';import {createServer}from'http';import {randomUUID,createHash}from'crypto';import*as P from'zlib';import {connect}from'net';var re="context-management-2025-06-27";function Xe(){return {edits:[{type:"clear_tool_uses_20250919",trigger:{type:"input_tokens",value:5e4},keep:{type:"tool_uses",value:8},clear_at_least:{type:"input_tokens",value:5e3}}]}}function et(e,t){if(t!==void 0&&t!==""&&t!=="identity")return null;try{let n=JSON.parse(e.toString("utf8"));return n===null||typeof n!="object"||Array.isArray(n)||typeof n.model!="string"||!Array.isArray(
3
+ n.messages)?null:(n.context_management=Yt(n.context_management),Buffer.from(JSON.stringify(n),"utf8"))}catch{return null}}var Gt="clear_tool_uses_20250919",Ze="clear_thinking_20251015";function Yt(e){
4
+ let t=Xe().edits[0],n=e!==null&&typeof e=="object"&&!Array.isArray(e)?{...e}:{},o=(Array.isArray(n.edits)?n.edits:[]).filter(i=>i!==null&&typeof i=="object"&&!Array.isArray(i)&&i.type!==Gt),r=o.filter(
5
+ i=>i.type===Ze),s=o.filter(i=>i.type!==Ze);return {...n,edits:[...r,...s,t]}}function tt(e,t){let n=" (se enciende solo si la licencia de la org trae context_elision; fail-closed)";return e==="0"?{linea:"\
6
+ elisi\xF3n S4a: APAGADA (BVSALA_GATEWAY_ELISION=0) \u2014 brazo CONTROL",aviso:false}:t?e==="1"?{linea:"elisi\xF3n S4a: ARMADA (BVSALA_GATEWAY_ELISION=1) \u2014 brazo PALANCA"+n,aviso:false}:{linea:"elisi\xF3n\
7
+ S4a: ARMADA por defecto (sin bandera; =0 la apaga) \u2014 brazo PALANCA"+n,aviso:false}:{linea:"elisi\xF3n S4a: NO SE ARMA \u2014 falta BIVELIO_SERVICE_KEY (sin clave no hay org que consultar); este proceso es \
8
+ brazo CONTROL"+(e==="1"?" AUNQUE la bandera diga =1. Abre un terminal nuevo o exporta la clave y relanza":""),aviso:e==="1"}}function nt(e){return e===void 0||e.trim()===""?re:e.split(",").map(n=>n.trim()).
9
+ filter(n=>n.length>0).includes(re)?e:`${e},${re}`}var ot=new Set;function A(e,t){ot.has(e)||(ot.add(e),console.warn(t));}var U=class{options;now;flushIntervalMs;maxBatch;maxBuffer;buffer=[];seatId;ci;timer;inflight=null;fallosSeguidos=0;constructor(t){this.options=t,this.now=t.now??(()=>Date.now()),this.flushIntervalMs=
3
10
  t.flushIntervalMs??15e3,this.maxBatch=t.maxBatch??50,this.maxBuffer=t.maxBuffer??1e3,this.ci=t.ci??false;}setSeat(t,n){t&&(this.seatId=t),this.ci=n;}record(t){this.buffer.push({report:t,at:this.now()}),this.
4
11
  buffer.length>this.maxBuffer&&this.buffer.splice(0,this.buffer.length-this.maxBuffer),this.buffer.length>=this.maxBatch&&this.flush();}start(){this.timer||(this.timer=setInterval(()=>{this.flush();},this.
5
12
  flushIntervalMs),this.timer.unref?.());}stop(){this.timer&&(clearInterval(this.timer),this.timer=void 0),this.flush();}async stopAndDrain(t){this.timer&&(clearInterval(this.timer),this.timer=void 0);let n=t??
6
- Math.ceil(this.maxBuffer/this.maxBatch)+4,r=0;for(let o=0;o<n&&this.buffer.length>0;o++){let s=this.buffer.length;if(await this.flush(),r=this.buffer.length>=s?r+1:0,r>=2)break}}async flush(){if(this.
13
+ Math.ceil(this.maxBuffer/this.maxBatch)+4,o=0;for(let r=0;r<n&&this.buffer.length>0;r++){let s=this.buffer.length;if(await this.flush(),o=this.buffer.length>=s?o+1:0,o>=2)break}}async flush(){if(this.
7
14
  inflight)return this.inflight;if(this.buffer.length!==0){this.inflight=this.hacerFlush();try{await this.inflight;}finally{this.inflight=null;}}}async hacerFlush(){let t=this.options.fetchImpl??globalThis.
8
- fetch;if(!t)return;let n=this.buffer.splice(0,this.maxBatch);try{let r=n.map(s=>this.toWire(s)),o=await t(this.options.url,{method:"POST",headers:{"content-type":"application/json",authorization:`Bear\
9
- er ${this.options.serviceAccountKey}`},body:JSON.stringify(r)});o.ok?this.fallosSeguidos=0:o.status>=500?(this.fallosSeguidos++,this.requeue(n),this.avisarDeFallo(`el servidor respondi\xF3 ${o.status}`)):
10
- o.status===401||o.status===403?(E(`metering-auth-${o.status}`,`[bv-sala] el env\xEDo de uso est\xE1 siendo rechazado con HTTP ${o.status} en ${this.options.url}. Revisa 'serviceAccountKey' (\xBFrotada? \xBF\
11
- revocada? \xBFde otra organizaci\xF3n?). Mientras no funcione NO se reporta uso: el panel dir\xE1 que no ve tr\xE1fico y los asientos facturables saldr\xE1n a cero.`),this.options.onAuthError?.(o.status)):
12
- (this.fallosSeguidos++,this.avisarDeFallo(o.status===404||o.status===405?`HTTP ${o.status}: la URL de env\xEDo parece equivocada`:`el servidor rechaz\xF3 el lote con HTTP ${o.status}`));}catch(r){this.
13
- fallosSeguidos++,this.requeue(n),this.avisarDeFallo(r instanceof Error?r.message:"error de red");}}avisarDeFallo(t){if(this.options.silenceWarnings)return;let n=this.fallosSeguidos;n<3||(n-3)%12!==0||console.
15
+ fetch;if(!t)return;let n=this.buffer.splice(0,this.maxBatch);try{let o=n.map(s=>this.toWire(s)),r=await t(this.options.url,{method:"POST",headers:{"content-type":"application/json",authorization:`Bear\
16
+ er ${this.options.serviceAccountKey}`},body:JSON.stringify(o)});r.ok?this.fallosSeguidos=0:r.status>=500?(this.fallosSeguidos++,this.requeue(n),this.avisarDeFallo(`el servidor respondi\xF3 ${r.status}`)):
17
+ r.status===401||r.status===403?(A(`metering-auth-${r.status}`,`[bv-sala] el env\xEDo de uso est\xE1 siendo rechazado con HTTP ${r.status} en ${this.options.url}. Revisa 'serviceAccountKey' (\xBFrotada? \xBF\
18
+ revocada? \xBFde otra organizaci\xF3n?). Mientras no funcione NO se reporta uso: el panel dir\xE1 que no ve tr\xE1fico y los asientos facturables saldr\xE1n a cero.`),this.options.onAuthError?.(r.status)):
19
+ (this.fallosSeguidos++,this.avisarDeFallo(r.status===404||r.status===405?`HTTP ${r.status}: la URL de env\xEDo parece equivocada`:`el servidor rechaz\xF3 el lote con HTTP ${r.status}`));}catch(o){this.
20
+ fallosSeguidos++,this.requeue(n),this.avisarDeFallo(o instanceof Error?o.message:"error de red");}}avisarDeFallo(t){if(this.options.silenceWarnings)return;let n=this.fallosSeguidos;n<3||(n-3)%12!==0||console.
14
21
  warn(`[bv-sala] el env\xEDo de uso lleva ${n} intentos seguidos fallando contra ${this.options.url} (${t}). Las peticiones SIGUEN funcionando, pero el uso no est\xE1 llegando: el panel dir\xE1 que no ve tr\xE1\
15
22
  fico y los asientos facturables saldr\xE1n a cero. Comprueba 'meteringUrl' \u2014 por defecto es \`\${licenseServerUrl}/api/metering/usage\`.`);}requeue(t){this.buffer=[...t,...this.buffer],this.buffer.
16
23
  length>this.maxBuffer&&(this.buffer.length=this.maxBuffer);}toWire(t){let n=t.report;return {orgId:this.options.orgId??"self",...this.seatId?{seatId:this.seatId}:{},...this.ci?{ci:true}:{},requestId:n.requestId,
17
24
  model:n.model,at:t.at,avoidedLlm:n.calls.avoidedLlm,actualLlm:n.calls.actualLlm,baselineInputTokens:n.tokens.baselineInput,actualInputTokens:n.tokens.actualInput,eliminatedInputTokens:n.tokens.eliminatedInput,
18
25
  compressedInputTokens:n.tokens.compressedInput,baselineOutputTokens:n.tokens.baselineOutput,actualOutputTokens:n.tokens.actualOutput,providerCachedInputTokens:n.tokens.providerCachedInput??0,cacheResult:n.
19
26
  cache.result,baselineCost:n.cost.baselineEstimate,actualCost:n.cost.actual,netSavings:n.cost.netSavings,...n.cost.basis?{basis:n.cost.basis}:{},...n.attribution?.sessionId?{sessionId:n.attribution.sessionId}:
20
- {},...n.attribution?.agentId?{agentId:n.attribution.agentId}:{}}}};function X(){return globalThis.process}function Rt(e){if(/^[0-9a-f]{12}$/.test(e)||/^\d{1,3}(\.\d{1,3}){3}$/.test(e)||/^ip-\d{1,3}(-\d{1,3}){3}$/i.test(e))return true;let t="[bcdfghjklmnpqrstvwxz2456789]";
21
- return new RegExp(`-${t}{8,10}-${t}{5}$`).test(e)}function _t(e){return !!(e.AWS_LAMBDA_FUNCTION_NAME??e.LAMBDA_TASK_ROOT??e.VERCEL??e.VERCEL_ENV??e.K_SERVICE??e.FUNCTION_TARGET??e.FUNCTIONS_WORKER_RUNTIME??
22
- e.NETLIFY)}async function It(){if(X()?.execPath)try{let t=await import(["node","os"].join(":")),n=typeof t.hostname=="function"?t.hostname():"";return n.length>0?n:void 0}catch{return}}async function At(e,t=It){
23
- if(e.KUBERNETES_SERVICE_HOST||_t(e))return;let n=e.HOSTNAME??e.COMPUTERNAME??await t();if(!(!n||Rt(n)))return n}async function Pt(){let e=X();if(!e||!e.env)return;let t=e.env,n=await At(t),r=[e.platform,
24
- e.arch,e.execPath,n,t.USER??t.USERNAME??t.LOGNAME,t.HOME??t.USERPROFILE].filter(o=>typeof o=="string"&&o.length>0);return r.length?r.join("|"):void 0}var Ot=["CI","CONTINUOUS_INTEGRATION","GITHUB_ACTI\
25
- ONS","GITLAB_CI","CIRCLECI","TRAVIS","JENKINS_URL","BUILDKITE","TF_BUILD","TEAMCITY_VERSION","BITBUCKET_BUILD_NUMBER","CODEBUILD_BUILD_ID","HEROKU_TEST_RUN_ID","DRONE"];function Z(){let e=X()?.env;if(!e)
26
- return false;for(let t of Ot){let n=e[t];if(n&&n!=="false"&&n!=="0")return true}return false}async function Dt(e,t){let n=globalThis.crypto,r=new TextEncoder;if(n?.subtle)try{let i=await n.subtle.importKey("raw",
27
- r.encode(e),{name:"HMAC",hash:"SHA-256"},!1,["sign"]),a=await n.subtle.sign("HMAC",i,r.encode(t));return [...new Uint8Array(a)].map(u=>u.toString(16).padStart(2,"0")).join("")}catch{}let o=2166136261,s=`${e}\
28
- |${t}`;for(let i=0;i<s.length;i++)o^=s.charCodeAt(i),o=Math.imul(o,16777619);return (o>>>0).toString(16).padStart(8,"0")}async function ee(e){let n=X()?.env?.BVSALA_SEAT_ID;if(n&&Lt.test(n))return n;let r=await Pt();
29
- if(!r)return;let o=await Dt(e,r);if(o)return `m-${o.slice(0,32)}`}var Lt=/^[A-Za-z0-9._:/-]{1,128}$/;var pe={"gpt-4.1":{inputPer1k:.002,outputPer1k:.008,cachedInputPer1k:5e-4},"gpt-4.1-mini":{inputPer1k:4e-4,outputPer1k:.0016,cachedInputPer1k:1e-4},"gpt-4.1-nano":{inputPer1k:1e-4,outputPer1k:4e-4,cachedInputPer1k:25e-6},
27
+ {},...n.attribution?.agentId?{agentId:n.attribution.agentId}:{}}}};function se(){return globalThis.process}function Qt(e){if(/^[0-9a-f]{12}$/.test(e)||/^\d{1,3}(\.\d{1,3}){3}$/.test(e)||/^ip-\d{1,3}(-\d{1,3}){3}$/i.test(e))return true;let t="[bcdfghjklmnpqrstvwxz2456789\
28
+ ]";return new RegExp(`-${t}{8,10}-${t}{5}$`).test(e)}function Xt(e){return !!(e.AWS_LAMBDA_FUNCTION_NAME??e.LAMBDA_TASK_ROOT??e.VERCEL??e.VERCEL_ENV??e.K_SERVICE??e.FUNCTION_TARGET??e.FUNCTIONS_WORKER_RUNTIME??
29
+ e.NETLIFY)}async function Zt(){if(se()?.execPath)try{let t=await import(["node","os"].join(":")),n=typeof t.hostname=="function"?t.hostname():"";return n.length>0?n:void 0}catch{return}}async function en(e,t=Zt){
30
+ if(e.KUBERNETES_SERVICE_HOST||Xt(e))return;let n=e.HOSTNAME??e.COMPUTERNAME??await t();if(!(!n||Qt(n)))return n}async function tn(){let e=se();if(!e||!e.env)return;let t=e.env,n=await en(t),o=[e.platform,
31
+ e.arch,e.execPath,n,t.USER??t.USERNAME??t.LOGNAME,t.HOME??t.USERPROFILE].filter(r=>typeof r=="string"&&r.length>0);return o.length?o.join("|"):void 0}var nn=["CI","CONTINUOUS_INTEGRATION","GITHUB_ACTI\
32
+ ONS","GITLAB_CI","CIRCLECI","TRAVIS","JENKINS_URL","BUILDKITE","TF_BUILD","TEAMCITY_VERSION","BITBUCKET_BUILD_NUMBER","CODEBUILD_BUILD_ID","HEROKU_TEST_RUN_ID","DRONE"];function ie(){let e=se()?.env;if(!e)
33
+ return false;for(let t of nn){let n=e[t];if(n&&n!=="false"&&n!=="0")return true}return false}async function on(e,t){let n=globalThis.crypto,o=new TextEncoder;if(n?.subtle)try{let i=await n.subtle.importKey("raw",
34
+ o.encode(e),{name:"HMAC",hash:"SHA-256"},!1,["sign"]),a=await n.subtle.sign("HMAC",i,o.encode(t));return [...new Uint8Array(a)].map(l=>l.toString(16).padStart(2,"0")).join("")}catch{}let r=2166136261,s=`${e}\
35
+ |${t}`;for(let i=0;i<s.length;i++)r^=s.charCodeAt(i),r=Math.imul(r,16777619);return (r>>>0).toString(16).padStart(8,"0")}async function ae(e){let n=se()?.env?.BVSALA_SEAT_ID;if(n&&rn.test(n))return n;let o=await tn();
36
+ if(!o)return;let r=await on(e,o);if(r)return `m-${r.slice(0,32)}`}var rn=/^[A-Za-z0-9._:/-]{1,128}$/;var we={"gpt-4.1":{inputPer1k:.002,outputPer1k:.008,cachedInputPer1k:5e-4},"gpt-4.1-mini":{inputPer1k:4e-4,outputPer1k:.0016,cachedInputPer1k:1e-4},"gpt-4.1-nano":{inputPer1k:1e-4,outputPer1k:4e-4,cachedInputPer1k:25e-6},
30
37
  "gpt-4o":{inputPer1k:.0025,outputPer1k:.01,cachedInputPer1k:.00125},"gpt-4o-mini":{inputPer1k:15e-5,outputPer1k:6e-4,cachedInputPer1k:75e-6},"gpt-4-turbo":{inputPer1k:.01,outputPer1k:.03},"gpt-4":{inputPer1k:.03,
31
38
  outputPer1k:.06},"gpt-3.5-turbo":{inputPer1k:5e-4,outputPer1k:.0015},"gpt-5":{inputPer1k:.00125,outputPer1k:.01,cachedInputPer1k:125e-6},"gpt-5-codex":{inputPer1k:.00125,outputPer1k:.01,cachedInputPer1k:125e-6},
32
39
  "gpt-5-mini":{inputPer1k:25e-5,outputPer1k:.002,cachedInputPer1k:25e-6},"gpt-5-nano":{inputPer1k:5e-5,outputPer1k:4e-4,cachedInputPer1k:5e-6},"gpt-5.1-codex":{inputPer1k:.00125,outputPer1k:.01,cachedInputPer1k:125e-6},
@@ -43,120 +50,136 @@ able-5":{inputPer1k:.01,outputPer1k:.05,cachedInputPer1k:.001},"claude-fable-5-1
43
50
  cachedInputPer1k:1e-4},"claude-3-5-sonnet":{inputPer1k:.003,outputPer1k:.015,cachedInputPer1k:3e-4},"claude-3-5-haiku":{inputPer1k:8e-4,outputPer1k:.004,cachedInputPer1k:8e-5},"claude-3-opus":{inputPer1k:.015,
44
51
  outputPer1k:.075,cachedInputPer1k:.0015},"claude-3-haiku":{inputPer1k:25e-5,outputPer1k:.00125,cachedInputPer1k:3e-5},"gemini-3.7-flash":{inputPer1k:75e-5,outputPer1k:.00375,cachedInputPer1k:75e-6},"g\
45
52
  emini-3.5-flash":{inputPer1k:.0015,outputPer1k:.009,cachedInputPer1k:15e-5},"gemini-3.5-flash-lite":{inputPer1k:3e-4,outputPer1k:.0025,cachedInputPer1k:3e-5},"gemini-3.1-pro-preview":{inputPer1k:.002,
46
- outputPer1k:.012,cachedInputPer1k:2e-4},"gemini-2.5-pro":{inputPer1k:.00125,outputPer1k:.01,cachedInputPer1k:125e-6},"gemini-2.5-flash":{inputPer1k:3e-4,outputPer1k:.0025,cachedInputPer1k:3e-5}};function Ne(e,t,n){
47
- if(!n)return;let r=e[n];if(r)return r;let o=n.lastIndexOf("/"),s=o>=0?n.slice(o+1):n,i=e[s];if(i)return i;for(let a of t){if(!s.startsWith(a))continue;let u=s.charAt(a.length);if(u!==""&&u!=="-"&&u!==
48
- "."&&u!=="_")continue;let p=s.slice(a.length+1);if(!(/^\d/.test(p)&&!/^\d{4}/.test(p)))return e[a]}}function me(e){return Object.keys(e).sort((t,n)=>n.length-t.length)}var Mt=me(pe);function M(e){return Ne(
49
- pe,Mt,e)}var $=class{resto="";uso=null;elisionObservada=null;eventos={};observar(t){this.resto+=typeof t=="string"?t:t.toString("utf8");let n;for(;(n=this.resto.indexOf(`
53
+ outputPer1k:.012,cachedInputPer1k:2e-4},"gemini-2.5-pro":{inputPer1k:.00125,outputPer1k:.01,cachedInputPer1k:125e-6},"gemini-2.5-flash":{inputPer1k:3e-4,outputPer1k:.0025,cachedInputPer1k:3e-5}};function rt(e,t,n){
54
+ if(!n)return;let o=e[n];if(o)return o;let r=n.lastIndexOf("/"),s=r>=0?n.slice(r+1):n,i=e[s];if(i)return i;for(let a of t){if(!s.startsWith(a))continue;let l=s.charAt(a.length);if(l!==""&&l!=="-"&&l!==
55
+ "."&&l!=="_")continue;let d=s.slice(a.length+1);if(!(/^\d/.test(d)&&!/^\d{4}/.test(d)))return e[a]}}function Te(e){return Object.keys(e).sort((t,n)=>n.length-t.length)}var sn=Te(we);function j(e){return rt(
56
+ we,sn,e)}var N=class{resto="";uso=null;elisionObservada=null;eventos={};observar(t){this.resto+=typeof t=="string"?t:t.toString("utf8");let n;for(;(n=this.resto.indexOf(`
50
57
 
51
- `))>=0;){let r=this.resto.slice(0,n);this.resto=this.resto.slice(n+2);let o=/^event: (.+)$/m.exec(r)?.[1];if(o&&(this.eventos[o]=(this.eventos[o]??0)+1),o!=="message_start"&&o!=="message_delta")continue;
52
- let s=/^data: (.+)$/m.exec(r)?.[1];if(s)try{let i=JSON.parse(s),a=ze(i.context_management);a&&(this.elisionObservada=a);let u=i.usage??i.message?.usage;if(u){let p=u.cache_creation||this.uso?.cache_creation?
53
- {...this.uso?.cache_creation,...u.cache_creation}:void 0;this.uso={...this.uso,...u,...p?{cache_creation:p}:{}};}}catch{}}}usage(){return this.uso}usageFinal(){return (this.eventos.message_delta??0)>0?this.
54
- uso:null}elision(){return this.elisionObservada}};function ze(e){if(e===null||typeof e!="object")return null;let t=e.applied_edits;if(!Array.isArray(t)||t.length===0)return null;let n=0;for(let r of t){
55
- let o=r.cleared_input_tokens;typeof o=="number"&&Number.isFinite(o)&&o>0&&(n+=o);}return {borrados:t.length,tokensLimpiados:n}}function Be(e){try{let t=JSON.parse(typeof e=="string"?e:e.toString("utf8"));
56
- return ze(t.context_management)}catch{return null}}var te=class{resto="";uso=null;eventos={};observar(t){this.resto+=typeof t=="string"?t:t.toString("utf8");let n;for(;(n=this.resto.indexOf(`
58
+ `))>=0;){let o=this.resto.slice(0,n);this.resto=this.resto.slice(n+2);let r=/^event: (.+)$/m.exec(o)?.[1];if(r&&(this.eventos[r]=(this.eventos[r]??0)+1),r!=="message_start"&&r!=="message_delta")continue;
59
+ let s=/^data: (.+)$/m.exec(o)?.[1];if(s)try{let i=JSON.parse(s),a=st(i.context_management);a&&(this.elisionObservada=a);let l=i.usage??i.message?.usage;if(l){let d=l.cache_creation||this.uso?.cache_creation?
60
+ {...this.uso?.cache_creation,...l.cache_creation}:void 0;this.uso={...this.uso,...l,...d?{cache_creation:d}:{}};}}catch{}}}usage(){return this.uso}usageFinal(){return (this.eventos.message_delta??0)>0?this.
61
+ uso:null}elision(){return this.elisionObservada}};function st(e){if(e===null||typeof e!="object")return null;let t=e.applied_edits;if(!Array.isArray(t)||t.length===0)return null;let n=0;for(let o of t){
62
+ let r=o.cleared_input_tokens;typeof r=="number"&&Number.isFinite(r)&&r>0&&(n+=r);}return {borrados:t.length,tokensLimpiados:n}}function it(e){try{let t=JSON.parse(typeof e=="string"?e:e.toString("utf8"));
63
+ return st(t.context_management)}catch{return null}}var ce=class{resto="";uso=null;eventos={};observar(t){this.resto+=typeof t=="string"?t:t.toString("utf8");let n;for(;(n=this.resto.indexOf(`
57
64
 
58
- `))>=0;){let r=this.resto.slice(0,n);this.resto=this.resto.slice(n+2);let o=/^event: (.+)$/m.exec(r)?.[1];o&&(this.eventos[o]=(this.eventos[o]??0)+1);let s=/^data: (.+)$/m.exec(r)?.[1];if(s)try{let i=JSON.
59
- parse(s);if((o??i.type)!=="response.completed")continue;let a=i.response?.usage;a&&(this.uso=$t(a));}catch{}}}usage(){return this.uso}usageFinal(){return this.uso}};function $t(e){let t=Math.max(0,e.input_tokens??
60
- 0),n=Math.min(Math.max(0,e.input_tokens_details?.cached_tokens??0),t),r=Math.min(Math.max(0,e.input_tokens_details?.cache_write_tokens??0),t-n);return {input_tokens:t-n-r,output_tokens:Math.max(0,e.output_tokens??
61
- 0),cache_read_input_tokens:n,cache_creation_input_tokens:r}}var je=1.25,fe=2;function Ue(e,t){let n=M(e);if(!n)return null;let r=t.input_tokens??0,o=t.output_tokens??0,s=t.cache_read_input_tokens??0,i=t.
62
- cache_creation,a=t.cache_creation_input_tokens??(i?.ephemeral_5m_input_tokens??0)+(i?.ephemeral_1h_input_tokens??0),u=Math.min(i?.ephemeral_1h_input_tokens??0,a),p=n.cachedInputPer1k??n.inputPer1k;return {
63
- costeUsd:r/1e3*n.inputPer1k+s/1e3*p+(a-u)/1e3*n.inputPer1k*ge(e)+u/1e3*n.inputPer1k*fe+o/1e3*n.outputPer1k,precio:n,tokens:{entrada:r,salida:o,cacheLeida:s,cacheEscrita:a,cacheEscrita1h:u}}}function Ve(e,t){
64
- let r=he(e,t)?.model;return typeof r=="string"?r:""}function he(e,t){try{let n=e,r={maxOutputLength:Nt};switch((t??"").trim().toLowerCase()){case "gzip":case "x-gzip":n=A.gunzipSync(e,r);break;case "defl\
65
- ate":n=A.inflateSync(e,r);break;case "br":n=A.brotliDecompressSync(e,r);break;case "zstd":{let o=A.zstdDecompressSync;if(typeof o!="function")return null;n=o(e,r);break}default:break}return JSON.parse(n.
66
- toString("utf8"))}catch{return null}}var Nt=5*1024*1024;function Fe(){return typeof A.zstdDecompressSync=="function"}function ge(e){let t=e.toLowerCase();return t.startsWith("gpt-")||t.startsWith("o1")||
67
- t.startsWith("o3")||t.startsWith("o4")?/^gpt-5\.6/.test(t)?je:1:t.startsWith("gemini")?1:je}function be(e){try{return JSON.parse(typeof e=="string"?e:e.toString("utf8")).usage??null}catch{return null}}
68
- function qe(e,t,n,r,o){return Je(e,t,n,false,r,o)}function Ke(e,t,n,r){return Je(e,t,n,true,r)}function He(e,t,n,r,o){return {requestId:e,model:t,...o&&(o.sessionId||o.agentId)?{attribution:o}:{},calls:{avoidedLlm:0,
69
- actualLlm:0},tokens:{baselineInput:0,actualInput:0,eliminatedInput:0,compressedInput:0,baselineOutput:0,actualOutput:0,providerCachedInput:0},cache:{result:"miss"},cost:{baselineEstimate:n,actual:r,netSavings:n>
70
- 0?Math.max(-100,Math.min(1,(n-r)/n)):0,basis:"shadow"}}}function Je(e,t,n,r,o,s){let i=n.tokens.entrada+n.tokens.cacheLeida+n.tokens.cacheEscrita;return {requestId:e,model:t,...o&&(o.sessionId||o.agentId)?
71
- {attribution:o}:{},calls:r?{avoidedLlm:1,actualLlm:0}:{avoidedLlm:0,actualLlm:1},tokens:{baselineInput:i,actualInput:r?0:i,eliminatedInput:r?0:s?.tokensLimpiados??0,compressedInput:0,baselineOutput:n.
72
- tokens.salida,actualOutput:r?0:n.tokens.salida,providerCachedInput:r?0:n.tokens.cacheLeida},cache:{result:r?"singleflight":"miss"},cost:r?{baselineEstimate:n.costeUsd,actual:0,netSavings:1,basis:"esti\
73
- mated"}:{baselineEstimate:n.costeUsd,actual:n.costeUsd,netSavings:0,basis:"measured"}}}var zt=1024,q=120,Bt=8,Ut=256*1024,Vt=/error|exception|traceback|warn|fatal|fail|panic|assert|denied|refused|timeout|\bat\s+\S+:\d+/i,Ge=/^\s*(export\s|import\s|function\s|class\s|interface\s|type\s|enum\s|def\s|fn\s|func\s|impl\s|struct\s|trait\s|package\s|module\s|@\w)/;
74
- function Ft(e){return Buffer.byteLength(typeof e=="string"?e:JSON.stringify(e??""))}function qt(e){return typeof e=="string"?e:Array.isArray(e)?e.map(t=>t&&typeof t=="object"&&typeof t.text=="string"?
65
+ `))>=0;){let o=this.resto.slice(0,n);this.resto=this.resto.slice(n+2);let r=/^event: (.+)$/m.exec(o)?.[1];r&&(this.eventos[r]=(this.eventos[r]??0)+1);let s=/^data: (.+)$/m.exec(o)?.[1];if(s)try{let i=JSON.
66
+ parse(s);if((r??i.type)!=="response.completed")continue;let a=i.response?.usage;a&&(this.uso=an(a));}catch{}}}usage(){return this.uso}usageFinal(){return this.uso}};function an(e){let t=Math.max(0,e.input_tokens??
67
+ 0),n=Math.min(Math.max(0,e.input_tokens_details?.cached_tokens??0),t),o=Math.min(Math.max(0,e.input_tokens_details?.cache_write_tokens??0),t-n);return {input_tokens:t-n-o,output_tokens:Math.max(0,e.output_tokens??
68
+ 0),cache_read_input_tokens:n,cache_creation_input_tokens:o}}var Ee=1.25,le=2;function at(e,t){let n=j(e);if(!n)return null;let o=t.input_tokens??0,r=t.output_tokens??0,s=t.cache_read_input_tokens??0,i=t.
69
+ cache_creation,a=t.cache_creation_input_tokens??(i?.ephemeral_5m_input_tokens??0)+(i?.ephemeral_1h_input_tokens??0),l=Math.min(i?.ephemeral_1h_input_tokens??0,a),d=n.cachedInputPer1k??n.inputPer1k;return {
70
+ costeUsd:o/1e3*n.inputPer1k+s/1e3*d+(a-l)/1e3*n.inputPer1k*Re(e)+l/1e3*n.inputPer1k*le+r/1e3*n.outputPer1k,precio:n,tokens:{entrada:o,salida:r,cacheLeida:s,cacheEscrita:a,cacheEscrita1h:l}}}function ct(e,t){
71
+ let o=Ce(e,t)?.model;return typeof o=="string"?o:""}function Ce(e,t){try{let n=e,o={maxOutputLength:cn};switch((t??"").trim().toLowerCase()){case "gzip":case "x-gzip":n=P.gunzipSync(e,o);break;case "defl\
72
+ ate":n=P.inflateSync(e,o);break;case "br":n=P.brotliDecompressSync(e,o);break;case "zstd":{let r=P.zstdDecompressSync;if(typeof r!="function")return null;n=r(e,o);break}default:break}return JSON.parse(n.
73
+ toString("utf8"))}catch{return null}}var cn=5*1024*1024;function lt(){return typeof P.zstdDecompressSync=="function"}function Re(e){let t=e.toLowerCase();return t.startsWith("gpt-")||t.startsWith("o1")||
74
+ t.startsWith("o3")||t.startsWith("o4")?/^gpt-5\.6/.test(t)?Ee:1:t.startsWith("gemini")?1:Ee}function Ae(e){try{return JSON.parse(typeof e=="string"?e:e.toString("utf8")).usage??null}catch{return null}}
75
+ function ut(e,t,n,o,r,s){return mt(e,t,n,false,o,r,s)}function dt(e,t,n,o){return mt(e,t,n,true,o)}function pt(e,t,n,o,r){return {requestId:e,model:t,...r&&(r.sessionId||r.agentId)?{attribution:r}:{},calls:{
76
+ avoidedLlm:0,actualLlm:0},tokens:{baselineInput:0,actualInput:0,eliminatedInput:0,compressedInput:0,baselineOutput:0,actualOutput:0,providerCachedInput:0},cache:{result:"miss"},cost:{baselineEstimate:n,
77
+ actual:o,netSavings:n>0?Math.max(-100,Math.min(1,(n-o)/n)):0,basis:"shadow"}}}function mt(e,t,n,o,r,s,i){let a=n.tokens.entrada+n.tokens.cacheLeida+n.tokens.cacheEscrita,l=n.tokens.cacheEscrita-n.tokens.
78
+ cacheEscrita1h,d=!o&&i&&i.rebajadas>0&&i.yaEran5m===0&&l>0?l/1e3*n.precio.inputPer1k*(le-Ee):0,m=n.costeUsd+d;return {requestId:e,model:t,...r&&(r.sessionId||r.agentId)?{attribution:r}:{},calls:o?{avoidedLlm:1,
79
+ actualLlm:0}:{avoidedLlm:0,actualLlm:1},tokens:{baselineInput:a,actualInput:o?0:a,eliminatedInput:o?0:s?.tokensLimpiados??0,compressedInput:0,baselineOutput:n.tokens.salida,actualOutput:o?0:n.tokens.salida,
80
+ providerCachedInput:o?0:n.tokens.cacheLeida},cache:{result:o?"singleflight":"miss"},cost:o?{baselineEstimate:n.costeUsd,actual:0,netSavings:1,basis:"estimated"}:{baselineEstimate:m,actual:n.costeUsd,netSavings:m>
81
+ 0?Math.max(-100,Math.min(1,d/m)):0,basis:"measured"}}}var un=1024,G=120,dn=8,pn=256*1024,mn=/error|exception|traceback|warn|fatal|fail|panic|assert|denied|refused|timeout|\bat\s+\S+:\d+/i,ht=/^\s*(export\s|import\s|function\s|class\s|interface\s|type\s|enum\s|def\s|fn\s|func\s|impl\s|struct\s|trait\s|package\s|module\s|@\w)/;
82
+ function fn(e){return Buffer.byteLength(typeof e=="string"?e:JSON.stringify(e??""))}function hn(e){return typeof e=="string"?e:Array.isArray(e)?e.map(t=>t&&typeof t=="object"&&typeof t.text=="string"?
75
83
  t.text:"").join(`
76
- `):""}var Kt=/^\s*\d+[\t→]/;function Ye(e){return e.replace(Kt,"")}function Ht(e){if(!e)return "otro";let t=e.split(`
77
- `),n=Math.max(1,t.length),r=0,o=0,s=0;for(let i of t){let a=Ye(i);(/^[+-](?![+-])/.test(a)||a.startsWith("@@")||a.startsWith("diff --git"))&&(r+=1),Ge.test(a)&&(o+=1),(/^\s*(\d{4}-\d{2}-\d{2}|\[\d|\d{2}:\d{2}:\d{2})/.
78
- test(a)||/\b(INFO|DEBUG|TRACE|WARN|ERROR)\b/.test(a))&&(s+=1);}return r/n>.25?"diff":s/n>.3?"log":o/n>.08?"codigo":"otro"}function Jt(e,t){if(t==="diff"||t==="otro")return Buffer.byteLength(e);let n=e.
84
+ `):""}var gn=/^\s*\d+[\t→]/;function gt(e){return e.replace(gn,"")}function bn(e){if(!e)return "otro";let t=e.split(`
85
+ `),n=Math.max(1,t.length),o=0,r=0,s=0;for(let i of t){let a=gt(i);(/^[+-](?![+-])/.test(a)||a.startsWith("@@")||a.startsWith("diff --git"))&&(o+=1),ht.test(a)&&(r+=1),(/^\s*(\d{4}-\d{2}-\d{2}|\[\d|\d{2}:\d{2}:\d{2})/.
86
+ test(a)||/\b(INFO|DEBUG|TRACE|WARN|ERROR)\b/.test(a))&&(s+=1);}return o/n>.25?"diff":s/n>.3?"log":r/n>.08?"codigo":"otro"}function vn(e,t){if(t==="diff"||t==="otro")return Buffer.byteLength(e);let n=e.
79
87
  split(`
80
- `),r=new Set;for(let s=0;s<n.length;s++){let i=Ye(n[s]);(t==="log"?Vt.test(i):Ge.test(i))&&(r.add(s),t==="log"&&(s>0&&r.add(s-1),s<n.length-1&&r.add(s+1)));}let o=q;for(let s of r)o+=Buffer.byteLength(
81
- n[s])+1;return Math.min(o,Buffer.byteLength(e))}function Qe(e){let t=[],n=(r,o)=>{let s=Ft(o),i={clave:createHash("sha256").update(typeof o=="string"?o:JSON.stringify(o??"")).digest("hex").slice(0,16),tipo:r,
82
- bytes:s,bytesV1:s,clase:"otro",esError:false};if(r.endsWith(":tool_result")&&o&&typeof o=="object"){let a=o;i.esError=a.is_error===true;let u=qt(a.content);i.clase=Ht(u);let p=s-Buffer.byteLength(u);i.bytesV1=
83
- Math.min(s,Math.max(0,p)+Jt(u,i.clase));}t.push(i);};if((e.system??void 0)!==void 0&&n("system",e.system),Array.isArray(e.tools))for(let r of e.tools)n("tools",r);for(let r of Array.isArray(e.messages)?
84
- e.messages:[]){if(!r||typeof r!="object"){n("?:invalido",r);continue}let o=r,s=typeof o.role=="string"?o.role:"?";if(typeof o.content=="string")n(`${s}:text`,o.content);else if(Array.isArray(o.content))
85
- for(let i of o.content)n(`${s}:${i?.type??"?"}`,i);}return t}function Wt(){return {nacimiento:new Map,turno:0,elididosV2m:new Set}}function Gt(e,t){let n=e.turno++;for(let r of t)e.nacimiento.has(r.clave)||
86
- e.nacimiento.set(r.clave,n);return n}function Xe(e,t,n,r,o=Ut){let s=t.reduce((l,c,d)=>c.tipo.endsWith(":tool_result")?d:l,-1),i=(l,c)=>l.tipo.endsWith(":tool_result")&&l.bytes>=zt&&c!==s;return t.map((l,c)=>{if(!i(l,c))return {clave:l.clave,bytes:l.bytes};let d=r-(n.nacimiento.get(l.clave)??r);return d>=2&&d*l.bytes/1024>=Bt?{clave:`${l.clave}:e`,bytes:q}:{clave:l.clave,bytes:l.bytes}});
87
- }function Yt(e){let t=M(e);return t?{lecturaPer1k:t.cachedInputPer1k??t.inputPer1k,escrituraPer1k:t.
88
- inputPer1k*ge(e),escritura1hPer1k:t.inputPer1k*fe}:null}function We(){return {lecturaUsd:0,escrituraUsd:0,totalUsd:0,tokensLeidos:0,tokensEscritos:0,tokensInvalidados:0,invalidacionUsd:0}}var Qt={"1h":36e5,
89
- "5m":3e5},K=class{constructor(t){this.transformar=t;}transformar;estado=Wt();previo=[];hayPrevio=false;atPrevio=0;acumulado=We();paso(t){let n=We(),r=Gt(this.estado,t.bloques),o=Yt(t.model),s=this.transformar(
90
- t.bloques,this.estado,r);if(!o||t.entradaReal<=0)return this.previo=s,this.hayPrevio=true,this.atPrevio=t.at,n;let i=t.bloques.reduce((h,b)=>h+b.bytes,0),a=i>0?t.entradaReal/i:0,u=Qt[t.escritura1h?"1h":
91
- "5m"],p=this.hayPrevio&&t.at-this.atPrevio>u,m=0;if(!p)for(;m<s.length&&m<this.previo.length&&s[m].clave===this.previo[m].clave&&s[m].bytes===this.previo[m].bytes;)m+=1;let l=this.previo.slice(m),c=0,
92
- d=t.escritura1h?o.escritura1hPer1k:o.escrituraPer1k;for(let h=0;h<s.length;h++){let b=s[h],v=b.bytes*a;if(h<m){n.tokensLeidos+=v,n.lecturaUsd+=v/1e3*o.lecturaPer1k;continue}if(n.tokensEscritos+=v,n.escrituraUsd+=
93
- v/1e3*d,!p){let f=c;for(;f<l.length&&l[f].clave!==b.clave;)f+=1;f<l.length&&(l[f].bytes===b.bytes&&(n.tokensInvalidados+=v,n.invalidacionUsd+=v/1e3*(d-o.lecturaPer1k)),c=f+1);}}return this.previo=s,this.
88
+ `),o=new Set;for(let s=0;s<n.length;s++){let i=gt(n[s]);(t==="log"?mn.test(i):ht.test(i))&&(o.add(s),t==="log"&&(s>0&&o.add(s-1),s<n.length-1&&o.add(s+1)));}let r=G;for(let s of o)r+=Buffer.byteLength(
89
+ n[s])+1;return Math.min(r,Buffer.byteLength(e))}function bt(e){let t=[],n=(o,r)=>{let s=fn(r),i={clave:createHash("sha256").update(typeof r=="string"?r:JSON.stringify(r??"")).digest("hex").slice(0,16),tipo:o,
90
+ bytes:s,bytesV1:s,clase:"otro",esError:false};if(o.endsWith(":tool_result")&&r&&typeof r=="object"){let a=r;i.esError=a.is_error===true;let l=hn(a.content);i.clase=bn(l);let d=s-Buffer.byteLength(l);i.bytesV1=
91
+ Math.min(s,Math.max(0,d)+vn(l,i.clase));}t.push(i);};if((e.system??void 0)!==void 0&&n("system",e.system),Array.isArray(e.tools))for(let o of e.tools)n("tools",o);for(let o of Array.isArray(e.messages)?
92
+ e.messages:[]){if(!o||typeof o!="object"){n("?:invalido",o);continue}let r=o,s=typeof r.role=="string"?r.role:"?";if(typeof r.content=="string")n(`${s}:text`,r.content);else if(Array.isArray(r.content))
93
+ for(let i of r.content)n(`${s}:${i?.type??"?"}`,i);}return t}function yn(){return {nacimiento:new Map,turno:0,elididosV2m:new Set}}function kn(e,t){let n=e.turno++;for(let o of t)e.nacimiento.has(o.clave)||
94
+ e.nacimiento.set(o.clave,n);return n}function vt(e,t,n,o,r=pn){let s=t.reduce((c,f,u)=>f.tipo.endsWith(":tool_result")?u:c,-1),i=(c,f)=>c.tipo.endsWith(":tool_result")&&c.bytes>=un&&f!==s;return t.map((c,f)=>{if(!i(c,f))return {clave:c.clave,bytes:c.bytes};let u=o-(n.nacimiento.get(c.clave)??o);return u>=2&&u*c.bytes/1024>=dn?{clave:`${c.clave}:e`,bytes:G}:{clave:c.clave,bytes:c.bytes}});
95
+ }function xn(e){let t=j(e);return t?{lecturaPer1k:t.cachedInputPer1k??t.inputPer1k,escrituraPer1k:t.
96
+ inputPer1k*Re(e),escritura1hPer1k:t.inputPer1k*le}:null}function ft(){return {lecturaUsd:0,escrituraUsd:0,totalUsd:0,tokensLeidos:0,tokensEscritos:0,tokensInvalidados:0,invalidacionUsd:0}}var Sn={"1h":36e5,
97
+ "5m":3e5},Y=class{constructor(t){this.transformar=t;}transformar;estado=yn();previo=[];hayPrevio=false;atPrevio=0;acumulado=ft();paso(t){let n=ft(),o=kn(this.estado,t.bloques),r=xn(t.model),s=this.transformar(
98
+ t.bloques,this.estado,o);if(!r||t.entradaReal<=0)return this.previo=s,this.hayPrevio=true,this.atPrevio=t.at,n;let i=t.bloques.reduce((p,g)=>p+g.bytes,0),a=i>0?t.entradaReal/i:0,l=Sn[t.escritura1h?"1h":
99
+ "5m"],d=this.hayPrevio&&t.at-this.atPrevio>l,m=0;if(!d)for(;m<s.length&&m<this.previo.length&&s[m].clave===this.previo[m].clave&&s[m].bytes===this.previo[m].bytes;)m+=1;let c=this.previo.slice(m),f=0,
100
+ u=t.escritura1h?r.escritura1hPer1k:r.escrituraPer1k;for(let p=0;p<s.length;p++){let g=s[p],y=g.bytes*a;if(p<m){n.tokensLeidos+=y,n.lecturaUsd+=y/1e3*r.lecturaPer1k;continue}if(n.tokensEscritos+=y,n.escrituraUsd+=
101
+ y/1e3*u,!d){let k=f;for(;k<c.length&&c[k].clave!==g.clave;)k+=1;k<c.length&&(c[k].bytes===g.bytes&&(n.tokensInvalidados+=y,n.invalidacionUsd+=y/1e3*(u-r.lecturaPer1k)),f=k+1);}}return this.previo=s,this.
94
102
  hayPrevio=true,this.atPrevio=t.at,n.totalUsd=n.lecturaUsd+n.escrituraUsd,this.acumulado.lecturaUsd+=n.lecturaUsd,this.acumulado.escrituraUsd+=n.escrituraUsd,this.acumulado.totalUsd+=n.totalUsd,this.acumulado.
95
- tokensLeidos+=n.tokensLeidos,this.acumulado.tokensEscritos+=n.tokensEscritos,this.acumulado.tokensInvalidados+=n.tokensInvalidados,this.acumulado.invalidacionUsd+=n.invalidacionUsd,n}};function Ze(e){return e.map(t=>({clave:t.clave,bytes:t.bytes}))}var Zt=64,ne=class{cadenas=new Map;observar(t){let n=t.uso.cache_creation_input_tokens??(t.uso.cache_creation?.ephemeral_5m_input_tokens??0)+(t.uso.cache_creation?.ephemeral_1h_input_tokens??0),r=(t.uso.
96
- input_tokens??0)+(t.uso.cache_read_input_tokens??0)+n;if(r<=0)return null;let o={bloques:Qe(t.cuerpo),at:t.at,model:t.model,entradaReal:r,escritura1h:(t.uso.cache_creation?.ephemeral_1h_input_tokens??
97
- 0)>0};if(o.bloques.length===0)return null;let s=this.cadenaPara(this.clave(t)),i=s.base.paso(o),a=s.v0.paso(o);return i.totalUsd<=0&&a.totalUsd<=0?null:{baselineUsd:i.totalUsd,politicaUsd:a.totalUsd}}clave(t){
103
+ tokensLeidos+=n.tokensLeidos,this.acumulado.tokensEscritos+=n.tokensEscritos,this.acumulado.tokensInvalidados+=n.tokensInvalidados,this.acumulado.invalidacionUsd+=n.invalidacionUsd,n}};function yt(e){return e.map(t=>({clave:t.clave,bytes:t.bytes}))}var Tn=64,ue=class{cadenas=new Map;observar(t){let n=t.uso.cache_creation_input_tokens??(t.uso.cache_creation?.ephemeral_5m_input_tokens??0)+(t.uso.cache_creation?.ephemeral_1h_input_tokens??0),o=(t.uso.
104
+ input_tokens??0)+(t.uso.cache_read_input_tokens??0)+n;if(o<=0)return null;let r={bloques:bt(t.cuerpo),at:t.at,model:t.model,entradaReal:o,escritura1h:(t.uso.cache_creation?.ephemeral_1h_input_tokens??
105
+ 0)>0};if(r.bloques.length===0)return null;let s=this.cadenaPara(this.clave(t)),i=s.base.paso(r),a=s.v0.paso(r);return i.totalUsd<=0&&a.totalUsd<=0?null:{baselineUsd:i.totalUsd,politicaUsd:a.totalUsd}}clave(t){
98
106
  if(t.sessionId)return `s:${t.sessionId}\xB7a:${t.agentId??""}\xB7${t.model}`;let n=Array.isArray(t.cuerpo.messages)?t.cuerpo.messages[0]:void 0;return `m:${createHash("sha256").update(JSON.stringify(n??null)).digest(
99
- "hex").slice(0,16)}\xB7${t.model}`}cadenaPara(t){let n=this.cadenas.get(t);if(!n&&(n={base:new K(r=>Ze(r)),v0:new K((r,o,s)=>Xe("v0",r,o,s)),ultimoUso:0},this.cadenas.set(t,n),this.cadenas.size>Zt)){let r=null,
100
- o=1/0;for(let[s,i]of this.cadenas)i.ultimoUso<o&&(o=i.ultimoUso,r=s);r!==null&&this.cadenas.delete(r);}return n.ultimoUso=Date.now(),n}};var oe=class{url;clave;ttlMs;fetchImpl;log;features=new Set;validoHasta=0;enVuelo=null;avisado=false;constructor(t){this.url=t.url,this.clave=t.serviceAccountKey,this.ttlMs=t.ttlMs??3e5,this.fetchImpl=t.
107
+ "hex").slice(0,16)}\xB7${t.model}`}cadenaPara(t){let n=this.cadenas.get(t);if(!n&&(n={base:new Y(o=>yt(o)),v0:new Y((o,r,s)=>vt("v0",o,r,s)),ultimoUso:0},this.cadenas.set(t,n),this.cadenas.size>Tn)){let o=null,
108
+ r=1/0;for(let[s,i]of this.cadenas)i.ultimoUso<r&&(r=i.ultimoUso,o=s);o!==null&&this.cadenas.delete(o);}return n.ultimoUso=Date.now(),n}};var de=class{url;clave;ttlMs;fetchImpl;log;features=new Set;validoHasta=0;enVuelo=null;avisado=false;constructor(t){this.url=t.url,this.clave=t.serviceAccountKey,this.ttlMs=t.ttlMs??3e5,this.fetchImpl=t.
101
109
  fetchImpl??fetch,this.log=t.log??(()=>{}),this.refrescar();}tiene(t){return Date.now()>this.validoHasta&&this.enVuelo===null&&this.refrescar(),this.features.has(t)}refrescar(){return this.enVuelo?this.
102
110
  enVuelo:(this.enVuelo=this.pedir().finally(()=>{this.enVuelo=null;}),this.enVuelo)}async pedir(){try{let t=await this.fetchImpl(this.url,{method:"GET",headers:{authorization:`Bearer ${this.clave}`},signal:AbortSignal.
103
- timeout(1e4)});if(!t.ok){this.cerrar(`entitlements HTTP ${t.status}`);return}let n=await t.json();if(!Array.isArray(n.features)||!n.features.every(o=>typeof o=="string")){this.cerrar("entitlements con\
104
- forma inesperada");return}this.features=new Set(n.features);let r=typeof n.refreshAfterSeconds=="number"&&n.refreshAfterSeconds>0?Math.min(n.refreshAfterSeconds*1e3,this.ttlMs):this.ttlMs;this.validoHasta=
105
- Date.now()+r,this.avisado=!1;}catch(t){this.cerrar(String(t));}}cerrar(t){this.features=new Set,this.validoHasta=Date.now()+Math.min(6e4,this.ttlMs),this.avisado||(this.avisado=true,this.log(`[gateway] en\
106
- titlements no disponibles (${t}) \u2014 palanca apagada (fail-closed)`));}};var re="context-management-2025-06-27";function et(){return {edits:[{type:"clear_tool_uses_20250919",trigger:{type:"input_tokens",value:5e4},keep:{type:"tool_uses",value:8},clear_at_least:{type:"input_tokens",value:5e3}}]}}function tt(e,t){if(t!==void 0&&t!==""&&t!=="identity")return null;try{let n=JSON.parse(e.toString("utf8"));return n===null||typeof n!="object"||Array.isArray(n)||typeof n.model!="string"||!Array.isArray(
107
- n.messages)?null:(n.context_management=et(),Buffer.from(JSON.stringify(n),"utf8"))}catch{return null}}function nt(e){return e===void 0||e.trim()===""?re:e.split(",").map(n=>n.trim()).filter(n=>n.length>
108
- 0).includes(re)?e:`${e},${re}`}var ve=5*1024*1024,tn=["authorization","x-api-key","anthropic-version","anthropic-beta"];function ot(e,t,n,r=""){return createHash("sha256").update(e).update(`
111
+ timeout(1e4)});if(!t.ok){this.cerrar(`entitlements HTTP ${t.status}`);return}let n=await t.json();if(!Array.isArray(n.features)||!n.features.every(r=>typeof r=="string")){this.cerrar("entitlements con\
112
+ forma inesperada");return}this.features=new Set(n.features);let o=typeof n.refreshAfterSeconds=="number"&&n.refreshAfterSeconds>0?Math.min(n.refreshAfterSeconds*1e3,this.ttlMs):this.ttlMs;this.validoHasta=
113
+ Date.now()+o,this.avisado=!1;}catch(t){this.cerrar(String(t));}}cerrar(t){this.features=new Set,this.validoHasta=Date.now()+Math.min(6e4,this.ttlMs),this.avisado||(this.avisado=true,this.log(`[gateway] en\
114
+ titlements no disponibles (${t}) \u2014 palanca apagada (fail-closed)`));}};var Cn=.3,Rn=4096,An=(e,t)=>e==="cache_control"?void 0:t;function _e(e){return e===void 0?"":JSON.stringify(e,An)??""}function Ie(e){return createHash("sha1").update(e).digest("base64url").slice(0,16)}function Oe(e,t){
115
+ if(t!==void 0&&t!==""&&t!=="identity")return null;try{let n=JSON.parse(e.toString("utf8"));if(n===null||typeof n!="object"||Array.isArray(n))return null;let o=n;return typeof o.model!="string"||!Array.
116
+ isArray(o.messages)?null:o}catch{return null}}function kt(e){let t=_e(e.system),n=_e(e.tools),o=Array.isArray(e.messages)?e.messages.slice(0,Rn):[],r=[],s=[];for(let i of o){let a=_e(i);r.push(Ie(a)),
117
+ s.push(Buffer.byteLength(a,"utf8"));}return {system:Ie(t),tools:Ie(n),mensajes:r,bytes:s,bytesFijos:Buffer.byteLength(t,"utf8")+Buffer.byteLength(n,"utf8")}}function xt(e,t){if(e===void 0||e.system!==t.
118
+ system||e.tools!==t.tools)return 1;let n=t.bytesFijos;for(let s of t.bytes)n+=s;if(n<=0)return 1;let o=0;for(;o<e.mensajes.length&&o<t.mensajes.length&&e.mensajes[o]===t.mensajes[o];)o++;let r=0;for(let s=o;s<
119
+ t.bytes.length;s++)r+=t.bytes[s]??0;return r/n}function St(e){let{fraccionNueva:t,umbral:n=Cn}=e;return t>=n}function Pe(e,t){if(e===null||typeof e!="object")return;if(Array.isArray(e)){for(let r of e)
120
+ Pe(r,t);return}let n=e,o=n.cache_control;if(o!==null&&typeof o=="object"&&!Array.isArray(o)){let r=o;r.ttl==="1h"?(r.ttl="5m",t.rebajadas++):(r.ttl==="5m"||r.ttl===void 0)&&t.yaEran5m++;}for(let[r,s]of Object.
121
+ entries(n))r!=="cache_control"&&s!==null&&typeof s=="object"&&Pe(s,t);}function wt(e,t){let n=Buffer.isBuffer(e)?Oe(e,t):e;if(n===null)return null;try{let o={rebajadas:0,yaEran5m:0};for(let r of ["syste\
122
+ m","messages","tools"])Pe(n[r],o);return o.rebajadas===0?null:{cuerpo:Buffer.from(JSON.stringify(n),"utf8"),rebajadas:o.rebajadas,yaEran5m:o.yaEran5m}}catch{return null}}var pe=class{constructor(t=512,n=3600*1e3){this.maxEntradas=t;this.maxEdadMs=n;}maxEntradas;maxEdadMs;visto=new Map;ultima(t,n){let o=this.visto.get(t);if(o!==void 0){if(n-o.vistoMs>this.maxEdadMs){this.
123
+ visto.delete(t);return}return o.huella}}anotar(t,n,o){for(this.visto.delete(t),this.visto.set(t,{huella:n,vistoMs:o});this.visto.size>this.maxEntradas;){let r=this.visto.keys().next();if(r.done===true)break;
124
+ this.visto.delete(r.value);}}get tamano(){return this.visto.size}};var De=5*1024*1024,In=["authorization","x-api-key","anthropic-version","anthropic-beta"];function Tt(e,t,n,o=""){return createHash("sha256").update(e).update(`
109
125
  `).update(t).update(`
110
- `).update(r).update(`
111
- `).update(n).digest("hex")}function rt(e){return tn.map(t=>`${t}=${e(t)??""}`).join(`
112
- `)}var se=class{enVuelo=new Map;primarias=0;gemelas=0;registrar(t){if(this.enVuelo.has(t))return null;this.primarias+=1;let n,r=new Promise(a=>n=a);this.enVuelo.set(t,{promesa:r,resolver:n});let o=[],
113
- s=0,i=false;return {capturar:a=>{if(!i){if(s+=a.length,s>ve){i=true,o.length=0;return}o.push(a);}},terminar:(a,u)=>{let p=!i&&a>=200&&a<300;this.enVuelo.get(t)?.resolver(p?{status:a,headers:u,chunks:o}:null),
114
- this.enVuelo.delete(t);},abortar:()=>{this.enVuelo.get(t)?.resolver(null),this.enVuelo.delete(t);}}}async esperar(t){let n=this.enVuelo.get(t);if(!n)return null;let r=await n.promesa;return r&&(this.gemelas+=
115
- 1),r}tieneEnVuelo(t){return this.enVuelo.has(t)}};var rn=["content-encoding","content-length","transfer-encoding"];async function st(e={}){let t=(e.upstream??"https://api.anthropic.com").replace(/\/+$/,""),n=e.fetchImpl??fetch,r=e.log??(c=>console.log(
116
- c)),o;if(e.serviceAccountKey){o=new z({url:e.meteringUrl??"https://savings.bivelio.com/api/metering/usage",serviceAccountKey:e.serviceAccountKey,...e.fetchImpl?{fetchImpl:e.fetchImpl}:{},onAuthError:d=>E(
117
- "gateway-ingest-auth",`[bvsala gateway] la ingesta de uso rechaza la credencial (${d}). El tr\xE1fico sigue fluyendo (avisar, nunca romper), pero este uso no est\xE1 llegando al panel. Revisa BIVELIO_SERVIC\
118
- E_KEY y el estado de la suscripci\xF3n en savings.bivelio.com.`)});let c=Z();e.seatId?o.setSeat(e.seatId,c):ee(e.serviceAccountKey).then(d=>o?.setSeat(d,c)).catch(()=>{}),o.start();}else E("gateway-sin\
119
- -clave","[bvsala gateway] sin BIVELIO_SERVICE_KEY: el gateway reenv\xEDa el tr\xE1fico pero NO mide. Consigue tu clave en savings.bivelio.com/dashboard/install para ver el gasto en tu panel.");let s=e.
120
- coalescer?new se:null,i=e.sombra&&o?new ne:null,a=e.elision!==false&&e.serviceAccountKey?new oe({url:new URL("/api/org/entitlements",e.meteringUrl??"https://savings.bivelio.com/api/metering/usage").toString(),
121
- serviceAccountKey:e.serviceAccountKey,...e.fetchImpl?{fetchImpl:e.fetchImpl}:{},log:r}):null,u=c=>c==="/v1/messages"?new $:c.endsWith("/responses")?new te:null,p=(c,d,h,b,v,f,y,R)=>{if(!o||!h)return;let W=o,
122
- V=h,S=Ve(d,f);if(!S){E(`gateway-sin-modelo:${v}`,`[bvsala gateway] no se pudo leer el modelo del cuerpo de ${v} (content-encoding: ${f??"ninguno"}); su uso se reenv\xEDa pero no se mide.`);return}let T=Ue(
123
- S,h);T?(o.record(b?Ke(c,S,T,y):qe(c,S,T,y,R)),r(`[gateway] POST ${v} ${b?"\xB7 COALESCIDA (llamada evitada)":""} \xB7 ${S} \xB7 $${T.costeUsd.toFixed(6)} (in ${T.tokens.entrada}, cache\u2191${T.tokens.
124
- cacheEscrita}${T.tokens.cacheEscrita1h?` (1h ${T.tokens.cacheEscrita1h})`:""} cache\u2193${T.tokens.cacheLeida}, out ${T.tokens.salida})`+(R?` \xB7 elisi\xF3n: ${R.borrados} borrado(s), ${R.tokensLimpiados}\
125
- tok limpiados por el proveedor`:"")),i&&!b&&v==="/v1/messages"&&setImmediate(()=>{try{let L=he(d,f);if(!L||typeof L!="object")return;let _=i.observar({cuerpo:L,uso:V,model:S,at:Date.now(),...y?.sessionId!==
126
- void 0?{sessionId:y.sessionId}:{},...y?.agentId!==void 0?{agentId:y.agentId}:{}});if(!_)return;W.record(He(`${c}:shadow`,S,_.baselineUsd,_.politicaUsd,y)),r(`[gateway] sombra \xB7 ${S} \xB7 baseline $${_.
127
- baselineUsd.toFixed(6)} \u2192 v0 $${_.politicaUsd.toFixed(6)}`);}catch{}})):E(`gateway-sin-precio:${S}`,`[bvsala gateway] el modelo "${S}" no est\xE1 en el cat\xE1logo de precios; su uso se reenv\xEDa pero no \
128
- se mide.`);},m=createServer(async(c,d)=>{let h=randomUUID(),b=new AbortController;d.on("close",()=>{d.writableEnded||b.abort();});let v=null,f=new URL(c.url??"/",t),y=null,R=Buffer.alloc(0),W=false,V=c.headers["content-enco\
129
- ding"],S=Array.isArray(V)?V[0]:V,T=I=>{let w=Array.isArray(I)?I[0]:I;return w!==void 0&&/^[A-Za-z0-9._:/-]{1,128}$/.test(w)?w:void 0},L=T(c.headers["x-claude-code-session-id"]),_=T(c.headers["x-claude\
130
- -code-agent-id"]),G=L!==void 0||_!==void 0?{...L!==void 0?{sessionId:L}:{},..._!==void 0?{agentId:_}:{}}:void 0;try{let I=[];for await(let g of c)I.push(g);let w=Buffer.concat(I);R=w,f=new URL(c.url??
131
- "/",t);let Y=s!==null&&c.method==="POST"&&w.length>0,Ct=rt(g=>{let x=c.headers[g];return Array.isArray(x)?x.join(", "):x}),le=Y?ot("POST",f.pathname+f.search,w,Ct):"";if(Y)if(s.tieneEnVuelo(le)){let g=await s.
132
- esperar(le);if(g){d.writeHead(g.status,g.headers);let x=u(f.pathname)??new $;for(let Me of g.chunks)d.write(Me),x.observar(Me);d.end();let Et=x.usage()??(f.pathname==="/v1/messages"?be(Buffer.concat(g.
133
- chunks)):null);p(h,w,Et,!0,f.pathname,S,G);return}}else v=s.registrar(le);let Q={};for(let[g,x]of Object.entries(c.headers))g==="host"||g==="content-length"||x===void 0||(Q[g]=Array.isArray(x)?x.join(
134
- ", "):x);let Oe=w;if(a!==null&&c.method==="POST"&&f.pathname==="/v1/messages"&&a.tiene("context_elision"))try{let g=tt(w,S);g!==null&&(Oe=g,Q["anthropic-beta"]=nt(Q["anthropic-beta"]));}catch{}let C;try{
135
- C=await n(f,{method:c.method,headers:Q,body:["GET","HEAD"].includes(c.method??"")?void 0:Oe,redirect:"manual",signal:b.signal});}catch(g){v?.abortar(),d.headersSent||(d.writeHead(502,{"content-type":"a\
136
- pplication/json"}),d.end(JSON.stringify({error:"bvsala gateway: upstream unreachable",detail:String(g)}))),r(`[gateway] ${c.method} ${f.pathname} \u2192 upstream inalcanzable: ${String(g)}`);return}let ue=Object.
137
- fromEntries(C.headers.entries());for(let g of rn)delete ue[g];d.writeHead(C.status,ue);let De=C.headers.get("content-type")??"",de=De.includes("text/event-stream")||De===""&&C.ok&&u(f.pathname)!==null;
138
- y=de?u(f.pathname):null;let F=!de&&C.ok&&o!==void 0&&c.method==="POST"&&f.pathname==="/v1/messages"&&(C.headers.get("content-type")??"").includes("application/json")?[]:null,Le=0;if(C.body)for await(let g of C.
139
- body){let x=Buffer.from(g);d.write(x),y?.observar(x),F&&(Le+=x.length,Le>ve?F=null:F.push(x)),v?.capturar(x);}if(d.end(),v?.terminar(C.status,ue),y&&C.ok){W=!0;let g=y instanceof $?y.elision():null;p(h,
140
- w,y.usage(),!1,f.pathname,S,G,g);}else if(F){let g=Buffer.concat(F);p(h,w,be(g),!1,f.pathname,S,G,Be(g));}else de||r(`[gateway] ${c.method} ${f.pathname} \u2192 ${C.status}`);}catch(I){if(v?.abortar(),b.
141
- signal.aborted){let w=!W&&y?y.usageFinal():null;if(w){r(`[gateway] ${c.method} ${f.pathname} \u2192 el cliente cerr\xF3 tras el usage final; se mide igual`);let Y=y instanceof $?y.elision():null;p(h,R,
142
- w,false,f.pathname,S,G,Y);}else r(`[gateway] ${c.method} ${f.pathname} \u2192 el cliente abort\xF3; upstream cancelado`);}else if(r(`[gateway] ${c.method} ${f.pathname} \u2192 error sirviendo: ${String(I)}`),
143
- !d.headersSent){d.writeHead(502,{"content-type":"application/json"}),d.end(JSON.stringify({error:"bvsala gateway: stream interrupted",detail:String(I)}));return}d.writableEnded||d.end();}});return m.on(
144
- "upgrade",(c,d)=>{r(`[gateway] ${c.method} ${new URL(c.url??"/","http://x").pathname} \u2192 426 (WebSocket no soportado; el cliente cae a HTTP)`),d.once("error",()=>{}),d.once("finish",()=>d.destroy()),
145
- d.end(`HTTP/1.1 426 Upgrade Required\r
126
+ `).update(o).update(`
127
+ `).update(n).digest("hex")}function Et(e){return In.map(t=>`${t}=${e(t)??""}`).join(`
128
+ `)}var me=class{enVuelo=new Map;primarias=0;gemelas=0;registrar(t){if(this.enVuelo.has(t))return null;this.primarias+=1;let n,o=new Promise(a=>n=a);this.enVuelo.set(t,{promesa:o,resolver:n});let r=[],
129
+ s=0,i=false;return {capturar:a=>{if(!i){if(s+=a.length,s>De){i=true,r.length=0;return}r.push(a);}},terminar:(a,l)=>{let d=!i&&a>=200&&a<300;this.enVuelo.get(t)?.resolver(d?{status:a,headers:l,chunks:r}:null),
130
+ this.enVuelo.delete(t);},abortar:()=>{this.enVuelo.get(t)?.resolver(null),this.enVuelo.delete(t);}}}async esperar(t){let n=this.enVuelo.get(t);if(!n)return null;let o=await n.promesa;return o&&(this.gemelas+=
131
+ 1),o}tieneEnVuelo(t){return this.enVuelo.has(t)}};var Dn=["content-encoding","content-length","transfer-encoding"];async function Ct(e={}){let t=(e.upstream??"https://api.anthropic.com").replace(/\/+$/,""),n=e.fetchImpl??fetch,o=e.log??(u=>console.log(
132
+ u)),r;if(e.serviceAccountKey){r=new U({url:e.meteringUrl??"https://savings.bivelio.com/api/metering/usage",serviceAccountKey:e.serviceAccountKey,...e.fetchImpl?{fetchImpl:e.fetchImpl}:{},onAuthError:p=>A(
133
+ "gateway-ingest-auth",`[bvsala gateway] la ingesta de uso rechaza la credencial (${p}). El tr\xE1fico sigue fluyendo (avisar, nunca romper), pero este uso no est\xE1 llegando al panel. Revisa BIVELIO_SERVIC\
134
+ E_KEY y el estado de la suscripci\xF3n en savings.bivelio.com.`)});let u=ie();e.seatId?r.setSeat(e.seatId,u):ae(e.serviceAccountKey).then(p=>r?.setSeat(p,u)).catch(()=>{}),r.start();}else A("gateway-si\
135
+ n-clave","[bvsala gateway] sin BIVELIO_SERVICE_KEY: el gateway reenv\xEDa el tr\xE1fico pero NO mide. Consigue tu clave en savings.bivelio.com/dashboard/install para ver el gasto en tu panel.");let s=e.
136
+ coalescer?new me:null,i=e.sombra&&r?new ue:null,a=new pe,l=e.elision!==false&&e.serviceAccountKey?new de({url:new URL("/api/org/entitlements",e.meteringUrl??"https://savings.bivelio.com/api/metering/usag\
137
+ e").toString(),serviceAccountKey:e.serviceAccountKey,...e.fetchImpl?{fetchImpl:e.fetchImpl}:{},log:o}):null,d=u=>u==="/v1/messages"?new N:u.endsWith("/responses")?new ce:null,m=(u,p,g,y,k,b,x,M,ee)=>{
138
+ if(!r||!g)return;let q=r,L=g,E=ct(p,b);if(!E){A(`gateway-sin-modelo:${k}`,`[bvsala gateway] no se pudo leer el modelo del cuerpo de ${k} (content-encoding: ${b??"ninguno"}); su uso se reenv\xEDa pero no \
139
+ se mide.`);return}let T=at(E,g);T?(r.record(y?dt(u,E,T,x):ut(u,E,T,x,M,ee)),o(`[gateway] POST ${k} ${y?"\xB7 COALESCIDA (llamada evitada)":""} \xB7 ${E} \xB7 $${T.costeUsd.toFixed(6)} (in ${T.tokens.entrada}\
140
+ , cache\u2191${T.tokens.cacheEscrita}${T.tokens.cacheEscrita1h?` (1h ${T.tokens.cacheEscrita1h})`:""} cache\u2193${T.tokens.cacheLeida}, out ${T.tokens.salida})`+(M?` \xB7 elisi\xF3n: ${M.borrados} bo\
141
+ rrado(s), ${M.tokensLimpiados} tok limpiados por el proveedor`:"")),i&&!y&&k==="/v1/messages"&&setImmediate(()=>{try{let $=Ce(p,b);if(!$||typeof $!="object")return;let R=i.observar({cuerpo:$,uso:L,model:E,
142
+ at:Date.now(),...x?.sessionId!==void 0?{sessionId:x.sessionId}:{},...x?.agentId!==void 0?{agentId:x.agentId}:{}});if(!R)return;q.record(pt(`${u}:shadow`,E,R.baselineUsd,R.politicaUsd,x)),o(`[gateway] \
143
+ sombra \xB7 ${E} \xB7 baseline $${R.baselineUsd.toFixed(6)} \u2192 v0 $${R.politicaUsd.toFixed(6)}`);}catch{}})):A(`gateway-sin-precio:${E}`,`[bvsala gateway] el modelo "${E}" no est\xE1 en el cat\xE1logo de\
144
+ precios; su uso se reenv\xEDa pero no se mide.`);},c=createServer(async(u,p)=>{let g=randomUUID(),y=new AbortController;p.on("close",()=>{p.writableEnded||y.abort();});let k=null,b=new URL(u.url??"/",t),x=null,M=Buffer.
145
+ alloc(0),ee=false,q=u.headers["content-encoding"],L=Array.isArray(q)?q[0]:q,E=I=>{let w=Array.isArray(I)?I[0]:I;return w!==void 0&&/^[A-Za-z0-9._:/-]{1,128}$/.test(w)?w:void 0},T=E(u.headers["x-claude-co\
146
+ de-session-id"]),$=E(u.headers["x-claude-code-agent-id"]),R=T!==void 0||$!==void 0?{...T!==void 0?{sessionId:T}:{},...$!==void 0?{agentId:$}:{}}:void 0;try{let I=[];for await(let h of u)I.push(h);let w=Buffer.
147
+ concat(I);M=w,b=new URL(u.url??"/",t);let te=s!==null&&u.method==="POST"&&w.length>0,Jt=Et(h=>{let v=u.headers[h];return Array.isArray(v)?v.join(", "):v}),ye=te?Tt("POST",b.pathname+b.search,w,Jt):"";
148
+ if(te)if(s.tieneEnVuelo(ye)){let h=await s.esperar(ye);if(h){p.writeHead(h.status,h.headers);let v=d(b.pathname)??new N;for(let W of h.chunks)p.write(W),v.observar(W);p.end();let J=v.usage()??(b.pathname===
149
+ "/v1/messages"?Ae(Buffer.concat(h.chunks)):null);m(g,w,J,!0,b.pathname,L,R);return}}else k=s.registrar(ye);let ne={};for(let[h,v]of Object.entries(u.headers))h==="host"||h==="content-length"||v===void 0||
150
+ (ne[h]=Array.isArray(v)?v.join(", "):v);let K=w;if(l!==null&&u.method==="POST"&&b.pathname==="/v1/messages"&&l.tiene("context_elision"))try{let h=et(w,L);h!==null&&(K=h,ne["anthropic-beta"]=nt(ne["ant\
151
+ hropic-beta"]));}catch{}let ke=null;if(l!==null&&u.method==="POST"&&b.pathname==="/v1/messages"&&l.tiene("cache_ttl_tuning"))try{let v=Oe(K,K===w?L:"identity");if(v!==null){let J=kt(v),W=`${R?.sessionId??
152
+ "sin-sesion"}:${J.system}`,Qe=Date.now(),Wt=a.ultima(W,Qe);if(a.anotar(W,J,Qe),St({fraccionNueva:xt(Wt,J)})){let oe=wt(v);oe!==null&&(K=oe.cuerpo,ke={rebajadas:oe.rebajadas,yaEran5m:oe.yaEran5m});}}}catch{}
153
+ let C;try{C=await n(b,{method:u.method,headers:ne,body:["GET","HEAD"].includes(u.method??"")?void 0:K,redirect:"manual",signal:y.signal});}catch(h){k?.abortar(),p.headersSent||(p.writeHead(502,{"conten\
154
+ t-type":"application/json"}),p.end(JSON.stringify({error:"bvsala gateway: upstream unreachable",detail:String(h)}))),o(`[gateway] ${u.method} ${b.pathname} \u2192 upstream inalcanzable: ${String(h)}`);
155
+ return}let xe=Object.fromEntries(C.headers.entries());for(let h of Dn)delete xe[h];p.writeHead(C.status,xe);let Ge=C.headers.get("content-type")??"",Se=Ge.includes("text/event-stream")||Ge===""&&C.ok&&
156
+ d(b.pathname)!==null;x=Se?d(b.pathname):null;let H=!Se&&C.ok&&r!==void 0&&u.method==="POST"&&b.pathname==="/v1/messages"&&(C.headers.get("content-type")??"").includes("application/json")?[]:null,Ye=0;
157
+ if(C.body)for await(let h of C.body){let v=Buffer.from(h);p.write(v),x?.observar(v),H&&(Ye+=v.length,Ye>De?H=null:H.push(v)),k?.capturar(v);}if(p.end(),k?.terminar(C.status,xe),x&&C.ok){ee=!0;let h=x instanceof
158
+ N?x.elision():null;m(g,w,x.usage(),!1,b.pathname,L,R,h,ke);}else if(H){let h=Buffer.concat(H);m(g,w,Ae(h),!1,b.pathname,L,R,it(h),ke);}else Se||o(`[gateway] ${u.method} ${b.pathname} \u2192 ${C.status}`);}catch(I){
159
+ if(k?.abortar(),y.signal.aborted){let w=!ee&&x?x.usageFinal():null;if(w){o(`[gateway] ${u.method} ${b.pathname} \u2192 el cliente cerr\xF3 tras el usage final; se mide igual`);let te=x instanceof N?x.
160
+ elision():null;m(g,M,w,false,b.pathname,L,R,te);}else o(`[gateway] ${u.method} ${b.pathname} \u2192 el cliente abort\xF3; upstream cancelado`);}else if(o(`[gateway] ${u.method} ${b.pathname} \u2192 error sirvie\
161
+ ndo: ${String(I)}`),!p.headersSent){p.writeHead(502,{"content-type":"application/json"}),p.end(JSON.stringify({error:"bvsala gateway: stream interrupted",detail:String(I)}));return}p.writableEnded||p.
162
+ end();}});return c.on("upgrade",(u,p)=>{o(`[gateway] ${u.method} ${new URL(u.url??"/","http://x").pathname} \u2192 426 (WebSocket no soportado; el cliente cae a HTTP)`),p.once("error",()=>{}),p.once("f\
163
+ inish",()=>p.destroy()),p.end(`HTTP/1.1 426 Upgrade Required\r
146
164
  connection: close\r
147
165
  content-length: 0\r
148
166
  \r
149
- `);}),await new Promise((c,d)=>{m.once("error",d),m.listen(e.puerto??8402,"127.0.0.1",()=>c());}),{puerto:m.address().port,cerrar:async()=>{await o?.stopAndDrain(),await new Promise(c=>m.close(()=>c()));}}}var ye=["claude","codex","goose","qwen"];function at(e){return ye.includes(e??"")}function ct(e,t={}){let n=t.path??process.env.PATH??"",r=t.
150
- existe??existsSync,o=null;for(let s of n.split(";").filter(i=>i.length>0)){for(let i of [".exe",".com"]){let a=join(s,e+i);if(r(a))return {tipo:"exe",ruta:a}}if(o===null)for(let i of [".cmd",".bat"]){let a=join(s,e+
151
- i);if(r(a)){o=a;break}}}return o!==null?{tipo:"solo-shim",ruta:o}:{tipo:"no-encontrado"}}function lt(e={}){let n=(e.env??process.env).BVSALA_CODEX_AUTH?.toLowerCase();if(n==="api-key"||n==="apikey")return "\
152
- api-key";if(n==="chatgpt")return "chatgpt";let r=null;try{r=e.leerAuth?e.leerAuth():null;}catch{r=null;}if(r===null)return "api-key";try{let o=JSON.parse(r);return typeof o.auth_mode=="string"?o.auth_mode.
153
- toLowerCase().replace(/[^a-z]/g,"")==="apikey"?"api-key":"chatgpt":o.tokens!==void 0&&o.tokens!==null?"chatgpt":"api-key"}catch{return "api-key"}}var an={"api-key":{upstream:"https://api.openai.com",prefijo:"\
154
- /v1"},chatgpt:{upstream:"https://chatgpt.com",prefijo:"/backend-api/codex"}};function ke(e,t,n,r={}){let o=`http://127.0.0.1:${t}`;switch(e){case "claude":return {bin:"claude",args:n,env:{ANTHROPIC_BASE_URL:o}};case "\
155
- goose":return {bin:"goose",args:n,env:{ANTHROPIC_HOST:o}};case "qwen":return {bin:"qwen",args:n,env:{ANTHROPIC_BASE_URL:o},nota:'Qwen Code solo enruta por aqu\xED con `security.auth.selectedType: "anthropic\
156
- "` en ~/.qwen/settings.json (ver `bvsala doctor`).'};case "codex":{let s=r.modoCodex??"api-key",i=an[s];return {bin:"codex",args:["-c",`openai_base_url="${o}${i.prefijo}"`,...n],env:{},upstream:i.upstream,
167
+ `);}),await new Promise((u,p)=>{c.once("error",p),c.listen(e.puerto??8402,"127.0.0.1",()=>u());}),{puerto:c.address().port,cerrar:async()=>{await r?.stopAndDrain(),await new Promise(u=>c.close(()=>u()));}}}var Le=["claude","codex","goose","qwen"];function At(e){return Le.includes(e??"")}function _t(e,t={}){let n=t.path??process.env.PATH??"",o=t.
168
+ existe??existsSync,r=null;for(let s of n.split(";").filter(i=>i.length>0)){for(let i of [".exe",".com"]){let a=join(s,e+i);if(o(a))return {tipo:"exe",ruta:a}}if(r===null)for(let i of [".cmd",".bat"]){let a=join(s,e+
169
+ i);if(o(a)){r=a;break}}}return r!==null?{tipo:"solo-shim",ruta:r}:{tipo:"no-encontrado"}}function It(e={}){let n=(e.env??process.env).BVSALA_CODEX_AUTH?.toLowerCase();if(n==="api-key"||n==="apikey")return "\
170
+ api-key";if(n==="chatgpt")return "chatgpt";let o=null;try{o=e.leerAuth?e.leerAuth():null;}catch{o=null;}if(o===null)return "api-key";try{let r=JSON.parse(o);return typeof r.auth_mode=="string"?r.auth_mode.
171
+ toLowerCase().replace(/[^a-z]/g,"")==="apikey"?"api-key":"chatgpt":r.tokens!==void 0&&r.tokens!==null?"chatgpt":"api-key"}catch{return "api-key"}}var Mn={"api-key":{upstream:"https://api.openai.com",prefijo:"\
172
+ /v1"},chatgpt:{upstream:"https://chatgpt.com",prefijo:"/backend-api/codex"}};function Me(e,t,n,o={}){let r=`http://127.0.0.1:${t}`;switch(e){case "claude":return {bin:"claude",args:n,env:{ANTHROPIC_BASE_URL:r}};case "\
173
+ goose":return {bin:"goose",args:n,env:{ANTHROPIC_HOST:r}};case "qwen":return {bin:"qwen",args:n,env:{ANTHROPIC_BASE_URL:r},nota:'Qwen Code solo enruta por aqu\xED con `security.auth.selectedType: "anthropic\
174
+ "` en ~/.qwen/settings.json (ver `bvsala doctor`).'};case "codex":{let s=o.modoCodex??"api-key",i=Mn[s];return {bin:"codex",args:["-c",`openai_base_url="${r}${i.prefijo}"`,...n],env:{},upstream:i.upstream,
157
175
  nota:s==="chatgpt"?"Auth ChatGPT detectada: el gateway enruta a chatgpt.com/backend-api/codex. El tr\xE1fico de suscripci\xF3n se mide (equivalente a precio de lista) pero no se monetiza: no hay factura por\
158
- tokens.":"Auth por API key: el gateway enruta a api.openai.com/v1."}}}}var dn="comprobar: en el log del gateway debe aparecer `[gateway] POST /v1/messages \u2026`; si ve\
159
- s `/v1/v1/messages`, sobra un /v1; si ves `POST /messages` a secas, falta uno.",pn=[{id:"claude",nombre:"Claude Code",binario:"claude",configs:[],detectable:true,receta:({base:e})=>["usa `bvsala claude`\
176
+ tokens.":"Auth por API key: el gateway enruta a api.openai.com/v1."}}}}function $n(e){let t=Number.parseInt(e.slice(8,10),10);return Number.isFinite(t)&&t%2===0?"palanca":"control"}function Pt(e){let t;try{t=JSON.parse(e());}catch{return null}if(typeof t!="object"||t===null)
177
+ return null;let n=t,o=n.espia;return typeof o!="number"||!Number.isInteger(o)||o<1||o>65535?null:{activo:n.activo!==false,espia:o}}function Ot(e){let{enrolamiento:t,espiaVivo:n,upstreamEnv:o,elisionEnv:r,
178
+ hoyUtcIso:s}=e;if(!t)return {linea:"",aviso:false};if(!t.activo)return {linea:"anillo 2: enrolamiento en pausa (activo:false)",aviso:false};if(!n)return {linea:`anillo 2: enrolado pero el esp\xEDa NO escucha en :${t.
179
+ espia} \u2014 NO encadeno (el tr\xE1fico de hoy no entra en el corpus). Arr\xE1ncalo con \`pnpm anillo2:espia\`.`,aviso:true};let i=$n(s),a=`http://127.0.0.1:${t.espia}`,l=o!==void 0&&o!=="",d=r!==void 0&&
180
+ r!=="",m=[];return m.push(`anillo 2: ${s} UTC \u2192 brazo ${i.toUpperCase()}`),m.push(l?`upstream respetado del entorno (${o})`:`encadenado a :${t.espia}`),d&&m.push(`elisi\xF3n respetada del entorno (=${r}\
181
+ )`),{...l?{}:{upstream:a},...d?{}:{elision:i==="palanca"?"1":"0"},brazo:i,linea:m.join(", "),aviso:false}}var Bn="comprobar: en el log del gateway debe aparecer `[gateway] POST /v1/messages \u2026`; si ve\
182
+ s `/v1/v1/messages`, sobra un /v1; si ves `POST /messages` a secas, falta uno.",Un=[{id:"claude",nombre:"Claude Code",binario:"claude",configs:[],detectable:true,receta:({base:e})=>["usa `bvsala claude`\
160
183
  \u2014 arranca el gateway en un puerto ef\xEDmero, lanza `claude` apunt\xE1ndole y lo apaga al salir.",`a mano: ANTHROPIC_BASE_URL=${e} claude (sin /v1: el cliente a\xF1ade /v1/messages)`]},{id:"co\
161
184
  dex",nombre:"Codex CLI",binario:"codex",configs:[join(".codex","config.toml"),join(".codex","auth.json")],detectable:true,receta:({base:e,rutas:t})=>["usa `bvsala codex` \u2014 el prefijo del base URL depende del \
162
185
  modo de auth y lo resuelve el envoltorio:",` API key \u2192 openai_base_url=${e}/v1`,` suscripci\xF3n ChatGPT \u2192 openai_base_url=${e}/backend-api/codex (tiene que terminar exactament\
@@ -172,40 +195,41 @@ Droid (Factory)",binario:"droid",configs:[join(".factory","settings.json")],dete
172
195
  idar en mano contra el log del gateway].`,"{",' "customModels": ['," {",' "model": "<id de modelo Anthropic>",',' "displayName": "<nombre visible>",',' "provider": "anthropic",',` \
173
196
  "baseUrl": "${e}",`,' "apiKey": "<tu API key de Anthropic>"'," }"," ]","}"]},{id:"cline",nombre:"Cline",configs:[],detectable:false,receta:({baseV1:e})=>["mecanismo: UI \u2192 proveedor Anthropic\
174
197
  \u2192 marca \xABUse custom base URL\xBB. CON /v1 (Cline fija https://api.anthropic.com/v1 y solo normaliza la URL oficial exacta).",`Base URL: ${e}`]},{id:"kilo",nombre:"Kilo Code",configs:[],detectable:false,
175
- receta:({baseV1:e})=>["mecanismo: UI \u2192 proveedor custom, Provider API \xABAnthropic Messages\xBB. Probar CON /v1 primero (linaje Cline) [inferido: validar en mano].",`Base URL: ${e}`]}];function mn(e,t){
176
- let n=e.split(delimiter).filter(o=>o.length>0),r=process.platform==="win32"?["",".exe",".cmd",".bat"]:[""];return o=>n.some(s=>r.some(i=>t(join(s,o+i))))}async function ut(e,t={}){if(!Number.isInteger(e)||e<1||
177
- e>65535)throw new RangeError(`[bvsala doctor] puerto inv\xE1lido: ${String(e)}`);let n=t.home??homedir(),r=t.existe??existsSync,o=t.enPath??mn(t.path??process.env.PATH??"",r),s=`http://127.0.0.1:${e}`,i=`${s}/v1`,
178
- a=[],u=[`bvsala doctor \u2014 gateway local en ${s}`,"Solo imprime: no escribe ninguna configuraci\xF3n. Detecci\xF3n por existencia (binarios en PATH y","archivos de configuraci\xF3n de usuario); nunca \
179
- se lee el contenido de ning\xFAn archivo.",""];for(let p of pn){let m=p.configs.map(b=>join(n,b)),l=p.binario!==void 0&&o(p.binario),c=m.filter(b=>r(b)),d=l||c.length>0;d&&a.push(p.id);let h;p.detectable?
180
- d?h=`detectado \u2014 ${[...l?[`binario \`${p.binario}\` en PATH`]:[],...c.map(v=>`config presente: ${v}`)].join("; ")}`:h="no detectado":h="sin detecci\xF3n autom\xE1tica (extensi\xF3n de editor)",u.
181
- push(`\xBB ${p.id}: ${h}`),u.push(` ${p.nombre}`);for(let b of p.receta({base:s,baseV1:i,rutas:m}))u.push(` ${b}`);u.push(` ${dn}`),u.push("");}return u.push("Regla BYOK: las recetas del anillo Anth\
198
+ receta:({baseV1:e})=>["mecanismo: UI \u2192 proveedor custom, Provider API \xABAnthropic Messages\xBB. Probar CON /v1 primero (linaje Cline) [inferido: validar en mano].",`Base URL: ${e}`]}];function Vn(e,t){
199
+ let n=e.split(delimiter).filter(r=>r.length>0),o=process.platform==="win32"?["",".exe",".cmd",".bat"]:[""];return r=>n.some(s=>o.some(i=>t(join(s,r+i))))}async function Dt(e,t={}){if(!Number.isInteger(e)||e<1||
200
+ e>65535)throw new RangeError(`[bvsala doctor] puerto inv\xE1lido: ${String(e)}`);let n=t.home??homedir(),o=t.existe??existsSync,r=t.enPath??Vn(t.path??process.env.PATH??"",o),s=`http://127.0.0.1:${e}`,i=`${s}/v1`,
201
+ a=[],l=[`bvsala doctor \u2014 gateway local en ${s}`,"Solo imprime: no escribe ninguna configuraci\xF3n. Detecci\xF3n por existencia (binarios en PATH y","archivos de configuraci\xF3n de usuario); nunca \
202
+ se lee el contenido de ning\xFAn archivo.",""];for(let d of Un){let m=d.configs.map(g=>join(n,g)),c=d.binario!==void 0&&r(d.binario),f=m.filter(g=>o(g)),u=c||f.length>0;u&&a.push(d.id);let p;d.detectable?
203
+ u?p=`detectado \u2014 ${[...c?[`binario \`${d.binario}\` en PATH`]:[],...f.map(y=>`config presente: ${y}`)].join("; ")}`:p="no detectado":p="sin detecci\xF3n autom\xE1tica (extensi\xF3n de editor)",l.
204
+ push(`\xBB ${d.id}: ${p}`),l.push(` ${d.nombre}`);for(let g of d.receta({base:s,baseV1:i,rutas:m}))l.push(` ${g}`);l.push(` ${Bn}`),l.push("");}return l.push("Regla BYOK: las recetas del anillo Anth\
182
205
  ropic (Goose, Qwen Code, opencode, Crush, Droid, Cline, Kilo) son","para API key. Nunca enrutes por el gateway el OAuth de una suscripci\xF3n Claude Pro/Max desde un harness","de terceros \u2014 Anthropic \
183
- lo proh\xEDbe. Claude Code y Codex con suscripci\xF3n se enrutan y se miden, pero no","se monetizan: no hay factura por tokens.","Detalle por terminal: docs/terminales/<terminal>.md"),{texto:u.join(`
184
- `),detectados:a}}var dt="savings-mode";function pt(e,t){for(let n of e){let r=join(n,"skills",dt,"SKILL.md");if(t.existe(r))return r}return null}var mt="<!-- bvsala:savings-mode:inicio -->",ie="\
185
- <!-- bvsala:savings-mode:fin -->";function fn(e){let t=e.replace(/^---\n[\s\S]*?\n---\n*/,"").trim();return `${mt}
206
+ lo proh\xEDbe. Claude Code y Codex con suscripci\xF3n se enrutan y se miden, pero no","se monetizan: no hay factura por tokens.","Detalle por terminal: docs/terminales/<terminal>.md"),{texto:l.join(`
207
+ `),detectados:a}}var Lt="savings-mode";function Mt(e,t){for(let n of e){let o=join(n,"skills",Lt,"SKILL.md");if(t.existe(o))return o}return null}var $t="<!-- bvsala:savings-mode:inicio -->",fe="\
208
+ <!-- bvsala:savings-mode:fin -->";function Fn(e){let t=e.replace(/^---\n[\s\S]*?\n---\n*/,"").trim();return `${$t}
186
209
  ${t}
187
210
 
188
211
  _Always on (AGENTS.md has no activation step). Delete this block to turn it off; \`bvsala skill --codex --forzar\` restores it._
189
- ${ie}`}function ft(e){let t=pt(e.origenes,e.fs);if(!t)return {ok:false,destino:"",mensaje:`[bvsala skill] no encuentro el SKILL.md empaquetado (ra\xEDces probadas: ${e.origenes.join(", ")})`};let n=fn(e.fs.
190
- leer(t)),r=e.proyecto?e.cwd:join(e.home,".codex"),o=join(r,"AGENTS.md");if(!e.fs.existe(o))return e.fs.crearDir(r),e.fs.escribir(o,n+`
191
- `),{ok:true,destino:o,mensaje:xe(o,"instalado")};let s=e.fs.leer(o),i=s.indexOf(mt),a=s.indexOf(ie);return i===-1||a===-1||a<i?(e.fs.escribir(o,s.trimEnd()+`
212
+ ${fe}`}function jt(e){let t=Mt(e.origenes,e.fs);if(!t)return {ok:false,destino:"",mensaje:`[bvsala skill] no encuentro el SKILL.md empaquetado (ra\xEDces probadas: ${e.origenes.join(", ")})`};let n=Fn(e.fs.
213
+ leer(t)),o=e.proyecto?e.cwd:join(e.home,".codex"),r=join(o,"AGENTS.md");if(!e.fs.existe(r))return e.fs.crearDir(o),e.fs.escribir(r,n+`
214
+ `),{ok:true,destino:r,mensaje:$e(r,"instalado")};let s=e.fs.leer(r),i=s.indexOf($t),a=s.indexOf(fe);return i===-1||a===-1||a<i?(e.fs.escribir(r,s.trimEnd()+`
192
215
 
193
216
  `+n+`
194
- `),{ok:true,destino:o,mensaje:xe(o,"a\xF1adido al AGENTS.md existente")}):s.slice(i,a+ie.length)===n?{ok:true,destino:o,mensaje:`[bvsala skill] ya instalado y al d\xEDa: ${o}`}:e.forzar?(e.fs.escribir(o,s.
195
- slice(0,i)+n+s.slice(a+ie.length)),{ok:true,destino:o,mensaje:xe(o,"bloque actualizado")}):{ok:false,destino:o,mensaje:`[bvsala skill] el bloque savings-mode de ${o} tiene contenido DISTINTO \u2014 no lo piso; \
196
- usa --forzar para actualizarlo`}}function xe(e,t){return `[bvsala skill] ${t}: ${e}
217
+ `),{ok:true,destino:r,mensaje:$e(r,"a\xF1adido al AGENTS.md existente")}):s.slice(i,a+fe.length)===n?{ok:true,destino:r,mensaje:`[bvsala skill] ya instalado y al d\xEDa: ${r}`}:e.forzar?(e.fs.escribir(r,s.
218
+ slice(0,i)+n+s.slice(a+fe.length)),{ok:true,destino:r,mensaje:$e(r,"bloque actualizado")}):{ok:false,destino:r,mensaje:`[bvsala skill] el bloque savings-mode de ${r} tiene contenido DISTINTO \u2014 no lo piso; \
219
+ usa --forzar para actualizarlo`}}function $e(e,t){return `[bvsala skill] ${t}: ${e}
197
220
  [bvsala skill] AGENTS.md va SIEMPRE activo en Codex (no hay paso de activaci\xF3n); borra el bloque para apagarlo.
198
- [bvsala skill] para medir su efecto: trabaja unos d\xEDas con \xE9l y otros sin \xE9l bajo \`bvsala codex\`, y compara en el panel.`}function ht(e){let t=pt(e.origenes,e.fs);if(!t)return {ok:false,destino:"",
199
- mensaje:`[bvsala skill] no encuentro el SKILL.md empaquetado (ra\xEDces probadas: ${e.origenes.join(", ")})`};let n=e.proyecto?join(e.cwd,".claude","skills"):join(e.home,".claude","skills"),r=join(n,dt),o=join(r,
200
- "SKILL.md"),s=e.fs.leer(t);if(e.fs.existe(o)&&!e.forzar){let i=e.fs.leer(o)===s;return {ok:i,destino:o,mensaje:i?`[bvsala skill] ya instalado y al d\xEDa: ${o}`:`[bvsala skill] ya existe ${o} con conte\
201
- nido DISTINTO \u2014 no lo piso; usa --forzar para sobrescribir`}}return e.fs.crearDir(r),e.fs.escribir(o,s),{ok:true,destino:o,mensaje:`[bvsala skill] instalado: ${o}
221
+ [bvsala skill] para medir su efecto: trabaja unos d\xEDas con \xE9l y otros sin \xE9l bajo \`bvsala codex\`, y compara en el panel.`}function Nt(e){let t=Mt(e.origenes,e.fs);if(!t)return {ok:false,destino:"",
222
+ mensaje:`[bvsala skill] no encuentro el SKILL.md empaquetado (ra\xEDces probadas: ${e.origenes.join(", ")})`};let n=e.proyecto?join(e.cwd,".claude","skills"):join(e.home,".claude","skills"),o=join(n,Lt),r=join(o,
223
+ "SKILL.md"),s=e.fs.leer(t);if(e.fs.existe(r)&&!e.forzar){let i=e.fs.leer(r)===s;return {ok:i,destino:r,mensaje:i?`[bvsala skill] ya instalado y al d\xEDa: ${r}`:`[bvsala skill] ya existe ${r} con conte\
224
+ nido DISTINTO \u2014 no lo piso; usa --forzar para sobrescribir`}}return e.fs.crearDir(o),e.fs.escribir(r,s),{ok:true,destino:r,mensaje:`[bvsala skill] instalado: ${r}
202
225
  [bvsala skill] arranca (o reinicia) Claude Code y p\xEDdele \xABsavings mode\xBB \u2014 o deja que se active solo al hablar de l\xEDmites.
203
- [bvsala skill] para medir su efecto de verdad: trabaja unos d\xEDas con \xE9l y otros sin \xE9l bajo \`bvsala claude\`, y compara en el panel.`}}var Se=class{id;exact=false;constructor(t="heuristic"){this.id=t;}count(t){if(t.length===0)return 0;let n=t.match(/[A-Za-z]+|\d+|\s+|[^\sA-Za-z\d]/g)??[],r=0;for(let o of n){let s=o[0];if(/\s/.test(s)){let i=(o.
204
- match(/\n/g)??[]).length;r+=i+Math.floor(Math.max(0,o.length-1)/2);}else /[A-Za-z]/.test(s)?r+=Math.max(1,Math.ceil(o.length/4)):/\d/.test(s)?r+=Math.max(1,Math.ceil(o.length/2)):r+=1;}return Math.max(r,
205
- Math.ceil(t.length/4))}},we=new Se;var Te=class{estimators=new Map;modelToTokenizer=new Map;fallbackId;constructor(t=we){this.fallbackId=t.id,this.estimators.set(t.id,t);}register(t){return this.estimators.set(t.id,t),this}mapModel(t,n){
206
- return this.modelToTokenizer.set(t,n),this}resolve(t){let n=t.tokenizer?this.estimators.get(t.tokenizer):void 0;if(n)return n;if(t.model){let r=this.modelToTokenizer.get(t.model);if(r){let o=this.estimators.
207
- get(r);if(o)return o}}return this.estimators.get(this.fallbackId)}count(t,n){return this.resolve(n).count(t)}};new Te;new TextEncoder;new TextDecoder;new TextDecoder;var An={"gpt-4o-mini":{deltaTokens:-16,salidaDelBrazoA:72,contrato:"triage (6 fields, long enums)",pares:8},"gpt-4o":{deltaTokens:3,salidaDelBrazoA:75,contrato:"triage (6 fields, long enums)",pares:8}};
208
- me(An);var _e="0.4.14";var[,,k,...O]=process.argv;function Nn(){console.log(`bvsala ${_e} \u2014 BiVelio Savings Layer
226
+ [bvsala skill] para medir su efecto de verdad: trabaja unos d\xEDas con \xE9l y otros sin \xE9l bajo \`bvsala claude\`, y compara en el panel.`}}var je=class{id;exact=false;constructor(t="heuristic"){this.id=t;}count(t){if(t.length===0)return 0;let n=t.match(/[A-Za-z]+|\d+|\s+|[^\sA-Za-z\d]/g)??[],o=0;for(let r of n){let s=r[0];if(/\s/.test(s)){let i=(r.
227
+ match(/\n/g)??[]).length;o+=i+Math.floor(Math.max(0,r.length-1)/2);}else /[A-Za-z]/.test(s)?o+=Math.max(1,Math.ceil(r.length/4)):/\d/.test(s)?o+=Math.max(1,Math.ceil(r.length/2)):o+=1;}return Math.max(o,
228
+ Math.ceil(t.length/4))}},Ne=new je;var ze=class{estimators=new Map;modelToTokenizer=new Map;fallbackId;constructor(t=Ne){this.fallbackId=t.id,this.estimators.set(t.id,t);}register(t){return this.estimators.set(t.id,t),this}mapModel(t,n){
229
+ return this.modelToTokenizer.set(t,n),this}resolve(t){let n=t.tokenizer?this.estimators.get(t.tokenizer):void 0;if(n)return n;if(t.model){let o=this.modelToTokenizer.get(t.model);if(o){let r=this.estimators.
230
+ get(o);if(r)return r}}return this.estimators.get(this.fallbackId)}count(t,n){return this.resolve(n).count(t)}};new ze;new TextEncoder;new TextDecoder;new TextDecoder;var so={"gpt-4o-mini":{deltaTokens:-16,salidaDelBrazoA:72,contrato:"triage (6 fields, long enums)",pares:8},"gpt-4o":{deltaTokens:3,salidaDelBrazoA:75,contrato:"triage (6 fields, long enums)",pares:8}};
231
+ Te(so);var Fe="0.4.16";function fo(e,t=300){return new Promise(n=>{let o=connect({port:e,host:"127.0.0.1"}),r=s=>{o.destroy(),n(s);};o.setTimeout(t,()=>r(false)),o.once("connect",()=>r(true)),o.once("error",()=>r(false));})}var[,,S,...D]=process.
232
+ argv;function ho(){console.log(`bvsala ${Fe} \u2014 BiVelio Savings Layer
209
233
 
210
234
  Comandos:
211
235
  gateway [--puerto N] Proxy local medidor (por defecto 8402) para terminales que
@@ -233,34 +257,44 @@ Entorno:
233
257
  BVSALA_GATEWAY_SHADOW =1 enciende el carril sombra de la elisi\xF3n (S2): calcula qu\xE9
234
258
  habr\xEDa ahorrado la pol\xEDtica v0 SIN tocar el tr\xE1fico y lo
235
259
  reporta aparte (jam\xE1s entra en la comisi\xF3n).
236
- BVSALA_GATEWAY_ELISION =1 arma la palanca de diales del proveedor (S4a). Solo se
237
- enciende de verdad si adem\xE1s la licencia de tu organizaci\xF3n
238
- trae el feature context_elision (consulta fail-closed): ajusta
239
- SOLO el bloque context_management de cada petici\xF3n /v1/messages
240
- y el borrado lo hace el propio proveedor. Ante cualquier duda,
241
- la petici\xF3n viaja intacta.
260
+ BVSALA_GATEWAY_ELISION =0 APAGA las palancas del proveedor (S4a), armadas por
261
+ defecto. Cada una se enciende de verdad solo si la licencia de
262
+ tu organizaci\xF3n trae su feature (consulta fail-closed):
263
+ \xB7 context_elision \u2014 ajusta SOLO el bloque context_management
264
+ de cada /v1/messages; el borrado lo hace el proveedor.
265
+ \xB7 cache_ttl_tuning \u2014 rebaja el TTL de escritura de cach\xE9 de
266
+ 1h (2x el precio de entrada) a 5m (1,25x) mientras la sesi\xF3n
267
+ siga caliente. NO toca un solo token que el modelo lea:
268
+ cambia la tarifa, no el contenido. En el corpus del esp\xEDa
269
+ el 99,1 % de los turnos encadena en menos de 5 minutos, y
270
+ ese sobreprecio era el 8,0 % de la factura.
271
+ Ante cualquier duda, la petici\xF3n viaja intacta. (Hasta 0.4.13
272
+ la bandera era al rev\xE9s: \xAB=1 arma\xBB; en un A/B p\xE1sala SIEMPRE
273
+ expl\xEDcita, =1 o =0, y no depender\xE1s de la versi\xF3n instalada.)
242
274
  BVSALA_CODEX_AUTH api-key | chatgpt \u2014 fuerza el modo de auth de Codex.
243
275
  BVSALA_GATEWAY_LOG =1 ense\xF1a el log por petici\xF3n tambi\xE9n dentro de los envoltorios
244
276
  (por defecto va silenciado para no pisar el TUI; mira el panel).
245
277
  CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1 (Claude Code, solo API key) tus modelos en /model.
246
278
 
247
279
  El gateway nunca corta el tr\xE1fico: sin clave o con la ingesta ca\xEDda, reenv\xEDa y avisa.
248
- Tus prompts jam\xE1s salen de tu m\xE1quina \u2014 solo cuentas y coste. M\xE1s: savings.bivelio.com`);}var J=at(k);k!=="gateway"&&k!=="doctor"&&k!=="skill"&&!J&&(Nn(),process.exit(k===void 0||k==="hel\
249
- p"||k==="--help"?0:1));if(k==="skill"){let e=dirname(fileURLToPath(import.meta.url)),t={origenes:[join(e,"..",".."),join(e,"..")],home:homedir(),cwd:process.cwd(),proyecto:O.includes("--proyecto"),forzar:O.includes("--forzar"),
250
- fs:{existe:existsSync,leer:r=>readFileSync(r,"utf8"),escribir:(r,o)=>writeFileSync(r,o),crearDir:r=>mkdirSync(r,{recursive:true})}},n=O.includes("--codex")?ft(t):ht(t);console.log(n.mensaje),process.exit(n.ok?0:1);}var Ae=O.indexOf("--puer\
251
- to"),U=J?0:Ae>=0?Number(O[Ae+1]):8402;(!Number.isInteger(U)||(k==="doctor"?U<1:U<0)||U>65535)&&(console.error(`[bvsala ${k}] puerto inv\xE1lido: ${O[Ae+1]}`),process.exit(1));if(k==="doctor"){O.includes(
252
- "--write")&&(console.error("[bvsala doctor] --write todav\xEDa no existe: el doctor solo imprime; copia el bloque a mano."),process.exit(1));let e=await ut(U);console.log(e.texto),process.exit(0);}var D=J?
253
- ke(k,0,O,{modoCodex:k==="codex"?lt({leerAuth:()=>readFileSync(join(homedir(),".codex","auth.json"),"utf8")}):void 0}):null,Pe=process.env.BIVELIO_SERVICE_KEY,jn=J&&process.env.BVSALA_GATEWAY_LOG!=="1",j=await st({puerto:U,
254
- ...jn?{log:()=>{}}:{},...Pe?{serviceAccountKey:Pe}:{},...process.env.BVSALA_SEAT_ID?{seatId:process.env.BVSALA_SEAT_ID}:{},...process.env.BVSALA_GATEWAY_UPSTREAM?{upstream:process.env.BVSALA_GATEWAY_UPSTREAM}:
255
- D?.upstream?{upstream:D.upstream}:{},...process.env.BVSALA_GATEWAY_COALESCE==="1"?{coalescer:true}:{},...process.env.BVSALA_GATEWAY_SHADOW==="1"?{sombra:true}:{},elision:process.env.BVSALA_GATEWAY_ELISION!==
256
- "0",...process.env.BVSALA_METERING_URL?{meteringUrl:process.env.BVSALA_METERING_URL}:{}}),zn=process.env.BVSALA_GATEWAY_UPSTREAM??D?.upstream??"https://api.anthropic.com";console.log(`[bvsala gateway]\
257
- v${_e} escuchando en http://127.0.0.1:${j.puerto} \u2192 ${zn}`);console.log(`[bvsala gateway] medici\xF3n: ${Pe?"ACTIVA (clave de servicio presente)":"APAGADA (falta BIVELIO_SERVICE_KEY)"}`);process.
258
- env.BVSALA_GATEWAY_UPSTREAM&&D?.upstream&&process.env.BVSALA_GATEWAY_UPSTREAM!==D.upstream&&console.error(`[bvsala ${k}] AVISO: BVSALA_GATEWAY_UPSTREAM=${process.env.BVSALA_GATEWAY_UPSTREAM} pisa el u\
259
- pstream de este terminal (${D.upstream}). Si no es lo que quieres, quita la variable.`);k==="codex"&&!Fe()&&console.error(`[bvsala codex] AVISO: este Node (${process.version}) no descomprime zstd y Co\
260
- dex manda el cuerpo en zstd: el tr\xE1fico pasa pero NO se mide. Usa Node \u2265 22.15.`);if(D&&J){let e=ke(k,j.puerto,O,{...D.upstream?{modoCodex:D.upstream.includes("chatgpt.com")?"chatgpt":"api-key"}:
261
- {}});e.nota&&console.log(`[bvsala ${k}] ${e.nota}`);let t=e.bin;if(process.platform==="win32"){let r=ct(e.bin);r.tipo==="exe"?t=r.ruta:r.tipo==="solo-shim"&&(console.error(`[bvsala ${k}] \`${e.bin}\` e\
262
- st\xE1 instalado como shim de npm (${r.ruta}) y Windows no puede lanzarlo de forma segura con argumentos (CVE-2024-27980). Inst\xE1lalo con su instalador nativo (deja un ${e.bin}.exe en el PATH) o usa\
263
- la receta manual de docs/terminales/.`),await j.cerrar(),process.exit(127));}let n=spawn(t,e.args,{stdio:"inherit",env:{...process.env,...e.env}});n.on("error",r=>{console.error(`[bvsala ${k}] no se pudo\
264
- lanzar \`${e.bin}\`: ${String(r)}. \xBFEst\xE1 instalado y en el PATH?`),j.cerrar().then(()=>process.exit(127));}),n.on("exit",(r,o)=>{j.cerrar().then(()=>process.exit(r??(o?1:0)));});}else console.log(
265
- `[bvsala gateway] apunta tu terminal (o usa \`bvsala ${ye.join("|")}\`): ANTHROPIC_BASE_URL=http://127.0.0.1:${j.puerto} claude \xB7 bvsala doctor para el resto`);var Tt=async()=>{await j.cerrar(),
266
- process.exit(0);};process.on("SIGINT",()=>{Tt();});process.on("SIGTERM",()=>{Tt();});
280
+ Tus prompts jam\xE1s salen de tu m\xE1quina \u2014 solo cuentas y coste. M\xE1s: savings.bivelio.com`);}var Z=At(S);S!=="gateway"&&S!=="doctor"&&S!=="skill"&&!Z&&(ho(),process.exit(S===void 0||S==="hel\
281
+ p"||S==="--help"?0:1));if(S==="skill"){let e=dirname(fileURLToPath(import.meta.url)),t={origenes:[join(e,"..",".."),join(e,"..")],home:homedir(),cwd:process.cwd(),proyecto:D.includes("--proyecto"),forzar:D.includes("--forzar"),
282
+ fs:{existe:existsSync,leer:o=>readFileSync(o,"utf8"),escribir:(o,r)=>writeFileSync(o,r),crearDir:o=>mkdirSync(o,{recursive:true})}},n=D.includes("--codex")?jt(t):Nt(t);console.log(n.mensaje),process.exit(n.ok?0:1);}var Ke=D.indexOf("--puer\
283
+ to"),F=Z?0:Ke>=0?Number(D[Ke+1]):8402;(!Number.isInteger(F)||(S==="doctor"?F<1:F<0)||F>65535)&&(console.error(`[bvsala ${S}] puerto inv\xE1lido: ${D[Ke+1]}`),process.exit(1));if(S==="doctor"){D.includes(
284
+ "--write")&&(console.error("[bvsala doctor] --write todav\xEDa no existe: el doctor solo imprime; copia el bloque a mano."),process.exit(1));let e=await Dt(F);console.log(e.texto),process.exit(0);}var _=Z?
285
+ Me(S,0,D,{modoCodex:S==="codex"?It({leerAuth:()=>readFileSync(join(homedir(),".codex","auth.json"),"utf8")}):void 0}):null,ve=process.env.BIVELIO_SERVICE_KEY,go=Z&&process.env.BVSALA_GATEWAY_LOG!=="1",qe=_?.upstream?null:
286
+ Pt(()=>readFileSync(process.env.BVSALA_ANILLO2_FICHERO??join(homedir(),".bvsala","anillo2.json"),"utf8")),X=Ot({enrolamiento:qe,espiaVivo:qe!==null&&await fo(qe.espia),upstreamEnv:process.env.BVSALA_GATEWAY_UPSTREAM,elisionEnv:process.
287
+ env.BVSALA_GATEWAY_ELISION,hoyUtcIso:new Date().toISOString().slice(0,10)}),He=process.env.BVSALA_GATEWAY_UPSTREAM??X.upstream,Kt=process.env.BVSALA_GATEWAY_ELISION??X.elision,B=await Ct({puerto:F,...go?
288
+ {log:()=>{}}:{},...ve?{serviceAccountKey:ve}:{},...process.env.BVSALA_SEAT_ID?{seatId:process.env.BVSALA_SEAT_ID}:{},...He?{upstream:He}:_?.upstream?{upstream:_.upstream}:{},...process.env.BVSALA_GATEWAY_COALESCE===
289
+ "1"?{coalescer:true}:{},...process.env.BVSALA_GATEWAY_SHADOW==="1"?{sombra:true}:{},elision:Kt!=="0",...process.env.BVSALA_METERING_URL?{meteringUrl:process.env.BVSALA_METERING_URL}:{}}),bo=He??_?.upstream??
290
+ "https://api.anthropic.com";console.log(`[bvsala gateway] v${Fe} escuchando en http://127.0.0.1:${B.puerto} \u2192 ${bo}`);console.log(`[bvsala gateway] medici\xF3n: ${ve?"ACTIVA (clave de servicio pr\
291
+ esente)":"APAGADA (falta BIVELIO_SERVICE_KEY)"}`);{let e=tt(Kt,ve!==void 0);(e.aviso?console.error:console.log)(`[bvsala gateway] ${e.linea}`),X.linea&&(X.aviso?console.error:console.log)(`[bvsala gat\
292
+ eway] ${X.linea}`);}process.env.BVSALA_GATEWAY_UPSTREAM&&_?.upstream&&process.env.BVSALA_GATEWAY_UPSTREAM!==_.upstream&&console.error(`[bvsala ${S}] AVISO: BVSALA_GATEWAY_UPSTREAM=${process.env.BVSALA_GATEWAY_UPSTREAM}\
293
+ pisa el upstream de este terminal (${_.upstream}). Si no es lo que quieres, quita la variable.`);S==="codex"&&!lt()&&console.error(`[bvsala codex] AVISO: este Node (${process.version}) no descomprime\
294
+ zstd y Codex manda el cuerpo en zstd: el tr\xE1fico pasa pero NO se mide. Usa Node \u2265 22.15.`);if(_&&Z){let e=Me(S,B.puerto,D,{..._.upstream?{modoCodex:_.upstream.includes("chatgpt.com")?"chatgpt":
295
+ "api-key"}:{}});e.nota&&console.log(`[bvsala ${S}] ${e.nota}`);let t=e.bin;if(process.platform==="win32"){let o=_t(e.bin);o.tipo==="exe"?t=o.ruta:o.tipo==="solo-shim"&&(console.error(`[bvsala ${S}] \`${e.
296
+ bin}\` est\xE1 instalado como shim de npm (${o.ruta}) y Windows no puede lanzarlo de forma segura con argumentos (CVE-2024-27980). Inst\xE1lalo con su instalador nativo (deja un ${e.bin}.exe en el PAT\
297
+ H) o usa la receta manual de docs/terminales/.`),await B.cerrar(),process.exit(127));}let n=spawn(t,e.args,{stdio:"inherit",env:{...process.env,...e.env}});n.on("error",o=>{console.error(`[bvsala ${S}] no\
298
+ se pudo lanzar \`${e.bin}\`: ${String(o)}. \xBFEst\xE1 instalado y en el PATH?`),B.cerrar().then(()=>process.exit(127));}),n.on("exit",(o,r)=>{B.cerrar().then(()=>process.exit(o??(r?1:0)));});}else console.
299
+ log(`[bvsala gateway] apunta tu terminal (o usa \`bvsala ${Le.join("|")}\`): ANTHROPIC_BASE_URL=http://127.0.0.1:${B.puerto} claude \xB7 bvsala doctor para el resto`);var Ht=async()=>{await B.cerrar(),
300
+ process.exit(0);};process.on("SIGINT",()=>{Ht();});process.on("SIGTERM",()=>{Ht();});
package/dist/index.d.ts CHANGED
@@ -3319,6 +3319,6 @@ declare function createSavingsLayer(config: Omit<SavingsLayerConfig, "tokenizer"
3319
3319
  * constant to package.json so the two can never drift.
3320
3320
  */
3321
3321
 
3322
- declare const BV_SALA_VERSION = "0.4.14";
3322
+ declare const BV_SALA_VERSION = "0.4.16";
3323
3323
 
3324
3324
  export { type AnthropicOptions, AnthropicProvider, BV_SALA_VERSION, type BivelioHandoff, CATALOGO, COMPACT_ROWS_INSTRUCTION, type CacheOutcome, type CacheTier, type CachedAnswer, type CanonicalRequest, type ChatMessage, type CompactRowsDecodeOptions, type CompactRowsOptions, type CompactVerification, type CompressionEconomics, type CompressionPolicyInput, type CompressionRequest, type CompressionResult, type Compressor, type ConstraintBackend, type ConstraintBackendId, type ConstraintPlan, type ConversationState, type CostBasis, type CostModel, DEFAULT_COST_MODEL, DEFAULT_MAX_STALENESS_SECONDS, type DeferredExecutionReport, type DeterministicResolver, EMBEDDED_PUBLIC_KEY, type EmbeddingFn, type EvidenceDoc, type ExactCache, ExactTokenizer, type ExecutionClass, ExecutionRouter, type FormatChoice, FormatSelector, type FormatSelectorOptions, type HandoffFact, HeuristicEstimator, InMemoryExactCache, InMemorySemanticCache, type JsonSchema, LicenseError, type LicenseGate, type LicenseKeyset, type LicenseStatus, type LicenseTokenPayload, type LocalClassifier, MODELOS_POR_CODIFICACION, MODELS_BY_ENCODING, type MemoryDelta, type MessageRole, MockProvider, type MockProviderOptions, type ModelCascadeMode, type ModelCascadeReport, type ModelCascadeSettings, type OpenAICompatibleOptions, OpenAICompatibleProvider, type OutputContract, PRECIOS_AL_DIA, type Policy, type ProtectedSpan, type Provider, type ProviderRequest, type ProviderResponse, type ProviderUsage, QUALITY_STATUSES, type QualityStatus, type RequestContext, type Reranker, type ResolvedDeps, type ResolvedGate, type ResolvedLicense, ResolverRegistry, type ResolverResult, type RetrievalOptions, type RetrievalOutcome, type RetrievalPlan, type Retriever, type RevocationListBody, type RevocationListVerification, type RevocationPollEvent, RevocationPoller, type RevocationPollerOptions, RevocationSnapshot, type RouteDecision, type SavingsLayer, type SavingsLayerConfig, SavingsLedger, type SavingsReport, type SavingsRequest, type SavingsResult, type SavingsToggles, SchemaRegistry, type SemanticCacheOptions, type SemanticHit, type SemanticRecord, type SemanticVerifier, type SerializationFormat, type Serializer, Singleflight, type TokenEstimator, TokenizerRegistry, type ToolCallRequest, type ToolDescriptor, type ToolRisk, type ToolSelection, ToolSelector, type ToolSelectorOptions, TraceCollector, type TraceEvent, UMBRAL_LOCAL, UsageEmitter, type UsageEmitterOptions, type ValidationError, type ValidationResult, adaptiveK, arithmeticResolver, buildExactKey, buildInflightKey, canonicalize, compactRowsSerializer, compresionFiel, computeNextDelay, cosine, createCompactRowsSerializer, createDefaultResolvers, createHandoff, createMockProvider, createSavingsLayer, csvSerializer, decodeCompactRows, dedupe, defaultTokenizerRegistry, deriveSeatId, deriveStatus, detectCi, embebedorLocal, emptyState, encodeCompactRows, evalArithmetic, evaluatePolicy, executeRetrievalPlan, gateFromKey, heuristicEstimator, isKeyset, isStrictCompatible, jsonCompactSerializer, keyTokensMatch, liveGateFromKey, mergeDelta, modelFamilyOf, multisetEqual, negationCount, noopCompressor, normalizeText, numericTokens, precioDeLista, projectContext, providerNativeBackend, randomId, registerExactTokenizer, registrarTokenizadorExacto, renderState, resolveConstraintBackend, resolveDependencies, resolveLicense, sha256, shouldCompress, stableStringify, uniformColumns, validateAgainstSchema, vectorLocal, verifyCompactSignature, verifyLicenseToken, verifyRevocationList, withProtectedSpans, words };
package/dist/index.js CHANGED
@@ -792,7 +792,7 @@ ng/usage`:void 0);if(a){i=new dt({url:a,serviceAccountKey:t.serviceAccountKey,..
792
792
  {},...t.metering?.maxBatch!=null?{maxBatch:t.metering.maxBatch}:{},...t.metering?.maxBuffer!=null?{maxBuffer:t.metering.maxBuffer}:{},...t.meteringFetch?{fetchImpl:t.meteringFetch}:t.licenseFetch?{fetchImpl:t.
793
793
  licenseFetch}:{},...t.now?{now:t.now}:{},...t.metering?.ci!=null?{ci:t.metering.ci}:{},...t.silenceWarnings!=null?{silenceWarnings:t.silenceWarnings}:{}});let c=t.metering?.ci??lo();if(t.metering?.seatId)
794
794
  i.setSeat(t.metering.seatId,c);else {let l=i;uo(t.serviceAccountKey).then(u=>l.setSeat(u,c)).catch(()=>{});}i.start();}}return {generate:async a=>{let c=await s.generate(a);if(i)try{i.record(c.report);}catch{}
795
- return c},close:()=>{o?.stop(),r?.stop(),i?.stop();}}}var yf="0.4.14";/*! Bundled license information:
795
+ return c},close:()=>{o?.stop(),r?.stop(),i?.stop();}}}var yf="0.4.16";/*! Bundled license information:
796
796
 
797
797
  @noble/curves/utils.js:
798
798
  @noble/curves/abstract/modular.js:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bivelio/savings-layer",
3
- "version": "0.4.14",
3
+ "version": "0.4.16",
4
4
  "description": "BV-SALA — provider-neutral LLM execution optimizer. A decision layer in front of any LLM provider that cuts the cost of every request while preserving required quality, and reports the saving per call with token-level accounting you can check against your bill. Proprietary and confidential — property of BiVelio Inc.",
5
5
  "keywords": [
6
6
  "llm",
@@ -81,7 +81,10 @@
81
81
  "sombra:corpus": "tsx benchmarks/sombra-corpus.ts",
82
82
  "sombra:diales": "tsx --env-file-if-exists=.env.bench benchmarks/sombra-diales.ts",
83
83
  "anillo1": "tsx --env-file-if-exists=.env.bench benchmarks/anillo1/arnes.ts",
84
- "anillo2": "tsx benchmarks/anillo2/arnes.ts"
84
+ "anillo2": "tsx benchmarks/anillo2/arnes.ts",
85
+ "anillo2:conciliar": "tsx benchmarks/anillo2/conciliar.ts",
86
+ "salida": "tsx --env-file-if-exists=.env.bench benchmarks/salida/arnes.ts",
87
+ "salida:anatomia": "tsx benchmarks/salida/anatomia.ts"
85
88
  },
86
89
  "devDependencies": {
87
90
  "@noble/curves": "^2.2.0",