inference-relay 1.6.8 → 1.6.10

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 +1 @@
1
- export { A as AuditEvent } from '../index--VZSRE8-.cjs';
1
+ export { A as AuditEvent } from '../index-yGhLy31i.cjs';
@@ -1 +1 @@
1
- export { A as AuditEvent } from '../index--VZSRE8-.js';
1
+ export { A as AuditEvent } from '../index-yGhLy31i.js';
package/dist/cli/main.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import {existsSync,mkdirSync,writeFileSync,readFileSync}from'fs';import {homedir}from'os';import {join,dirname}from'path';import {randomUUID,createHash}from'crypto';import {compileFunction}from'vm';import {createRequire}from'module';import {execSync}from'child_process';import {EventEmitter}from'events';/*! inference-relay CLI (c) 2026 L2B II LLC. Patent pending. */
3
- var St=Object.defineProperty;var C=(n,e)=>()=>(n&&(e=n(n=0)),e);var He=(n,e)=>{for(var t in e)St(n,t,{get:e[t],enumerable:true});};var $,ve=C(()=>{$=class n extends Error{code="RELAY_CAP_EXCEEDED";tier;baseCap;topUps;effectiveCap;usedThisCycle;resolutionUrl;constructor(e){let t=e.resolutionUrl??"https://inference-relay.com/dashboard/billing?topup=1";super(`Cap reached (${e.usedThisCycle} / ${e.effectiveCap??"\u221E"} calls this cycle). Buy a top-up or upgrade at ${t}`),this.name="RelayCapExceededError",this.tier=e.tier,this.baseCap=e.baseCap,this.topUps=e.topUps,this.effectiveCap=e.effectiveCap,this.usedThisCycle=e.usedThisCycle,this.resolutionUrl=t,Object.setPrototypeOf(this,n.prototype);}};});function Z(n,e){let t=new Map,r=null,s=null,a=new Promise((d,f)=>{r=d,s=f;});a.catch(()=>{});let i=[],o=null,l="",p="";function c(d,...f){let u=t.get(d);u&&u.forEach(h=>h(...f));}async function*g(){try{for await(let d of n)if(yield d,d.type==="content_block_start")i[d.index]=d.content_block;else if(d.type==="content_block_delta"){let f=i[d.index];f&&d.delta?.type==="text_delta"&&(f.text=(f.text||"")+d.delta.text,c("text",d.delta.text));}else if(d.type==="message_start")l=d.message?.model||"",o=d.message?.usage;else if(d.type==="message_delta")p=d.delta?.stop_reason||"",d.usage&&(o={...o,...d.usage});else if(d.type==="message_stop"){let f={role:"assistant",model:l,content:i.filter(Boolean),usage:o,stop_reason:p};c("message",f),r&&(r(f),r=null),e&&e(f);}if(r){let d={role:"assistant",model:l,content:i.filter(Boolean),usage:o,stop_reason:p||"end_turn"};c("message",d),r(d),r=null,e&&e(d);}}catch(d){throw c("error",d),s&&(s(d),s=null),d}}let m=g(),y=false,b={[Symbol.asyncIterator](){if(y)throw new Error("[inference-relay] RelayStream can only be iterated once");return y=true,m},on(d,f){return t.has(d)||t.set(d,[]),t.get(d).push(f),b},finalMessage(){let d,f=new Promise((u,h)=>{d=setTimeout(()=>h(new Error("[inference-relay] finalMessage() timed out \u2014 no message_stop received after 5 minutes")),3e5);});return Promise.race([a,f]).finally(()=>clearTimeout(d))}};return b}var Ce=C(()=>{});var P,Y=C(()=>{Ce();P=class{priority=100;async streamRaw(e,t){throw new Error(`[inference-relay] Provider '${this.type}' does not implement streamRaw(). Override either stream() or streamRaw() in the provider class.`)}async stream(e,t){return Z(await this.streamRaw(e,t))}};});function Be(){Lt.clearCache();}var Ae,$e,K,Lt,Re=C(()=>{Ae=`-----BEGIN PUBLIC KEY-----
3
+ var Dt=Object.defineProperty;var v=(n,e)=>()=>(n&&(e=n(n=0)),e);var $e=(n,e)=>{for(var t in e)Dt(n,t,{get:e[t],enumerable:true});};var B,Re=v(()=>{B=class n extends Error{code="RELAY_CAP_EXCEEDED";tier;baseCap;topUps;effectiveCap;usedThisCycle;resolutionUrl;constructor(e){let t=e.resolutionUrl??"https://inference-relay.com/dashboard/billing?topup=1";super(`Cap reached (${e.usedThisCycle} / ${e.effectiveCap??"\u221E"} calls this cycle). Buy a top-up or upgrade at ${t}`),this.name="RelayCapExceededError",this.tier=e.tier,this.baseCap=e.baseCap,this.topUps=e.topUps,this.effectiveCap=e.effectiveCap,this.usedThisCycle=e.usedThisCycle,this.resolutionUrl=t,Object.setPrototypeOf(this,n.prototype);}};});function Z(n,e){let t=new Map,r=null,s=null,a=new Promise((d,f)=>{r=d,s=f;});a.catch(()=>{});let i=[],o=null,l="",p="";function c(d,...f){let u=t.get(d);u&&u.forEach(h=>h(...f));}async function*g(){try{for await(let d of n)if(yield d,d.type==="content_block_start")i[d.index]=d.content_block;else if(d.type==="content_block_delta"){let f=i[d.index];f&&d.delta?.type==="text_delta"&&(f.text=(f.text||"")+d.delta.text,c("text",d.delta.text));}else if(d.type==="message_start")l=d.message?.model||"",o=d.message?.usage;else if(d.type==="message_delta")p=d.delta?.stop_reason||"",d.usage&&(o={...o,...d.usage});else if(d.type==="message_stop"){let f={role:"assistant",model:l,content:i.filter(Boolean),usage:o,stop_reason:p};c("message",f),r&&(r(f),r=null),e&&e(f);}if(r){let d={role:"assistant",model:l,content:i.filter(Boolean),usage:o,stop_reason:p||"end_turn"};c("message",d),r(d),r=null,e&&e(d);}}catch(d){throw c("error",d),s&&(s(d),s=null),d}}let m=g(),y=false,b={[Symbol.asyncIterator](){if(y)throw new Error("[inference-relay] RelayStream can only be iterated once");return y=true,m},on(d,f){return t.has(d)||t.set(d,[]),t.get(d).push(f),b},finalMessage(){let d,f=new Promise((u,h)=>{d=setTimeout(()=>h(new Error("[inference-relay] finalMessage() timed out \u2014 no message_stop received after 5 minutes")),3e5);});return Promise.race([a,f]).finally(()=>clearTimeout(d))}};return b}var Ce=v(()=>{});var S,G=v(()=>{Ce();S=class{priority=100;async streamRaw(e,t){throw new Error(`[inference-relay] Provider '${this.type}' does not implement streamRaw(). Override either stream() or streamRaw() in the provider class.`)}async stream(e,t){return Z(await this.streamRaw(e,t))}};});function Ye(){Mt.clearCache();}var Ae,Ve,K,Mt,ke=v(()=>{Ae=`-----BEGIN PUBLIC KEY-----
4
4
  MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzk88Bt9LZSmuSd8ulKqy
5
5
  EGNiPB+r8u1ZinBvMM4qX8dp4kzJEC/47L1RYrrxCphD05HToREjljbj+upH6rZH
6
6
  t6D/5funYPi2TO1IOSC6BRVRwMqqTmJGVJcLcG/WF3gTE+2UQ3q5EppWJCEKcz6x
@@ -8,12 +8,12 @@ kfynZEzOcLikoQALIxEjxRfi6g83wNJS+WBwAJQ68s7N9FHE3rkLzEqv3FJRP+ZR
8
8
  7lqwqIyuCLr9j9yc4XqF6VY9yooD2hyw/n1EVFejzjDgntWTqIkaCIXwh8lDzRrK
9
9
  Rxn07gcI6ea2Eym9sXh4xZLFudXfAT2DFsH/XboDUuMKAV1YHc1NsIGApesWe2M+
10
10
  UQIDAQAB
11
- -----END PUBLIC KEY-----`,$e={version:"1.0.0",cliVersion:"2.1.87",eventTypes:{system:"system",streamEvent:"stream_event",assistant:"assistant",result:"result"},fieldMappings:{sessionId:"session_id",model:"model",cliVersion:"claude_code_version",content:"content",usage:"usage",inputTokens:"input_tokens",outputTokens:"output_tokens",stopReason:"stop_reason",isError:"is_error",totalCostUsd:"total_cost_usd",durationMs:"duration_ms",error:"error",event:"event"},syntheticModel:"<synthetic>"},K=class{verificationFailures=0;cachedManifest=null;currentSecurityState="SEC_NOMINAL";async verifyManifest(e){try{let{compactVerify:t,importSPKI:r}=await import('jose'),s=await r(Ae,"RS256"),{payload:a}=await t(e,s),i=JSON.parse(new TextDecoder().decode(a));return this.verificationFailures=0,this.cachedManifest=i,this.currentSecurityState="SEC_NOMINAL",{manifest:i,securityState:"SEC_NOMINAL"}}catch{if(this.verificationFailures++,this.verificationFailures>=3){this.currentSecurityState="SEC_DEGRADED";let t=2e3+Math.random()*3e3;return await new Promise(r=>setTimeout(r,t)),console.warn("[inference-relay] Logic synchronization mismatch. Routing via local recovery."),{manifest:$e,securityState:"SEC_DEGRADED"}}return this.cachedManifest?(this.currentSecurityState="SEC_CACHE",{manifest:this.cachedManifest,securityState:"SEC_CACHE"}):(this.currentSecurityState="SEC_RECOVERY",{manifest:$e,securityState:"SEC_RECOVERY"})}}getSecurityState(){return this.currentSecurityState}clearCache(){this.cachedManifest=null,this.verificationFailures=0,this.currentSecurityState="SEC_NOMINAL";}},Lt=new K;});function I(n,...e){process.env.IR_DEBUG==="1"&&console.error(`[ir-debug:${n}]`,...e);}var ke=C(()=>{});function Ie(n){return join(homedir(),".inference-relay","gateway",n)}function Ye(n){return join(Ie(n),"bundle.js")}function Ke(n){return join(Ie(n),"meta.json")}function Ft(n){let e=(r,s)=>{if(!Array.isArray(r)||r.length===0)return null;let a=[];for(let i of r){let o=typeof i=="string"?Number(i):i;if(typeof o!="number"||!Number.isFinite(o)||o<0)return I("loader.retry-config-invalid",{source:s,badValue:i}),null;a.push(o);}return a};if(n!==void 0){let r=e(n,"option");if(r)return r}let t=process.env.IR_GATEWAY_RETRY_DELAYS_MS;if(t){let r=e(t.split(",").map(s=>s.trim()),"env");if(r)return r}return Nt}var Ut,A,N,W,Nt,q,Pe=C(()=>{Re();ke();Ut=process.env.IR_GATEWAY_URL||"https://api.inference-relay.com";A=class extends Error{constructor(t,r,s){super(t);this.code=r;this.cause=s;this.name="GatewayLoaderError";}code;cause},N=class extends A{constructor(e,t){super(e,"GATEWAY_FETCH_FAILED",t);}},W=new Map,Nt=[0,1e3,4e3];q=class{static async load(e,t,r=Ut,s){let a=`${t}:${e.slice(-8)}`;if(W.has(a))return W.get(a);try{let m=await this.tryLoadFromDisk(t);if(m)return I("loader.cache-hit",{libraryVersion:t}),W.set(a,m),m}catch{}I("loader.cache-miss",{libraryVersion:t});let{bytes:i,sha256:o,signature:l,libraryVersion:p}=await this.fetchFromAuthority(e,t,r,s);if(createHash("sha256").update(i).digest("hex")!==o)throw new A("[ir-system]: GATEWAY_VERIFICATION_FAILED (REASON: HASH_MISMATCH)","GATEWAY_VERIFICATION_FAILED");await this.verifySignature(l,p,o);try{let m=Ie(t);mkdirSync(m,{recursive:!0}),writeFileSync(Ye(t),i),writeFileSync(Ke(t),JSON.stringify({sha256:o,signature:l,libraryVersion:p}));}catch{}let g=this.loadIntoVm(i.toString("utf-8"));return W.set(a,g),g}static async loadFromDisk(e){if(!existsSync(e))throw new A(`[ir-system]: GATEWAY_LOAD_FAILED (REASON: BUNDLE_NOT_FOUND at ${e})`,"GATEWAY_LOAD_FAILED");let t=readFileSync(e,"utf-8");return this.loadIntoVm(t)}static async tryLoadFromDisk(e){let t=Ye(e),r=Ke(e);if(!existsSync(t)||!existsSync(r))return null;let s=readFileSync(t),a=JSON.parse(readFileSync(r,"utf-8"));return createHash("sha256").update(s).digest("hex")!==a.sha256?null:(await this.verifySignature(a.signature,a.libraryVersion,a.sha256),this.loadIntoVm(s.toString("utf-8")))}static async fetchFromAuthority(e,t,r,s){let a,i=Ft(s?.retryDelaysMs),o;for(let g=0;g<i.length;g++){let m=i[g];m>0&&await new Promise(y=>setTimeout(y,m)),I("loader.fetch",{url:`${r}/v1/gateway/fetch`,libraryVersion:t,attempt:g+1,delayMs:m});try{let y=await fetch(`${r}/v1/gateway/fetch`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({libraryVersion:t})});if(I("loader.fetch-result",{status:y.status,attempt:g+1}),y.status===401||y.status===403)throw new A("[ir-system]: LICENSE_REJECTED (REASON: GATEWAY_FETCH_UNAUTHORIZED)","LICENSE_REJECTED");if(y.status>=500&&y.status<600){o=new N(`[ir-system]: GATEWAY_FETCH_FAILED (REASON: HTTP_${y.status})`);continue}if(!y.ok)throw new N(`[ir-system]: GATEWAY_FETCH_FAILED (REASON: HTTP_${y.status})`);a=await y.json(),o=null;break}catch(y){if(y instanceof A&&y.code==="LICENSE_REJECTED")throw y;o=y;}}if(o||!a)throw o instanceof A?o:new N("[ir-system]: GATEWAY_FETCH_FAILED (REASON: NETWORK_ERROR)",o);let l;try{l=await fetch(a.bundleUrl);}catch(g){throw new N("[ir-system]: GATEWAY_FETCH_FAILED (REASON: BUNDLE_DOWNLOAD_FAILED)",g)}if(!l.ok)throw new N(`[ir-system]: GATEWAY_FETCH_FAILED (REASON: BUNDLE_HTTP_${l.status})`);let p=await l.arrayBuffer();return {bytes:Buffer.from(p),sha256:a.sha256,signature:a.signature,libraryVersion:a.libraryVersion,bundleVersion:a.bundleVersion}}static async verifySignature(e,t,r){try{let{compactVerify:s,importSPKI:a}=await import('jose'),i=await a(Ae,"RS256"),{payload:o}=await s(e,i),l=JSON.parse(new TextDecoder().decode(o));if(l.purpose!=="gateway-bundle")throw new A("[ir-system]: GATEWAY_VERIFICATION_FAILED (REASON: PURPOSE_MISMATCH)","GATEWAY_VERIFICATION_FAILED");if(l.libraryVersion!==t)throw new A("[ir-system]: GATEWAY_VERIFICATION_FAILED (REASON: LIBRARY_VERSION_MISMATCH)","GATEWAY_VERIFICATION_FAILED");if(l.sha256!==r)throw new A("[ir-system]: GATEWAY_VERIFICATION_FAILED (REASON: SHA256_MISMATCH)","GATEWAY_VERIFICATION_FAILED")}catch(s){throw s instanceof A?s:new A("[ir-system]: GATEWAY_VERIFICATION_FAILED (REASON: SIGNATURE_INVALID)","GATEWAY_VERIFICATION_FAILED",s)}}static loadIntoVm(e){try{let t=join(homedir(),".inference-relay","gateway","runtime.cjs"),r=dirname(t),s=createRequire(t),a={exports:{}};compileFunction(e,["exports","require","module","__filename","__dirname"],{filename:"<gateway-bundle>"})(a.exports,s,a,t,r);let o=a.exports;if(!o.ClaudeCLIProvider)throw new A("[ir-system]: GATEWAY_LOAD_FAILED (REASON: MISSING_CLAUDE_CLI_EXPORT)","GATEWAY_LOAD_FAILED");return o}catch(t){throw t instanceof A?t:new A("[ir-system]: GATEWAY_LOAD_FAILED (REASON: VM_EXECUTION_ERROR)","GATEWAY_LOAD_FAILED",t)}}static clearCache(){W.clear();}};});var qe={};He(qe,{detectCLI:()=>B});function Gt(n){let e=process.env.PATH;if(!e)return null;let t=process.platform==="win32",r=t?";":":",s=t?(process.env.PATHEXT??".COM;.EXE;.BAT;.CMD").split(";").map(a=>a.toLowerCase()):[""];for(let a of e.split(r))if(a)for(let i of s){let o=join(a,n+i);if(existsSync(o))return o}return null}async function B(){if(!Gt("claude"))return {available:false,authenticated:false};let e=null;try{let r=execSync("claude --version",{encoding:"utf-8",timeout:5e3}).trim(),s=r.match(/(\d+\.\d+\.\d+)/);e=s?s[1]:r;}catch{}let t;return e&&!Vt.some(r=>e.startsWith(r.split(".").slice(0,2).join(".")))&&(t=`CLI version ${e} is not tested with this version of inference-relay. Streaming may be unstable.`),{available:true,authenticated:true,cliVersion:e||void 0,versionWarning:t}}var Vt,te=C(()=>{Vt=["2.1.87"];});var je,ne,re,Je=C(()=>{Y();Pe();je="1.6.8",ne=class extends P{type="claude-cli";supportsStreaming=true;supportsMultimodal=true;platformRequirement="desktop";licenseKey;loadOptions;loadedProvider=null;loadingPromise=null;health={status:"healthy",lastCheckAt:Date.now(),errorCount:0};constructor(e,t){super(),this.licenseKey=e,this.loadOptions=t;}async ensureLoaded(){return this.loadedProvider?this.loadedProvider:this.loadingPromise?this.loadingPromise:(this.loadingPromise=(async()=>{try{let t=(await q.load(this.licenseKey,je,void 0,this.loadOptions)).ClaudeCLIProvider,r=new t;return this.loadedProvider=r,r}catch(e){throw this.loadingPromise=null,this.health.status="unhealthy",this.health.errorCount++,e instanceof A?this.health.lastError=e.message:e instanceof Error&&(this.health.lastError=e.message),e}})(),this.loadingPromise)}async warmup(){await this.ensureLoaded();}async probe(){let{detectCLI:e}=await Promise.resolve().then(()=>(te(),qe));return e()}async execute(e,t){return (await this.ensureLoaded()).execute(e,t)}async streamRaw(e,t){return (await this.ensureLoaded()).streamRaw(e,t)}estimateCost(e){if(this.loadedProvider)return this.loadedProvider.estimateCost(e);let r=JSON.stringify(e.messages).length/4+5e3,s=(r*3+1e3*15)/1e6;return {estimatedInputTokens:Math.round(r),estimatedCost:Math.round(s*1e4)/1e4,model:e.model,provider:"claude-cli"}}getHealth(){return this.loadedProvider?this.loadedProvider.getHealth():{...this.health}}reportRateLimit(e){this.loadedProvider?this.loadedProvider.reportRateLimit(e):(this.health.status="degraded",this.health.lastError=`Rate limited: ${e.utilization*100}% utilization`,this.health.lastCheckAt=Date.now());}},re=class extends P{type="kimi-cli";supportsStreaming=true;supportsMultimodal=false;platformRequirement="desktop";licenseKey;loadOptions;loadedProvider=null;loadingPromise=null;health={status:"healthy",lastCheckAt:Date.now(),errorCount:0};constructor(e,t){super(),this.licenseKey=e,this.loadOptions=t;}async ensureLoaded(){return this.loadedProvider?this.loadedProvider:this.loadingPromise?this.loadingPromise:(this.loadingPromise=(async()=>{try{let t=(await q.load(this.licenseKey,je,void 0,this.loadOptions)).KimiCLIProvider;if(!t)throw new A("[ir-system]: GATEWAY_LOAD_FAILED (REASON: STALE_BUNDLE_NO_KIMI_CLI)","GATEWAY_LOAD_FAILED");let r=new t;return this.loadedProvider=r,r}catch(e){throw this.loadingPromise=null,this.health.status="unhealthy",this.health.errorCount++,this.health.lastError=e instanceof Error?e.message:String(e),e}})(),this.loadingPromise)}async warmup(){await this.ensureLoaded();}async probe(){let{existsSync:e}=await import('fs'),{homedir:t}=await import('os'),{join:r}=await import('path'),s=process.env.KIMI_CODE_HOME||r(t(),".kimi-code"),a=process.env.IR_KIMI_BIN||r(s,"bin","kimi"),i=e(a),o=e(r(s,"credentials"))||e(r(s,"oauth"));return {available:i,authenticated:o,subscriptionType:o?"kimi-code":void 0}}async execute(e,t){return (await this.ensureLoaded()).execute(e,t)}async streamRaw(e,t){return (await this.ensureLoaded()).streamRaw(e,t)}estimateCost(e){if(this.loadedProvider)return this.loadedProvider.estimateCost(e);let t=JSON.stringify(e.messages).length/4;return {estimatedInputTokens:Math.round(t+2e3),estimatedCost:0,model:e.model,provider:"kimi-cli"}}getHealth(){return this.loadedProvider?this.loadedProvider.getHealth():{...this.health}}reportRateLimit(e){this.loadedProvider?this.loadedProvider.reportRateLimit(e):(this.health.status="degraded",this.health.lastError=`Rate limited: ${e.utilization*100}% utilization`,this.health.lastCheckAt=Date.now());}};});function Xe(n){return se[n]||n}function Se(n){return ze.find(e=>e.canonical===n)?.provider}var ze,se,Le=C(()=>{ze=[{canonical:"claude-haiku-4-5",apiId:"claude-haiku-4-5-20251001",provider:"anthropic-api",capabilities:{streaming:true,tools:true,multimodal:true,contextWindow:2e5},pricing:[.8,4]},{canonical:"claude-sonnet-4-6",apiId:"claude-sonnet-4-20250514",provider:"anthropic-api",capabilities:{streaming:true,tools:true,multimodal:true,contextWindow:2e5},pricing:[3,15]},{canonical:"claude-opus-4-6",apiId:"claude-opus-4-20250514",provider:"anthropic-api",capabilities:{streaming:true,tools:true,multimodal:true,contextWindow:2e5},pricing:[15,75]},{canonical:"gpt-4.1",apiId:"gpt-4.1",provider:"openai-api",capabilities:{streaming:true,tools:true,multimodal:true,contextWindow:1e6},pricing:[2,8]},{canonical:"gpt-4.1-mini",apiId:"gpt-4.1-mini",provider:"openai-api",capabilities:{streaming:true,tools:true,multimodal:true,contextWindow:1e6},pricing:[.4,1.6]},{canonical:"gpt-4.1-nano",apiId:"gpt-4.1-nano",provider:"openai-api",capabilities:{streaming:true,tools:true,multimodal:true,contextWindow:1e6},pricing:[.1,.4]},{canonical:"gpt-4o",apiId:"gpt-4o",provider:"openai-api",capabilities:{streaming:true,tools:true,multimodal:true,contextWindow:128e3},pricing:[2.5,10]},{canonical:"gpt-4o-mini",apiId:"gpt-4o-mini",provider:"openai-api",capabilities:{streaming:true,tools:true,multimodal:true,contextWindow:128e3},pricing:[.15,.6]},{canonical:"o4-mini",apiId:"o4-mini",provider:"openai-api",capabilities:{streaming:true,tools:true,multimodal:false,contextWindow:2e5},pricing:[1.1,4.4]},{canonical:"o3",apiId:"o3",provider:"openai-api",capabilities:{streaming:true,tools:true,multimodal:false,contextWindow:2e5},pricing:[.4,1.6]},{canonical:"o3-mini",apiId:"o3-mini",provider:"openai-api",capabilities:{streaming:true,tools:true,multimodal:false,contextWindow:2e5},pricing:[1.1,4.4]},{canonical:"o1",apiId:"o1",provider:"openai-api",capabilities:{streaming:false,tools:false,multimodal:false,contextWindow:2e5},pricing:[15,60]},{canonical:"llama3.1",apiId:"llama3.1",provider:"ollama",capabilities:{streaming:true,tools:true,multimodal:false,contextWindow:128e3}},{canonical:"mistral",apiId:"mistral",provider:"ollama",capabilities:{streaming:true,tools:false,multimodal:false,contextWindow:32e3}},{canonical:"mistral-nemo",apiId:"mistral-nemo",provider:"ollama",capabilities:{streaming:true,tools:true,multimodal:false,contextWindow:128e3}},{canonical:"llava",apiId:"llava",provider:"ollama",capabilities:{streaming:true,tools:false,multimodal:true,contextWindow:32e3}},{canonical:"qwen2:0.5b",apiId:"qwen2:0.5b",provider:"ollama",capabilities:{streaming:true,tools:false,multimodal:false,contextWindow:32e3}}],se=Object.fromEntries(ze.filter(n=>n.canonical!==n.apiId).map(n=>[n.canonical,n.apiId]));se["claude-sonnet-4"]="claude-sonnet-4-20250514";se["claude-opus-4"]="claude-opus-4-20250514";se["claude-haiku-4"]="claude-haiku-4-5-20251001";});function Qe(n){if(xe[n])return xe[n];for(let[e,t]of Object.entries(xe))if(n.startsWith(e.split("-20")[0]))return t;return [3,15]}var Yt,Kt,xe,ie,Ze=C(()=>{Y();Le();Yt="https://api.anthropic.com/v1/messages",Kt="2023-06-01",xe={"claude-sonnet-4-5-20250514":[3,15],"claude-sonnet-4-20250514":[3,15],"claude-haiku-4-5-20250414":[.8,4],"claude-opus-4-20250514":[15,75]};ie=class extends P{type="anthropic-api";supportsStreaming=true;supportsMultimodal=true;platformRequirement="any";apiKey;baseUrl;dangerousDirectBrowserAccess;health={status:"healthy",lastCheckAt:Date.now(),errorCount:0};constructor(e){super(),this.apiKey=e.apiKey,this.baseUrl=e.baseUrl?.replace(/\/$/,"")||Yt,this.dangerousDirectBrowserAccess=e.dangerousDirectBrowserAccess??false;}async probe(){try{let e=await fetch(this.baseUrl,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify({model:"claude-haiku-4-5-20250414",max_tokens:1,messages:[{role:"user",content:"hi"}]})});return e.status===401?{available:!0,authenticated:!1}:e.ok||e.status===429?{available:!0,authenticated:!0,rateLimitTier:e.headers.get("anthropic-ratelimit-tier")??void 0}:e.status===529?{available:!0,authenticated:!0}:{available:!1,authenticated:!1}}catch{return {available:false,authenticated:false}}}async execute(e,t){let r=Date.now(),s=this.buildRequestBody(e,false),a=await fetch(this.baseUrl,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify(s),signal:t?.signal});if(!a.ok)throw this.handleErrorResponse(a),new Error("unreachable");let i=await a.json(),o=Date.now()-r;this.recordSuccess();let[l,p]=Qe(i.model||e.model),c=((i.usage?.input_tokens||0)*l+(i.usage?.output_tokens||0)*p)/1e6,g={},m=["request-id","x-request-id","anthropic-ratelimit-requests-limit","anthropic-ratelimit-requests-remaining","anthropic-ratelimit-requests-reset","anthropic-ratelimit-tokens-limit","anthropic-ratelimit-tokens-remaining","anthropic-ratelimit-tokens-reset","anthropic-ratelimit-tier"];for(let y of m){let b=a.headers.get(y);b&&(g[y]=b);}return {content:i.content||[],model:i.model||e.model,usage:{input_tokens:i.usage?.input_tokens||0,output_tokens:i.usage?.output_tokens||0},stop_reason:i.stop_reason||"end_turn",provider:"anthropic-api",costUsd:Math.round(c*1e6)/1e6,durationMs:o,fallbackChain:["anthropic-api:success"],headers:Object.keys(g).length>0?g:void 0}}async streamRaw(e,t){let r=this.buildRequestBody(e,true),s=await fetch(this.baseUrl,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify(r),signal:t?.signal});if(s.ok||this.handleErrorResponse(s),!s.body)throw new Error("ANTHROPIC_API_ERROR: Response body is null \u2014 streaming unavailable");let a=s.body.getReader(),i=new TextDecoder;return (async function*(){let o="",l=false;try{for(;;){let{done:p,value:c}=await a.read();if(p)break;o+=i.decode(c,{stream:!0});let g=o.split(`
12
- `);o=g.pop()||"";let m=null;for(let y of g)if(y.startsWith("event: "))m=y.slice(7).trim();else if(y.startsWith("data: ")){let b=y.slice(6);if(m&&b)try{let d=JSON.parse(b);d.type==="message_stop"&&(l=!0),yield d;}catch{console.warn("[inference-relay] Skipped malformed SSE data:",b.substring(0,100));}m=null;}else y.trim()===""&&(m=null);}l||(yield {type:"message_stop"});}finally{try{a.releaseLock();}catch{}}})()}estimateCost(e){let t=Math.round(JSON.stringify(e.messages).length/4),r=e.system?Math.round(e.system.length/4):0,s=t+r,[a,i]=Qe(e.model),o=(s*a+1e3*i)/1e6;return {estimatedInputTokens:s,estimatedCost:Math.round(o*1e4)/1e4,model:e.model,provider:"anthropic-api"}}getHealth(){return {...this.health}}reportRateLimit(e){this.health.status="degraded",this.health.lastError=`Rate limited: ${e.utilization*100}% utilization`,this.health.lastCheckAt=Date.now();}buildHeaders(){let e={"content-type":"application/json","x-api-key":this.apiKey,"anthropic-version":Kt};return this.dangerousDirectBrowserAccess&&(e["anthropic-dangerous-direct-browser-access"]="true"),e}buildRequestBody(e,t){let r={model:Xe(e.model),max_tokens:e.max_tokens,messages:e.messages};return t&&(r.stream=true),e.system&&(r.system=e.system),e.temperature!==void 0&&(r.temperature=e.temperature),e.tools&&e.tools.length>0&&(r.tools=e.tools),e.metadata&&(r.metadata=e.metadata),r}handleErrorResponse(e){let t=e.status;if(t===401)throw this.health.status="unhealthy",this.health.lastError="Authentication failed",this.health.errorCount++,this.health.lastCheckAt=Date.now(),new Error("ANTHROPIC_AUTH_ERROR: Invalid API key (401)");if(t===429){let r=e.headers.get("retry-after"),s=r?parseInt(r,10)*1e3:6e4;this.health.status="degraded",this.health.lastError=`Rate limited \u2014 retry after ${s}ms`,this.health.lastCheckAt=Date.now();let a=new Error(`ANTHROPIC_RATE_LIMIT: Too many requests (429). Retry after ${s}ms`);throw a.retryAfterMs=s,a}throw t===529?(this.health.status="degraded",this.health.lastError="API overloaded",this.health.lastCheckAt=Date.now(),new Error("ANTHROPIC_OVERLOADED: API is temporarily overloaded (529)")):(this.health.errorCount++,this.health.lastCheckAt=Date.now(),new Error(`ANTHROPIC_API_ERROR: Request failed with status ${t}`))}recordSuccess(){this.health.status="healthy",this.health.lastCheckAt=Date.now(),this.health.errorCount=0,this.health.lastError=void 0;}};});function tt(n){if(De[n])return De[n];for(let[e,t]of Object.entries(De))if(n.startsWith(e))return t;return [2.5,10]}function qt(n){return typeof n=="string"?n:n.filter(e=>e.type==="text"&&e.text).map(e=>e.text).join("")}function jt(n,e){let t=[];e&&t.push({role:"system",content:e});for(let r of n){let s=qt(r.content);if(r.role==="assistant"&&Array.isArray(r.content)){let a=r.content.filter(i=>i.type==="tool_use");if(a.length>0){t.push({role:"assistant",content:s||"",tool_calls:a.map(i=>({id:i.id||`call_${Math.random().toString(36).slice(2)}`,type:"function",function:{name:i.name,arguments:typeof i.input=="string"?i.input:JSON.stringify(i.input)}}))});continue}}t.push({role:r.role,content:s});}return t}function nt(n){switch(n){case "stop":return "end_turn";case "length":return "max_tokens";case "tool_calls":case "function_call":return "tool_use";default:return "end_turn"}}var Wt,et,De,ae,rt=C(()=>{Y();Wt="https://api.openai.com/v1/chat/completions",et=["gpt-","o1","o3","o4","chatgpt-","text-","davinci","babbage","ft:"],De={"gpt-4.1":[2,8],"gpt-4.1-mini":[.4,1.6],"gpt-4.1-nano":[.1,.4],"gpt-4o":[2.5,10],"gpt-4o-mini":[.15,.6],"o4-mini":[1.1,4.4],o3:[.4,1.6],"o3-mini":[1.1,4.4],o1:[15,60],"o1-mini":[3,12],"gpt-4-turbo":[10,30],"gpt-4":[30,60],"gpt-3.5-turbo":[.5,1.5]};ae=class extends P{type="openai-api";supportsStreaming=true;supportsMultimodal=true;platformRequirement="any";apiKey;baseUrl;health={status:"healthy",lastCheckAt:Date.now(),errorCount:0};constructor(e){super(),this.apiKey=e.apiKey,this.baseUrl=e.baseUrl?.replace(/\/$/,"")||Wt;}async probe(){try{let e=this.baseUrl.replace(/\/chat\/completions$/,"/models"),t=await fetch(e,{method:"GET",headers:this.buildHeaders()});return t.status===401?{available:!0,authenticated:!1}:t.ok||t.status===429?{available:!0,authenticated:!0}:{available:!1,authenticated:!1}}catch{return {available:false,authenticated:false}}}async execute(e,t){let r=Date.now(),s=this.buildRequestBody(e,false),a=await fetch(this.baseUrl,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify(s),signal:t?.signal});if(!a.ok)throw this.handleErrorResponse(a),new Error("unreachable");let i=await a.json(),o=Date.now()-r;this.recordSuccess();let l=i.choices?.[0],p=[];if(l?.message?.content&&p.push({type:"text",text:l.message.content}),l?.message?.tool_calls)for(let u of l.message.tool_calls)p.push({type:"tool_use",id:u.id,name:u.function?.name,input:u.function?.arguments?JSON.parse(u.function.arguments):{}});let c=i.usage?.prompt_tokens||0,g=i.usage?.completion_tokens||0,[m,y]=tt(i.model||e.model),b=(c*m+g*y)/1e6,d={},f=["x-request-id","x-ratelimit-limit-requests","x-ratelimit-remaining-requests","x-ratelimit-limit-tokens","x-ratelimit-remaining-tokens","x-ratelimit-reset-requests","x-ratelimit-reset-tokens"];for(let u of f){let h=a.headers.get(u);h&&(d[u]=h);}return {content:p,model:i.model||e.model,usage:{input_tokens:c,output_tokens:g},stop_reason:nt(l?.finish_reason),provider:"openai-api",costUsd:Math.round(b*1e6)/1e6,durationMs:o,fallbackChain:["openai-api:success"],headers:Object.keys(d).length>0?d:void 0}}async streamRaw(e,t){let r=this.buildRequestBody(e,true),s=await fetch(this.baseUrl,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify(r),signal:t?.signal});if(s.ok||this.handleErrorResponse(s),!s.body)throw new Error("OPENAI_API_ERROR: Response body is null \u2014 streaming unavailable");let a=s.body.getReader(),i=new TextDecoder,o=e.model;return (async function*(){let l="",p=false,c=false,g,m;yield {type:"message_start",message:{model:o,usage:{input_tokens:0,output_tokens:0}}};try{for(;;){let{done:y,value:b}=await a.read();if(y)break;l+=i.decode(b,{stream:!0});let d=l.split(`
13
- `);l=d.pop()||"";for(let f of d){if(!f.startsWith("data: "))continue;let u=f.slice(6).trim();if(u==="[DONE]"){yield {type:"message_delta",delta:{stop_reason:m||"end_turn"},usage:g||{}},yield {type:"message_stop"},c=!0;return}try{let h=JSON.parse(u);h.usage&&(g={input_tokens:h.usage.prompt_tokens||0,output_tokens:h.usage.completion_tokens||0});let v=h.choices?.[0];if(!v)continue;let E=v.delta;E?.content&&!p&&(p=!0,yield {type:"content_block_start",index:0,content_block:{type:"text",text:""}}),E?.content&&(yield {type:"content_block_delta",index:0,delta:{type:"text_delta",text:E.content}}),v.finish_reason&&(p&&(yield {type:"content_block_stop",index:0}),m=nt(v.finish_reason));}catch{}}}c||(yield {type:"message_delta",delta:{stop_reason:m||"end_turn"},usage:g||{}},yield {type:"message_stop"});}finally{try{a.releaseLock();}catch{}}})()}estimateCost(e){let t=Math.round(JSON.stringify(e.messages).length/4),r=e.system?Math.round(e.system.length/4):0,s=t+r,[a,i]=tt(e.model),o=(s*a+1e3*i)/1e6;return {estimatedInputTokens:s,estimatedCost:Math.round(o*1e4)/1e4,model:e.model,provider:"openai-api"}}getHealth(){return {...this.health}}reportRateLimit(e){this.health.status="degraded",this.health.lastError=`Rate limited: ${e.utilization*100}% utilization`,this.health.lastCheckAt=Date.now();}buildHeaders(){return {"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`}}buildRequestBody(e,t){let r=e.model.toLowerCase();if(!et.some(o=>r.startsWith(o)))throw new Error(`OPENAI_MODEL_TRANSLATION_REQUIRED: The OpenAI provider received the model name '${e.model}', which does not match any known OpenAI model prefix (${et.join(", ")}). The relay does NOT auto-translate model names across providers in v1.3.x. Either (a) pass an OpenAI model name like 'gpt-4o-mini' when routing to this provider, or (b) route non-OpenAI models through a provider that understands them (e.g. 'anthropic-api' for Claude models).`);let a=jt(e.messages,e.system),i={model:e.model,max_tokens:e.max_tokens,messages:a};return t&&(i.stream=true,i.stream_options={include_usage:true}),e.temperature!==void 0&&(i.temperature=e.temperature),e.tools&&e.tools.length>0&&(i.tools=e.tools),i}handleErrorResponse(e){let t=e.status;if(t===401)throw this.health.status="unhealthy",this.health.lastError="Authentication failed",this.health.errorCount++,this.health.lastCheckAt=Date.now(),new Error("OPENAI_AUTH_ERROR: Invalid API key (401)");if(t===429){let r=e.headers.get("retry-after"),s=r?parseInt(r,10)*1e3:6e4;this.health.status="degraded",this.health.lastError=`Rate limited \u2014 retry after ${s}ms`,this.health.lastCheckAt=Date.now();let a=new Error(`OPENAI_RATE_LIMIT: Too many requests (429). Retry after ${s}ms`);throw a.retryAfterMs=s,a}throw this.health.errorCount++,this.health.lastCheckAt=Date.now(),new Error(`OPENAI_API_ERROR: Request failed with status ${t}`)}recordSuccess(){this.health.status="healthy",this.health.lastCheckAt=Date.now(),this.health.errorCount=0,this.health.lastError=void 0;}};});function zt(n){return typeof n=="string"?n:n.filter(e=>e.type==="text"&&e.text).map(e=>e.text).join("")}function Xt(n,e){let t=[];e&&t.push({role:"system",content:e});for(let r of n)t.push({role:r.role,content:zt(r.content)});return t}var Jt,oe,st=C(()=>{Y();Jt="http://localhost:11434";oe=class extends P{type="ollama";supportsStreaming=true;supportsMultimodal=false;platformRequirement="desktop";baseUrl;health={status:"healthy",lastCheckAt:Date.now(),errorCount:0};constructor(e){super(),this.baseUrl=e?.baseUrl?.replace(/\/$/,"")||Jt;}async probe(){try{return (await fetch(`${this.baseUrl}/api/tags`,{method:"GET"})).ok?{available:!0,authenticated:!0}:{available:!1,authenticated:!1}}catch{return {available:false,authenticated:false}}}async execute(e,t){let r=Date.now(),s=this.buildRequestBody(e,false),a=await fetch(`${this.baseUrl}/api/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s),signal:t?.signal});if(!a.ok)throw this.handleErrorResponse(a),new Error("unreachable");let i=await a.json(),o=Date.now()-r;this.recordSuccess();let l=[];i.message?.content&&l.push({type:"text",text:i.message.content});let p=i.prompt_eval_count||0,c=i.eval_count||0;return {content:l,model:i.model||e.model,usage:{input_tokens:p,output_tokens:c},stop_reason:(i.done,"end_turn"),provider:"ollama",costUsd:0,durationMs:o,fallbackChain:["ollama:success"]}}async streamRaw(e,t){let r=this.buildRequestBody(e,true),s=await fetch(`${this.baseUrl}/api/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r),signal:t?.signal});if(s.ok||this.handleErrorResponse(s),!s.body)throw new Error("OLLAMA_ERROR: Response body is null \u2014 streaming unavailable");let a=s.body.getReader(),i=new TextDecoder,o=e.model;return (async function*(){let l="",p=false,c=false;yield {type:"message_start",message:{model:o,usage:{input_tokens:0,output_tokens:0}}};try{for(;;){let{done:g,value:m}=await a.read();if(g)break;l+=i.decode(m,{stream:!0});let y=l.split(`
14
- `);l=y.pop()||"";for(let b of y){let d=b.trim();if(d)try{let f=JSON.parse(d);if(f.message?.content&&(p||(p=!0,yield {type:"content_block_start",index:0,content_block:{type:"text",text:""}}),yield {type:"content_block_delta",index:0,delta:{type:"text_delta",text:f.message.content}}),f.done){p&&(yield {type:"content_block_stop",index:0}),yield {type:"message_delta",delta:{stop_reason:"end_turn"},usage:{input_tokens:f.prompt_eval_count||0,output_tokens:f.eval_count||0}},yield {type:"message_stop"},c=!0;return}}catch{}}}c||(yield {type:"message_stop"});}finally{try{a.releaseLock();}catch{}}})()}estimateCost(e){let t=Math.round(JSON.stringify(e.messages).length/4),r=e.system?Math.round(e.system.length/4):0;return {estimatedInputTokens:t+r,estimatedCost:0,model:e.model,provider:"ollama"}}getHealth(){return {...this.health}}reportRateLimit(e){this.health.status="degraded",this.health.lastError=`Rate limited: ${e.utilization*100}% utilization`,this.health.lastCheckAt=Date.now();}buildRequestBody(e,t){if(e.tools&&e.tools.length>0)throw new Error(`OLLAMA_TOOLS_NOT_SUPPORTED: The Ollama provider received ${e.tools.length} tool definition(s) in params.tools, but this provider does not implement function calling in v1.3.x. For tool-use workflows route to 'anthropic-api' or 'openai-api' instead. Tracking issue: 1.4.0 ships an Ollama tool-use shim for models that support native function calling (llama3.1, mistral-nemo, etc.).`);let r=Xt(e.messages,e.system),s={model:e.model,messages:r,stream:t};return e.temperature!==void 0&&(s.options={temperature:e.temperature}),s}handleErrorResponse(e){let t=e.status;throw this.health.errorCount++,this.health.lastCheckAt=Date.now(),t===404?(this.health.status="unhealthy",this.health.lastError="Model not found",new Error("OLLAMA_MODEL_NOT_FOUND: Requested model is not available locally (404)")):(this.health.status="unhealthy",this.health.lastError=`Request failed with status ${t}`,new Error(`OLLAMA_ERROR: Request failed with status ${t}`))}recordSuccess(){this.health.status="healthy",this.health.lastCheckAt=Date.now(),this.health.errorCount=0,this.health.lastError=void 0;}};});var le,it=C(()=>{le=class extends EventEmitter{constructor(){super(),this.setMaxListeners(50);}emitTyped(e){return this.emit(e.kind,e)}onTyped(e,t){return this.on(e,t)}offTyped(e,t){return this.off(e,t)}};});function ce(n,e){if(e instanceof A)return `${n}:failed:${e.code}:${e.message}`;let t=e?.message;return `${n}:failed:${t?.slice(0,mt)||"unknown"}`}function at(n){let e=n.filter(t=>t.includes(":failed:"));return e.length===0?false:e.every(t=>t.endsWith(":failed:request_too_large"))}function lt(n){return n.messages.some(e=>typeof e.content=="string"?false:Array.isArray(e.content)&&e.content.some(t=>t.type==="image"||t.type==="image_url"))}function ue(n){if(!(n instanceof Error))return "unknown";let e=n.code;if(typeof e=="string"){if(e==="LICENSE_REJECTED")return "auth_failed";if(e==="GATEWAY_FETCH_FAILED"||e==="GATEWAY_VERIFICATION_FAILED"||e==="GATEWAY_LOAD_FAILED")return "gateway_unavailable"}let t=n.message.toLowerCase(),r=n.name.toLowerCase();return t.includes("prompt is too long")||t.includes("prompt too long")||t.includes("prompt_too_large")||t.includes("input length")||t.includes("input is too long")||t.includes("context_length_exceeded")||t.includes("context length exceeded")||t.includes("request too large")||t.includes("tokens exceed")||t.includes("exceeds the maximum")||t.includes("too many tokens")?"request_too_large":t.includes("code 3221226505")||t.includes("cli exited with code 3 ")||t.includes("cli stream exited with code 3 ")||t.includes("bun has crashed")||t.includes("illegal instruction")||t.includes("stream ended without producing any content")||t.includes("cli returned empty response")||t.includes("cli closed stdout without sending any response")||t.includes("kimi_stall_silent")?"transient":t.includes("credit balance is too low")||t.includes("credit balance too low")?"auth_failed":t.startsWith("openai_model_translation_required:")||t.startsWith("ollama_tools_not_supported:")||t.startsWith("multimodal_cli_too_old:")||t.startsWith("stream_json_cli_too_old:")?"provider_incompatible":t.includes("rate limit")||t.includes("429")||r.includes("ratelimit")?"rate_limited":t.includes("auth")||t.includes("401")||t.includes("403")||t.includes("unauthorized")||t.includes("forbidden")?"auth_failed":t.includes("timeout")||t.includes("timed out")||t.includes("aborted")||r==="aborterror"||r==="timeouterror"?"timeout":"unknown"}function ct(n){return [...n].sort((e,t)=>e.priority-t.priority)}function ut(n){return {provider:n,inputTokens:0,outputTokens:0,costUsd:0,userCostUsd:0}}function Zt(n,e,t){typeof t.input_tokens=="number"&&(n.inputTokens=t.input_tokens),typeof t.output_tokens=="number"&&(e==="anthropic-api"||e==="claude-cli"?n.outputTokens+=t.output_tokens:n.outputTokens=t.output_tokens);}function dt(n){return {input_tokens:n[n.length-1]?.inputTokens??0,output_tokens:n.reduce((e,t)=>e+t.outputTokens,0)}}function en(n,e){if(e.type==="content_block_start"){let t=e.content_block;t?.type==="text"?n.content.push({type:"text",text:t.text||"",open:true}):t?.type==="tool_use"&&n.content.push({type:"tool_use",id:t.id,name:t.name,input:{},_partialJson:"",open:true});}else if(e.type==="content_block_delta"){let t=n.content[n.content.length-1];if(!t)return;t.type==="text"&&e.delta?.type==="text_delta"?t.text+=e.delta.text||"":t.type==="tool_use"&&e.delta?.type==="input_json_delta"&&(t._partialJson=(t._partialJson||"")+(e.delta.partial_json||""));}else if(e.type==="content_block_stop"){for(let t=n.content.length-1;t>=0;t--)if(n.content[t].open){if(n.content[t].open=false,n.content[t].type==="tool_use"){let r=n.content[t];try{r.input=JSON.parse(r._partialJson||"{}");}catch{}delete r._partialJson;}break}}}function tn(n,e,t,r,s){if(s&&n.type==="content_block_delta"&&n.index===s.fromIndex)return {action:"yield",event:{...n,index:s.toIndex}};if(s&&n.type==="content_block_stop"&&n.index===s.fromIndex)return {action:"suppress",coalesceMode:null,coalesceModeCleared:true};if(r&&n.type==="content_block_start"&&n.content_block?.type==="text"){let i=t.content[t.content.length-1];if(i?.type==="text"&&i.open===true)return {action:"suppress",coalesceMode:{fromIndex:n.index+e,toIndex:t.content.length-1},clearedJustFailedOver:true}}let a=r&&n.type==="content_block_start";return typeof n.index=="number"&&e>0?{action:"yield",event:{...n,index:n.index+e},clearedJustFailedOver:a}:{action:"yield",event:n,clearedJustFailedOver:a}}function nn(n){let e=[];for(let t of n)t.type==="text"?t.text&&e.push({type:"text",text:t.text}):t.type==="tool_use"&&!t.open&&t.input&&Object.keys(t.input).length>0&&e.push({type:"tool_use",id:t.id,name:t.name,input:t.input});return e}function rn(n,e){return n?`${n}
11
+ -----END PUBLIC KEY-----`,Ve={version:"1.0.0",cliVersion:"2.1.87",eventTypes:{system:"system",streamEvent:"stream_event",assistant:"assistant",result:"result"},fieldMappings:{sessionId:"session_id",model:"model",cliVersion:"claude_code_version",content:"content",usage:"usage",inputTokens:"input_tokens",outputTokens:"output_tokens",stopReason:"stop_reason",isError:"is_error",totalCostUsd:"total_cost_usd",durationMs:"duration_ms",error:"error",event:"event"},syntheticModel:"<synthetic>"},K=class{verificationFailures=0;cachedManifest=null;currentSecurityState="SEC_NOMINAL";async verifyManifest(e){try{let{compactVerify:t,importSPKI:r}=await import('jose'),s=await r(Ae,"RS256"),{payload:a}=await t(e,s),i=JSON.parse(new TextDecoder().decode(a));return this.verificationFailures=0,this.cachedManifest=i,this.currentSecurityState="SEC_NOMINAL",{manifest:i,securityState:"SEC_NOMINAL"}}catch{if(this.verificationFailures++,this.verificationFailures>=3){this.currentSecurityState="SEC_DEGRADED";let t=2e3+Math.random()*3e3;return await new Promise(r=>setTimeout(r,t)),console.warn("[inference-relay] Logic synchronization mismatch. Routing via local recovery."),{manifest:Ve,securityState:"SEC_DEGRADED"}}return this.cachedManifest?(this.currentSecurityState="SEC_CACHE",{manifest:this.cachedManifest,securityState:"SEC_CACHE"}):(this.currentSecurityState="SEC_RECOVERY",{manifest:Ve,securityState:"SEC_RECOVERY"})}}getSecurityState(){return this.currentSecurityState}clearCache(){this.cachedManifest=null,this.verificationFailures=0,this.currentSecurityState="SEC_NOMINAL";}},Mt=new K;});function I(n,...e){process.env.IR_DEBUG==="1"&&console.error(`[ir-debug:${n}]`,...e);}var we=v(()=>{});function Se(n){return join(homedir(),".inference-relay","gateway",n)}function We(n){return join(Se(n),"bundle.js")}function qe(n){return join(Se(n),"meta.json")}function Vt(n){let e=(r,s)=>{if(!Array.isArray(r)||r.length===0)return null;let a=[];for(let i of r){let o=typeof i=="string"?Number(i):i;if(typeof o!="number"||!Number.isFinite(o)||o<0)return I("loader.retry-config-invalid",{source:s,badValue:i}),null;a.push(o);}return a};if(n!==void 0){let r=e(n,"option");if(r)return r}let t=process.env.IR_GATEWAY_RETRY_DELAYS_MS;if(t){let r=e(t.split(",").map(s=>s.trim()),"env");if(r)return r}return $t}var Bt,C,U,W,$t,q,Pe=v(()=>{ke();we();Bt=process.env.IR_GATEWAY_URL||"https://api.inference-relay.com";C=class extends Error{constructor(t,r,s){super(t);this.code=r;this.cause=s;this.name="GatewayLoaderError";}code;cause},U=class extends C{constructor(e,t){super(e,"GATEWAY_FETCH_FAILED",t);}},W=new Map,$t=[0,1e3,4e3];q=class{static async load(e,t,r=Bt,s){let a=`${t}:${e.slice(-8)}`;if(W.has(a))return W.get(a);try{let m=await this.tryLoadFromDisk(t);if(m)return I("loader.cache-hit",{libraryVersion:t}),W.set(a,m),m}catch{}I("loader.cache-miss",{libraryVersion:t});let{bytes:i,sha256:o,signature:l,libraryVersion:p}=await this.fetchFromAuthority(e,t,r,s);if(createHash("sha256").update(i).digest("hex")!==o)throw new C("[ir-system]: GATEWAY_VERIFICATION_FAILED (REASON: HASH_MISMATCH)","GATEWAY_VERIFICATION_FAILED");await this.verifySignature(l,p,o);try{let m=Se(t);mkdirSync(m,{recursive:!0}),writeFileSync(We(t),i),writeFileSync(qe(t),JSON.stringify({sha256:o,signature:l,libraryVersion:p}));}catch{}let g=this.loadIntoVm(i.toString("utf-8"));return W.set(a,g),g}static async loadFromDisk(e){if(!existsSync(e))throw new C(`[ir-system]: GATEWAY_LOAD_FAILED (REASON: BUNDLE_NOT_FOUND at ${e})`,"GATEWAY_LOAD_FAILED");let t=readFileSync(e,"utf-8");return this.loadIntoVm(t)}static async tryLoadFromDisk(e){let t=We(e),r=qe(e);if(!existsSync(t)||!existsSync(r))return null;let s=readFileSync(t),a=JSON.parse(readFileSync(r,"utf-8"));return createHash("sha256").update(s).digest("hex")!==a.sha256?null:(await this.verifySignature(a.signature,a.libraryVersion,a.sha256),this.loadIntoVm(s.toString("utf-8")))}static async fetchFromAuthority(e,t,r,s){let a,i=Vt(s?.retryDelaysMs),o;for(let g=0;g<i.length;g++){let m=i[g];m>0&&await new Promise(y=>setTimeout(y,m)),I("loader.fetch",{url:`${r}/v1/gateway/fetch`,libraryVersion:t,attempt:g+1,delayMs:m});try{let y=await fetch(`${r}/v1/gateway/fetch`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({libraryVersion:t})});if(I("loader.fetch-result",{status:y.status,attempt:g+1}),y.status===401||y.status===403)throw new C("[ir-system]: LICENSE_REJECTED (REASON: GATEWAY_FETCH_UNAUTHORIZED)","LICENSE_REJECTED");if(y.status>=500&&y.status<600){o=new U(`[ir-system]: GATEWAY_FETCH_FAILED (REASON: HTTP_${y.status})`);continue}if(!y.ok)throw new U(`[ir-system]: GATEWAY_FETCH_FAILED (REASON: HTTP_${y.status})`);a=await y.json(),o=null;break}catch(y){if(y instanceof C&&y.code==="LICENSE_REJECTED")throw y;o=y;}}if(o||!a)throw o instanceof C?o:new U("[ir-system]: GATEWAY_FETCH_FAILED (REASON: NETWORK_ERROR)",o);let l;try{l=await fetch(a.bundleUrl);}catch(g){throw new U("[ir-system]: GATEWAY_FETCH_FAILED (REASON: BUNDLE_DOWNLOAD_FAILED)",g)}if(!l.ok)throw new U(`[ir-system]: GATEWAY_FETCH_FAILED (REASON: BUNDLE_HTTP_${l.status})`);let p=await l.arrayBuffer();return {bytes:Buffer.from(p),sha256:a.sha256,signature:a.signature,libraryVersion:a.libraryVersion,bundleVersion:a.bundleVersion}}static async verifySignature(e,t,r){try{let{compactVerify:s,importSPKI:a}=await import('jose'),i=await a(Ae,"RS256"),{payload:o}=await s(e,i),l=JSON.parse(new TextDecoder().decode(o));if(l.purpose!=="gateway-bundle")throw new C("[ir-system]: GATEWAY_VERIFICATION_FAILED (REASON: PURPOSE_MISMATCH)","GATEWAY_VERIFICATION_FAILED");if(l.libraryVersion!==t)throw new C("[ir-system]: GATEWAY_VERIFICATION_FAILED (REASON: LIBRARY_VERSION_MISMATCH)","GATEWAY_VERIFICATION_FAILED");if(l.sha256!==r)throw new C("[ir-system]: GATEWAY_VERIFICATION_FAILED (REASON: SHA256_MISMATCH)","GATEWAY_VERIFICATION_FAILED")}catch(s){throw s instanceof C?s:new C("[ir-system]: GATEWAY_VERIFICATION_FAILED (REASON: SIGNATURE_INVALID)","GATEWAY_VERIFICATION_FAILED",s)}}static loadIntoVm(e){try{let t=join(homedir(),".inference-relay","gateway","runtime.cjs"),r=dirname(t),s=createRequire(t),a={exports:{}};compileFunction(e,["exports","require","module","__filename","__dirname"],{filename:"<gateway-bundle>"})(a.exports,s,a,t,r);let o=a.exports;if(!o.ClaudeCLIProvider)throw new C("[ir-system]: GATEWAY_LOAD_FAILED (REASON: MISSING_CLAUDE_CLI_EXPORT)","GATEWAY_LOAD_FAILED");return o}catch(t){throw t instanceof C?t:new C("[ir-system]: GATEWAY_LOAD_FAILED (REASON: VM_EXECUTION_ERROR)","GATEWAY_LOAD_FAILED",t)}}static clearCache(){W.clear();}};});var Je={};$e(Je,{detectCLI:()=>$});function qt(n){let e=process.env.PATH;if(!e)return null;let t=process.platform==="win32",r=t?";":":",s=t?(process.env.PATHEXT??".COM;.EXE;.BAT;.CMD").split(";").map(a=>a.toLowerCase()):[""];for(let a of e.split(r))if(a)for(let i of s){let o=join(a,n+i);if(existsSync(o))return o}return null}async function $(){if(!qt("claude"))return {available:false,authenticated:false};let e=null;try{let r=execSync("claude --version",{encoding:"utf-8",timeout:5e3}).trim(),s=r.match(/(\d+\.\d+\.\d+)/);e=s?s[1]:r;}catch{}let t;return e&&!Wt.some(r=>e.startsWith(r.split(".").slice(0,2).join(".")))&&(t=`CLI version ${e} is not tested with this version of inference-relay. Streaming may be unstable.`),{available:true,authenticated:true,cliVersion:e||void 0,versionWarning:t}}var Wt,te=v(()=>{Wt=["2.1.87"];});var ze,ne,re,Xe=v(()=>{G();Pe();ze="1.6.10",ne=class extends S{type="claude-cli";supportsStreaming=true;supportsMultimodal=true;platformRequirement="desktop";licenseKey;loadOptions;loadedProvider=null;loadingPromise=null;health={status:"healthy",lastCheckAt:Date.now(),errorCount:0};constructor(e,t){super(),this.licenseKey=e,this.loadOptions=t;}async ensureLoaded(){return this.loadedProvider?this.loadedProvider:this.loadingPromise?this.loadingPromise:(this.loadingPromise=(async()=>{try{let t=(await q.load(this.licenseKey,ze,void 0,this.loadOptions)).ClaudeCLIProvider,r=new t;return this.loadedProvider=r,r}catch(e){throw this.loadingPromise=null,this.health.status="unhealthy",this.health.errorCount++,e instanceof C?this.health.lastError=e.message:e instanceof Error&&(this.health.lastError=e.message),e}})(),this.loadingPromise)}async warmup(){await this.ensureLoaded();}async probe(){let{detectCLI:e}=await Promise.resolve().then(()=>(te(),Je));return e()}async execute(e,t){return (await this.ensureLoaded()).execute(e,t)}async streamRaw(e,t){return (await this.ensureLoaded()).streamRaw(e,t)}estimateCost(e){if(this.loadedProvider)return this.loadedProvider.estimateCost(e);let r=JSON.stringify(e.messages).length/4+5e3,s=(r*3+1e3*15)/1e6;return {estimatedInputTokens:Math.round(r),estimatedCost:Math.round(s*1e4)/1e4,model:e.model,provider:"claude-cli"}}getHealth(){return this.loadedProvider?this.loadedProvider.getHealth():{...this.health}}reportRateLimit(e){this.loadedProvider?this.loadedProvider.reportRateLimit(e):(this.health.status="degraded",this.health.lastError=`Rate limited: ${e.utilization*100}% utilization`,this.health.lastCheckAt=Date.now());}},re=class extends S{type="kimi-cli";supportsStreaming=true;supportsMultimodal=false;platformRequirement="desktop";licenseKey;loadOptions;loadedProvider=null;loadingPromise=null;health={status:"healthy",lastCheckAt:Date.now(),errorCount:0};constructor(e,t){super(),this.licenseKey=e,this.loadOptions=t;}async ensureLoaded(){return this.loadedProvider?this.loadedProvider:this.loadingPromise?this.loadingPromise:(this.loadingPromise=(async()=>{try{let t=(await q.load(this.licenseKey,ze,void 0,this.loadOptions)).KimiCLIProvider;if(!t)throw new C("[ir-system]: GATEWAY_LOAD_FAILED (REASON: STALE_BUNDLE_NO_KIMI_CLI)","GATEWAY_LOAD_FAILED");let r=new t;return this.loadedProvider=r,r}catch(e){throw this.loadingPromise=null,this.health.status="unhealthy",this.health.errorCount++,this.health.lastError=e instanceof Error?e.message:String(e),e}})(),this.loadingPromise)}async warmup(){await this.ensureLoaded();}async probe(){let{existsSync:e}=await import('fs'),{homedir:t}=await import('os'),{join:r}=await import('path'),s=process.env.KIMI_CODE_HOME||r(t(),".kimi-code"),a=process.env.IR_KIMI_BIN||r(s,"bin","kimi"),i=e(a),o=e(r(s,"credentials"))||e(r(s,"oauth"));return {available:i,authenticated:o,subscriptionType:o?"kimi-code":void 0}}async execute(e,t){return (await this.ensureLoaded()).execute(e,t)}async streamRaw(e,t){return (await this.ensureLoaded()).streamRaw(e,t)}estimateCost(e){if(this.loadedProvider)return this.loadedProvider.estimateCost(e);let t=JSON.stringify(e.messages).length/4;return {estimatedInputTokens:Math.round(t+2e3),estimatedCost:0,model:e.model,provider:"kimi-cli"}}getHealth(){return this.loadedProvider?this.loadedProvider.getHealth():{...this.health}}reportRateLimit(e){this.loadedProvider?this.loadedProvider.reportRateLimit(e):(this.health.status="degraded",this.health.lastError=`Rate limited: ${e.utilization*100}% utilization`,this.health.lastCheckAt=Date.now());}};});function Ze(n){return se[n]||n}function Le(n){return Qe.find(e=>e.canonical===n)?.provider}var Qe,se,xe=v(()=>{Qe=[{canonical:"claude-haiku-4-5",apiId:"claude-haiku-4-5-20251001",provider:"anthropic-api",capabilities:{streaming:true,tools:true,multimodal:true,contextWindow:2e5},pricing:[.8,4]},{canonical:"claude-sonnet-4-6",apiId:"claude-sonnet-4-20250514",provider:"anthropic-api",capabilities:{streaming:true,tools:true,multimodal:true,contextWindow:2e5},pricing:[3,15]},{canonical:"claude-opus-4-6",apiId:"claude-opus-4-20250514",provider:"anthropic-api",capabilities:{streaming:true,tools:true,multimodal:true,contextWindow:2e5},pricing:[15,75]},{canonical:"gpt-4.1",apiId:"gpt-4.1",provider:"openai-api",capabilities:{streaming:true,tools:true,multimodal:true,contextWindow:1e6},pricing:[2,8]},{canonical:"gpt-4.1-mini",apiId:"gpt-4.1-mini",provider:"openai-api",capabilities:{streaming:true,tools:true,multimodal:true,contextWindow:1e6},pricing:[.4,1.6]},{canonical:"gpt-4.1-nano",apiId:"gpt-4.1-nano",provider:"openai-api",capabilities:{streaming:true,tools:true,multimodal:true,contextWindow:1e6},pricing:[.1,.4]},{canonical:"gpt-4o",apiId:"gpt-4o",provider:"openai-api",capabilities:{streaming:true,tools:true,multimodal:true,contextWindow:128e3},pricing:[2.5,10]},{canonical:"gpt-4o-mini",apiId:"gpt-4o-mini",provider:"openai-api",capabilities:{streaming:true,tools:true,multimodal:true,contextWindow:128e3},pricing:[.15,.6]},{canonical:"o4-mini",apiId:"o4-mini",provider:"openai-api",capabilities:{streaming:true,tools:true,multimodal:false,contextWindow:2e5},pricing:[1.1,4.4]},{canonical:"o3",apiId:"o3",provider:"openai-api",capabilities:{streaming:true,tools:true,multimodal:false,contextWindow:2e5},pricing:[.4,1.6]},{canonical:"o3-mini",apiId:"o3-mini",provider:"openai-api",capabilities:{streaming:true,tools:true,multimodal:false,contextWindow:2e5},pricing:[1.1,4.4]},{canonical:"o1",apiId:"o1",provider:"openai-api",capabilities:{streaming:false,tools:false,multimodal:false,contextWindow:2e5},pricing:[15,60]},{canonical:"llama3.1",apiId:"llama3.1",provider:"ollama",capabilities:{streaming:true,tools:true,multimodal:false,contextWindow:128e3}},{canonical:"mistral",apiId:"mistral",provider:"ollama",capabilities:{streaming:true,tools:false,multimodal:false,contextWindow:32e3}},{canonical:"mistral-nemo",apiId:"mistral-nemo",provider:"ollama",capabilities:{streaming:true,tools:true,multimodal:false,contextWindow:128e3}},{canonical:"llava",apiId:"llava",provider:"ollama",capabilities:{streaming:true,tools:false,multimodal:true,contextWindow:32e3}},{canonical:"qwen2:0.5b",apiId:"qwen2:0.5b",provider:"ollama",capabilities:{streaming:true,tools:false,multimodal:false,contextWindow:32e3}}],se=Object.fromEntries(Qe.filter(n=>n.canonical!==n.apiId).map(n=>[n.canonical,n.apiId]));se["claude-sonnet-4"]="claude-sonnet-4-20250514";se["claude-opus-4"]="claude-opus-4-20250514";se["claude-haiku-4"]="claude-haiku-4-5-20251001";});function et(n){if(Oe[n])return Oe[n];for(let[e,t]of Object.entries(Oe))if(n.startsWith(e.split("-20")[0]))return t;return [3,15]}var jt,Jt,Oe,ie,tt=v(()=>{G();xe();jt="https://api.anthropic.com/v1/messages",Jt="2023-06-01",Oe={"claude-sonnet-4-5-20250514":[3,15],"claude-sonnet-4-20250514":[3,15],"claude-haiku-4-5-20250414":[.8,4],"claude-opus-4-20250514":[15,75]};ie=class extends S{type="anthropic-api";supportsStreaming=true;supportsMultimodal=true;platformRequirement="any";apiKey;baseUrl;dangerousDirectBrowserAccess;health={status:"healthy",lastCheckAt:Date.now(),errorCount:0};constructor(e){super(),this.apiKey=e.apiKey,this.baseUrl=e.baseUrl?.replace(/\/$/,"")||jt,this.dangerousDirectBrowserAccess=e.dangerousDirectBrowserAccess??false;}async probe(){try{let e=await fetch(this.baseUrl,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify({model:"claude-haiku-4-5-20250414",max_tokens:1,messages:[{role:"user",content:"hi"}]})});return e.status===401?{available:!0,authenticated:!1}:e.ok||e.status===429?{available:!0,authenticated:!0,rateLimitTier:e.headers.get("anthropic-ratelimit-tier")??void 0}:e.status===529?{available:!0,authenticated:!0}:{available:!1,authenticated:!1}}catch{return {available:false,authenticated:false}}}async execute(e,t){let r=Date.now(),s=this.buildRequestBody(e,false),a=await fetch(this.baseUrl,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify(s),signal:t?.signal});if(!a.ok)throw this.handleErrorResponse(a),new Error("unreachable");let i=await a.json(),o=Date.now()-r;this.recordSuccess();let[l,p]=et(i.model||e.model),c=((i.usage?.input_tokens||0)*l+(i.usage?.output_tokens||0)*p)/1e6,g={},m=["request-id","x-request-id","anthropic-ratelimit-requests-limit","anthropic-ratelimit-requests-remaining","anthropic-ratelimit-requests-reset","anthropic-ratelimit-tokens-limit","anthropic-ratelimit-tokens-remaining","anthropic-ratelimit-tokens-reset","anthropic-ratelimit-tier"];for(let y of m){let b=a.headers.get(y);b&&(g[y]=b);}return {content:i.content||[],model:i.model||e.model,usage:{input_tokens:i.usage?.input_tokens||0,output_tokens:i.usage?.output_tokens||0},stop_reason:i.stop_reason||"end_turn",provider:"anthropic-api",costUsd:Math.round(c*1e6)/1e6,durationMs:o,fallbackChain:["anthropic-api:success"],headers:Object.keys(g).length>0?g:void 0}}async streamRaw(e,t){let r=this.buildRequestBody(e,true),s=await fetch(this.baseUrl,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify(r),signal:t?.signal});if(s.ok||this.handleErrorResponse(s),!s.body)throw new Error("ANTHROPIC_API_ERROR: Response body is null \u2014 streaming unavailable");let a=s.body.getReader(),i=new TextDecoder;return (async function*(){let o="",l=false;try{for(;;){let{done:p,value:c}=await a.read();if(p)break;o+=i.decode(c,{stream:!0});let g=o.split(`
12
+ `);o=g.pop()||"";let m=null;for(let y of g)if(y.startsWith("event: "))m=y.slice(7).trim();else if(y.startsWith("data: ")){let b=y.slice(6);if(m&&b)try{let d=JSON.parse(b);d.type==="message_stop"&&(l=!0),yield d;}catch{console.warn("[inference-relay] Skipped malformed SSE data:",b.substring(0,100));}m=null;}else y.trim()===""&&(m=null);}l||(yield {type:"message_stop"});}finally{try{a.releaseLock();}catch{}}})()}estimateCost(e){let t=Math.round(JSON.stringify(e.messages).length/4),r=e.system?Math.round(e.system.length/4):0,s=t+r,[a,i]=et(e.model),o=(s*a+1e3*i)/1e6;return {estimatedInputTokens:s,estimatedCost:Math.round(o*1e4)/1e4,model:e.model,provider:"anthropic-api"}}getHealth(){return {...this.health}}reportRateLimit(e){this.health.status="degraded",this.health.lastError=`Rate limited: ${e.utilization*100}% utilization`,this.health.lastCheckAt=Date.now();}buildHeaders(){let e={"content-type":"application/json","x-api-key":this.apiKey,"anthropic-version":Jt};return this.dangerousDirectBrowserAccess&&(e["anthropic-dangerous-direct-browser-access"]="true"),e}buildRequestBody(e,t){let r={model:Ze(e.model),max_tokens:e.max_tokens,messages:e.messages};return t&&(r.stream=true),e.system&&(r.system=e.system),e.temperature!==void 0&&(r.temperature=e.temperature),e.tools&&e.tools.length>0&&(r.tools=e.tools),e.metadata&&(r.metadata=e.metadata),r}handleErrorResponse(e){let t=e.status;if(t===401)throw this.health.status="unhealthy",this.health.lastError="Authentication failed",this.health.errorCount++,this.health.lastCheckAt=Date.now(),new Error("ANTHROPIC_AUTH_ERROR: Invalid API key (401)");if(t===429){let r=e.headers.get("retry-after"),s=r?parseInt(r,10)*1e3:6e4;this.health.status="degraded",this.health.lastError=`Rate limited \u2014 retry after ${s}ms`,this.health.lastCheckAt=Date.now();let a=new Error(`ANTHROPIC_RATE_LIMIT: Too many requests (429). Retry after ${s}ms`);throw a.retryAfterMs=s,a}throw t===529?(this.health.status="degraded",this.health.lastError="API overloaded",this.health.lastCheckAt=Date.now(),new Error("ANTHROPIC_OVERLOADED: API is temporarily overloaded (529)")):(this.health.errorCount++,this.health.lastCheckAt=Date.now(),new Error(`ANTHROPIC_API_ERROR: Request failed with status ${t}`))}recordSuccess(){this.health.status="healthy",this.health.lastCheckAt=Date.now(),this.health.errorCount=0,this.health.lastError=void 0;}};});function rt(n){if(De[n])return De[n];for(let[e,t]of Object.entries(De))if(n.startsWith(e))return t;return [2.5,10]}function Xt(n){return typeof n=="string"?n:n.filter(e=>e.type==="text"&&e.text).map(e=>e.text).join("")}function Qt(n,e){let t=[];e&&t.push({role:"system",content:e});for(let r of n){let s=Xt(r.content);if(r.role==="assistant"&&Array.isArray(r.content)){let a=r.content.filter(i=>i.type==="tool_use");if(a.length>0){t.push({role:"assistant",content:s||"",tool_calls:a.map(i=>({id:i.id||`call_${Math.random().toString(36).slice(2)}`,type:"function",function:{name:i.name,arguments:typeof i.input=="string"?i.input:JSON.stringify(i.input)}}))});continue}}t.push({role:r.role,content:s});}return t}function st(n){switch(n){case "stop":return "end_turn";case "length":return "max_tokens";case "tool_calls":case "function_call":return "tool_use";default:return "end_turn"}}var zt,nt,De,ae,it=v(()=>{G();zt="https://api.openai.com/v1/chat/completions",nt=["gpt-","o1","o3","o4","chatgpt-","text-","davinci","babbage","ft:"],De={"gpt-4.1":[2,8],"gpt-4.1-mini":[.4,1.6],"gpt-4.1-nano":[.1,.4],"gpt-4o":[2.5,10],"gpt-4o-mini":[.15,.6],"o4-mini":[1.1,4.4],o3:[.4,1.6],"o3-mini":[1.1,4.4],o1:[15,60],"o1-mini":[3,12],"gpt-4-turbo":[10,30],"gpt-4":[30,60],"gpt-3.5-turbo":[.5,1.5]};ae=class extends S{type="openai-api";supportsStreaming=true;supportsMultimodal=true;platformRequirement="any";apiKey;baseUrl;health={status:"healthy",lastCheckAt:Date.now(),errorCount:0};constructor(e){super(),this.apiKey=e.apiKey,this.baseUrl=e.baseUrl?.replace(/\/$/,"")||zt;}async probe(){try{let e=this.baseUrl.replace(/\/chat\/completions$/,"/models"),t=await fetch(e,{method:"GET",headers:this.buildHeaders()});return t.status===401?{available:!0,authenticated:!1}:t.ok||t.status===429?{available:!0,authenticated:!0}:{available:!1,authenticated:!1}}catch{return {available:false,authenticated:false}}}async execute(e,t){let r=Date.now(),s=this.buildRequestBody(e,false),a=await fetch(this.baseUrl,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify(s),signal:t?.signal});if(!a.ok)throw this.handleErrorResponse(a),new Error("unreachable");let i=await a.json(),o=Date.now()-r;this.recordSuccess();let l=i.choices?.[0],p=[];if(l?.message?.content&&p.push({type:"text",text:l.message.content}),l?.message?.tool_calls)for(let u of l.message.tool_calls)p.push({type:"tool_use",id:u.id,name:u.function?.name,input:u.function?.arguments?JSON.parse(u.function.arguments):{}});let c=i.usage?.prompt_tokens||0,g=i.usage?.completion_tokens||0,[m,y]=rt(i.model||e.model),b=(c*m+g*y)/1e6,d={},f=["x-request-id","x-ratelimit-limit-requests","x-ratelimit-remaining-requests","x-ratelimit-limit-tokens","x-ratelimit-remaining-tokens","x-ratelimit-reset-requests","x-ratelimit-reset-tokens"];for(let u of f){let h=a.headers.get(u);h&&(d[u]=h);}return {content:p,model:i.model||e.model,usage:{input_tokens:c,output_tokens:g},stop_reason:st(l?.finish_reason),provider:"openai-api",costUsd:Math.round(b*1e6)/1e6,durationMs:o,fallbackChain:["openai-api:success"],headers:Object.keys(d).length>0?d:void 0}}async streamRaw(e,t){let r=this.buildRequestBody(e,true),s=await fetch(this.baseUrl,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify(r),signal:t?.signal});if(s.ok||this.handleErrorResponse(s),!s.body)throw new Error("OPENAI_API_ERROR: Response body is null \u2014 streaming unavailable");let a=s.body.getReader(),i=new TextDecoder,o=e.model;return (async function*(){let l="",p=false,c=false,g,m;yield {type:"message_start",message:{model:o,usage:{input_tokens:0,output_tokens:0}}};try{for(;;){let{done:y,value:b}=await a.read();if(y)break;l+=i.decode(b,{stream:!0});let d=l.split(`
13
+ `);l=d.pop()||"";for(let f of d){if(!f.startsWith("data: "))continue;let u=f.slice(6).trim();if(u==="[DONE]"){yield {type:"message_delta",delta:{stop_reason:m||"end_turn"},usage:g||{}},yield {type:"message_stop"},c=!0;return}try{let h=JSON.parse(u);h.usage&&(g={input_tokens:h.usage.prompt_tokens||0,output_tokens:h.usage.completion_tokens||0});let R=h.choices?.[0];if(!R)continue;let E=R.delta;E?.content&&!p&&(p=!0,yield {type:"content_block_start",index:0,content_block:{type:"text",text:""}}),E?.content&&(yield {type:"content_block_delta",index:0,delta:{type:"text_delta",text:E.content}}),R.finish_reason&&(p&&(yield {type:"content_block_stop",index:0}),m=st(R.finish_reason));}catch{}}}c||(yield {type:"message_delta",delta:{stop_reason:m||"end_turn"},usage:g||{}},yield {type:"message_stop"});}finally{try{a.releaseLock();}catch{}}})()}estimateCost(e){let t=Math.round(JSON.stringify(e.messages).length/4),r=e.system?Math.round(e.system.length/4):0,s=t+r,[a,i]=rt(e.model),o=(s*a+1e3*i)/1e6;return {estimatedInputTokens:s,estimatedCost:Math.round(o*1e4)/1e4,model:e.model,provider:"openai-api"}}getHealth(){return {...this.health}}reportRateLimit(e){this.health.status="degraded",this.health.lastError=`Rate limited: ${e.utilization*100}% utilization`,this.health.lastCheckAt=Date.now();}buildHeaders(){return {"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`}}buildRequestBody(e,t){let r=e.model.toLowerCase();if(!nt.some(o=>r.startsWith(o)))throw new Error(`OPENAI_MODEL_TRANSLATION_REQUIRED: The OpenAI provider received the model name '${e.model}', which does not match any known OpenAI model prefix (${nt.join(", ")}). The relay does NOT auto-translate model names across providers in v1.3.x. Either (a) pass an OpenAI model name like 'gpt-4o-mini' when routing to this provider, or (b) route non-OpenAI models through a provider that understands them (e.g. 'anthropic-api' for Claude models).`);let a=Qt(e.messages,e.system),i={model:e.model,max_tokens:e.max_tokens,messages:a};return t&&(i.stream=true,i.stream_options={include_usage:true}),e.temperature!==void 0&&(i.temperature=e.temperature),e.tools&&e.tools.length>0&&(i.tools=e.tools),i}handleErrorResponse(e){let t=e.status;if(t===401)throw this.health.status="unhealthy",this.health.lastError="Authentication failed",this.health.errorCount++,this.health.lastCheckAt=Date.now(),new Error("OPENAI_AUTH_ERROR: Invalid API key (401)");if(t===429){let r=e.headers.get("retry-after"),s=r?parseInt(r,10)*1e3:6e4;this.health.status="degraded",this.health.lastError=`Rate limited \u2014 retry after ${s}ms`,this.health.lastCheckAt=Date.now();let a=new Error(`OPENAI_RATE_LIMIT: Too many requests (429). Retry after ${s}ms`);throw a.retryAfterMs=s,a}throw this.health.errorCount++,this.health.lastCheckAt=Date.now(),new Error(`OPENAI_API_ERROR: Request failed with status ${t}`)}recordSuccess(){this.health.status="healthy",this.health.lastCheckAt=Date.now(),this.health.errorCount=0,this.health.lastError=void 0;}};});function en(n){return typeof n=="string"?n:n.filter(e=>e.type==="text"&&e.text).map(e=>e.text).join("")}function tn(n,e){let t=[];e&&t.push({role:"system",content:e});for(let r of n)t.push({role:r.role,content:en(r.content)});return t}var Zt,oe,at=v(()=>{G();Zt="http://localhost:11434";oe=class extends S{type="ollama";supportsStreaming=true;supportsMultimodal=false;platformRequirement="desktop";baseUrl;health={status:"healthy",lastCheckAt:Date.now(),errorCount:0};constructor(e){super(),this.baseUrl=e?.baseUrl?.replace(/\/$/,"")||Zt;}async probe(){try{return (await fetch(`${this.baseUrl}/api/tags`,{method:"GET"})).ok?{available:!0,authenticated:!0}:{available:!1,authenticated:!1}}catch{return {available:false,authenticated:false}}}async execute(e,t){let r=Date.now(),s=this.buildRequestBody(e,false),a=await fetch(`${this.baseUrl}/api/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s),signal:t?.signal});if(!a.ok)throw this.handleErrorResponse(a),new Error("unreachable");let i=await a.json(),o=Date.now()-r;this.recordSuccess();let l=[];i.message?.content&&l.push({type:"text",text:i.message.content});let p=i.prompt_eval_count||0,c=i.eval_count||0;return {content:l,model:i.model||e.model,usage:{input_tokens:p,output_tokens:c},stop_reason:(i.done,"end_turn"),provider:"ollama",costUsd:0,durationMs:o,fallbackChain:["ollama:success"]}}async streamRaw(e,t){let r=this.buildRequestBody(e,true),s=await fetch(`${this.baseUrl}/api/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r),signal:t?.signal});if(s.ok||this.handleErrorResponse(s),!s.body)throw new Error("OLLAMA_ERROR: Response body is null \u2014 streaming unavailable");let a=s.body.getReader(),i=new TextDecoder,o=e.model;return (async function*(){let l="",p=false,c=false;yield {type:"message_start",message:{model:o,usage:{input_tokens:0,output_tokens:0}}};try{for(;;){let{done:g,value:m}=await a.read();if(g)break;l+=i.decode(m,{stream:!0});let y=l.split(`
14
+ `);l=y.pop()||"";for(let b of y){let d=b.trim();if(d)try{let f=JSON.parse(d);if(f.message?.content&&(p||(p=!0,yield {type:"content_block_start",index:0,content_block:{type:"text",text:""}}),yield {type:"content_block_delta",index:0,delta:{type:"text_delta",text:f.message.content}}),f.done){p&&(yield {type:"content_block_stop",index:0}),yield {type:"message_delta",delta:{stop_reason:"end_turn"},usage:{input_tokens:f.prompt_eval_count||0,output_tokens:f.eval_count||0}},yield {type:"message_stop"},c=!0;return}}catch{}}}c||(yield {type:"message_stop"});}finally{try{a.releaseLock();}catch{}}})()}estimateCost(e){let t=Math.round(JSON.stringify(e.messages).length/4),r=e.system?Math.round(e.system.length/4):0;return {estimatedInputTokens:t+r,estimatedCost:0,model:e.model,provider:"ollama"}}getHealth(){return {...this.health}}reportRateLimit(e){this.health.status="degraded",this.health.lastError=`Rate limited: ${e.utilization*100}% utilization`,this.health.lastCheckAt=Date.now();}buildRequestBody(e,t){if(e.tools&&e.tools.length>0)throw new Error(`OLLAMA_TOOLS_NOT_SUPPORTED: The Ollama provider received ${e.tools.length} tool definition(s) in params.tools, but this provider does not implement function calling in v1.3.x. For tool-use workflows route to 'anthropic-api' or 'openai-api' instead. Tracking issue: 1.4.0 ships an Ollama tool-use shim for models that support native function calling (llama3.1, mistral-nemo, etc.).`);let r=tn(e.messages,e.system),s={model:e.model,messages:r,stream:t};return e.temperature!==void 0&&(s.options={temperature:e.temperature}),s}handleErrorResponse(e){let t=e.status;throw this.health.errorCount++,this.health.lastCheckAt=Date.now(),t===404?(this.health.status="unhealthy",this.health.lastError="Model not found",new Error("OLLAMA_MODEL_NOT_FOUND: Requested model is not available locally (404)")):(this.health.status="unhealthy",this.health.lastError=`Request failed with status ${t}`,new Error(`OLLAMA_ERROR: Request failed with status ${t}`))}recordSuccess(){this.health.status="healthy",this.health.lastCheckAt=Date.now(),this.health.errorCount=0,this.health.lastError=void 0;}};});var le,ot=v(()=>{le=class extends EventEmitter{constructor(){super(),this.setMaxListeners(50);}emitTyped(e){return this.emit(e.kind,e)}onTyped(e,t){return this.on(e,t)}offTyped(e,t){return this.off(e,t)}};});function ce(n,e){if(e instanceof C)return `${n}:failed:${e.code}:${e.message}`;let t=e?.message;return `${n}:failed:${t?.slice(0,gt)||"unknown"}`}function lt(n){let e=n.filter(t=>t.includes(":failed:"));return e.length===0?false:e.every(t=>t.endsWith(":failed:request_too_large"))}function ut(n){return n.messages.some(e=>typeof e.content=="string"?false:Array.isArray(e.content)&&e.content.some(t=>t.type==="image"||t.type==="image_url"))}function ue(n){if(!(n instanceof Error))return "unknown";let e=n.code;if(typeof e=="string"){if(e==="LICENSE_REJECTED")return "auth_failed";if(e==="GATEWAY_FETCH_FAILED"||e==="GATEWAY_VERIFICATION_FAILED"||e==="GATEWAY_LOAD_FAILED")return "gateway_unavailable"}let t=n.message.toLowerCase(),r=n.name.toLowerCase();return t.includes("prompt is too long")||t.includes("prompt too long")||t.includes("prompt_too_large")||t.includes("input length")||t.includes("input is too long")||t.includes("context_length_exceeded")||t.includes("context length exceeded")||t.includes("request too large")||t.includes("tokens exceed")||t.includes("exceeds the maximum")||t.includes("too many tokens")?"request_too_large":t.includes("code 3221226505")||t.includes("cli exited with code 3 ")||t.includes("cli stream exited with code 3 ")||t.includes("bun has crashed")||t.includes("illegal instruction")||t.includes("stream ended without producing any content")||t.includes("cli returned empty response")||t.includes("cli closed stdout without sending any response")||t.includes("kimi_stall_silent")?"transient":t.includes("credit balance is too low")||t.includes("credit balance too low")?"auth_failed":t.startsWith("openai_model_translation_required:")||t.startsWith("ollama_tools_not_supported:")||t.startsWith("multimodal_cli_too_old:")||t.startsWith("stream_json_cli_too_old:")?"provider_incompatible":t.includes("rate limit")||t.includes("429")||r.includes("ratelimit")?"rate_limited":t.includes("auth")||t.includes("401")||t.includes("403")||t.includes("unauthorized")||t.includes("forbidden")?"auth_failed":t.includes("timeout")||t.includes("timed out")||t.includes("aborted")||r==="aborterror"||r==="timeouterror"?"timeout":"unknown"}function dt(n){return [...n].sort((e,t)=>e.priority-t.priority)}function pt(n){return {provider:n,inputTokens:0,outputTokens:0,costUsd:0,userCostUsd:0}}function rn(n,e,t){typeof t.input_tokens=="number"&&(n.inputTokens=t.input_tokens),typeof t.output_tokens=="number"&&(e==="anthropic-api"||e==="claude-cli"?n.outputTokens+=t.output_tokens:n.outputTokens=t.output_tokens);}function mt(n){return {input_tokens:n[n.length-1]?.inputTokens??0,output_tokens:n.reduce((e,t)=>e+t.outputTokens,0)}}function sn(n,e){if(e.type==="content_block_start"){let t=e.content_block;t?.type==="text"?n.content.push({type:"text",text:t.text||"",open:true}):t?.type==="tool_use"&&n.content.push({type:"tool_use",id:t.id,name:t.name,input:{},_partialJson:"",open:true});}else if(e.type==="content_block_delta"){let t=n.content[n.content.length-1];if(!t)return;t.type==="text"&&e.delta?.type==="text_delta"?t.text+=e.delta.text||"":t.type==="tool_use"&&e.delta?.type==="input_json_delta"&&(t._partialJson=(t._partialJson||"")+(e.delta.partial_json||""));}else if(e.type==="content_block_stop"){for(let t=n.content.length-1;t>=0;t--)if(n.content[t].open){if(n.content[t].open=false,n.content[t].type==="tool_use"){let r=n.content[t];try{r.input=JSON.parse(r._partialJson||"{}");}catch{}delete r._partialJson;}break}}}function an(n,e,t,r,s){if(s&&n.type==="content_block_delta"&&n.index===s.fromIndex)return {action:"yield",event:{...n,index:s.toIndex}};if(s&&n.type==="content_block_stop"&&n.index===s.fromIndex)return {action:"suppress",coalesceMode:null,coalesceModeCleared:true};if(r&&n.type==="content_block_start"&&n.content_block?.type==="text"){let i=t.content[t.content.length-1];if(i?.type==="text"&&i.open===true)return {action:"suppress",coalesceMode:{fromIndex:n.index+e,toIndex:t.content.length-1},clearedJustFailedOver:true}}let a=r&&n.type==="content_block_start";return typeof n.index=="number"&&e>0?{action:"yield",event:{...n,index:n.index+e},clearedJustFailedOver:a}:{action:"yield",event:n,clearedJustFailedOver:a}}function on(n){let e=[];for(let t of n)t.type==="text"?t.text&&e.push({type:"text",text:t.text}):t.type==="tool_use"&&!t.open&&t.input&&Object.keys(t.input).length>0&&e.push({type:"tool_use",id:t.id,name:t.name,input:t.input});return e}function ln(n,e){return n?`${n}
15
15
 
16
- ${e}`:e}function pt(n){let e=0;for(let t of n.content)t.type==="text"?e+=t.text.length:t.type==="tool_use"&&(e+=(t._partialJson||"").length);return e}function sn(n){return Math.max(0,n.content.length-1)}async function*an(n){for await(let e of n)await new Promise(t=>setTimeout(t,50+Math.random()*50)),yield e;}var mt,ot,F,de,pe,Me=C(()=>{Ce();it();Le();Pe();ke();mt=200;ot=new Set(["anthropic-api","openai-api","ollama"]),F=class extends Error{code="ALL_PROVIDERS_FAILED";fallbackChain;constructor(e){super(`All providers failed. Chain: ${e.join(" \u2192 ")}`),this.name="RelayError",this.fallbackChain=e;}},de=class extends F{constructor(e){super(e);}};pe=class n{healthMap=new Map;engineEvents=new le;static UNHEALTHY_TTL_DEFAULT_MS=300*1e3;static UNHEALTHY_TTL_AUTH_MS=30*1e3;getHealthStatus(e){let t=this.healthMap.get(e);if(!t)return "healthy";let r=t.ttlMs??n.UNHEALTHY_TTL_DEFAULT_MS;if(t.status==="unhealthy"&&Date.now()-t.updatedAt>=r){let s=Date.now()-t.updatedAt;return this.healthMap.delete(e),I("engine.recovered",{providerType:e,ageMs:s,ttlMs:r}),"healthy"}return t.status}markUnhealthy(e,t,r){this.healthMap.set(e,{status:"unhealthy",lastError:t,updatedAt:Date.now(),ttlMs:r}),I("engine.unhealthy",{providerType:e,reason:t,ttlMs:r});}markDegraded(e,t){this.healthMap.set(e,{status:"degraded",lastError:t,updatedAt:Date.now()});}markHealthy(e){this.healthMap.set(e,{status:"healthy",updatedAt:Date.now()});}resetHealth(){this.healthMap.clear();}async execute(e,t,r){let s=ct(t),a=[],i=lt(e),o=randomUUID(),l=Date.now();for(let p of s){let c=p.type;if(this.getHealthStatus(c)==="unhealthy"){a.push(`${c}:skipped:unhealthy`);continue}if(i&&!p.supportsMultimodal){a.push(`${c}:skipped:no_multimodal`);continue}let m=Se(e.model);if(m&&m!==c&&ot.has(c)){a.push(`${c}:skipped:wrong_provider`);continue}let y=r?.maxSameProviderRetries??2,b=0,d=null,f=false;for(;!f;)try{let u=await p.execute(e,{signal:r?.signal});return f=!0,this.markHealthy(c),b>0&&a.push(`${c}:retry_success:${b}`),a.push(`${c}:success`),this.emitEngineEvent({kind:"stream_complete",callId:o,id:randomUUID(),ts:Date.now(),stitched:!1,segments:[{provider:c,inputTokens:u.usage.input_tokens,outputTokens:u.usage.output_tokens,costUsd:u.costUsd,userCostUsd:u.userCostUsd??0}],provider:c,model:u.model,inputTokens:u.usage.input_tokens,outputTokens:u.usage.output_tokens,costUsd:u.costUsd,userCostUsd:u.userCostUsd,durationMs:u.durationMs??Date.now()-l,stopReason:u.stop_reason,fallbackChain:a,rateLimitHit:!1,securityState:r?.licenseState}),{...u,fallbackChain:a}}catch(u){if(u?.name==="AbortError"||r?.signal?.aborted)throw u;if(ue(u)==="transient"&&b<y){b++;let v=250*Math.pow(2,b-1);I("engine.transient-retry",{id:c,attempt:b,backoffMs:v,msg:String(u?.message||"").slice(0,120)}),a.push(`${c}:retry:${b}`),await new Promise(E=>setTimeout(E,v));continue}d=u;break}if(!f){let u=d;switch(ue(u)){case "rate_limited":p.reportRateLimit({provider:c,utilization:1,resetsAt:Date.now()+6e4}),this.markDegraded(c,"rate_limited"),a.push(`${c}:failed:rate_limited`);break;case "auth_failed":this.markUnhealthy(c,"auth_failed",n.UNHEALTHY_TTL_AUTH_MS),a.push(`${c}:failed:auth_failed`);break;case "timeout":a.push(`${c}:failed:timeout`);break;case "provider_incompatible":a.push(`${c}:incompatible`);break;case "gateway_unavailable":this.markUnhealthy(c,"gateway_unavailable"),a.push(ce(c,u));break;case "request_too_large":a.push(`${c}:failed:request_too_large`);break;case "transient":this.markDegraded(c,"transient_exhausted"),a.push(`${c}:failed:transient_exhausted`);break;default:a.push(ce(c,u));break}if(r?.subscriptionOnly&&c==="claude-cli"){a.push("subscription_only:cascade_halted");break}}}throw I("engine.cascade-exhausted",{chain:a,mode:"execute"}),at(a)?new de(a):new F(a)}async stream(e,t,r){let s=randomUUID(),a=ct(t),i=lt(e),o=Date.now(),l=[],p=null,c=null;for(let u of a){let h=u.type;if(this.getHealthStatus(h)==="unhealthy"){l.push(`${h}:skipped:unhealthy`);continue}if(i&&!u.supportsMultimodal){l.push(`${h}:skipped:no_multimodal`);continue}if(!u.supportsStreaming){l.push(`${h}:skipped:no_streaming`);continue}let v=Se(e.model);if(v&&v!==h&&ot.has(h)){l.push(`${h}:skipped:wrong_provider`);continue}try{c=await u.streamRaw(e,{signal:r?.signal}),p=u,l.push(`${h}:success`);break}catch(E){if(E?.name==="AbortError"||r?.signal?.aborted)throw E;switch(ue(E)){case "rate_limited":u.reportRateLimit({provider:h,utilization:1,resetsAt:Date.now()+6e4}),this.markDegraded(h,"rate_limited"),l.push(`${h}:failed:rate_limited`);break;case "auth_failed":this.markUnhealthy(h,"auth_failed",n.UNHEALTHY_TTL_AUTH_MS),l.push(`${h}:failed:auth_failed`);break;case "timeout":l.push(`${h}:failed:timeout`);break;case "provider_incompatible":l.push(`${h}:incompatible`);break;case "gateway_unavailable":this.markUnhealthy(h,"gateway_unavailable"),l.push(ce(h,E));break;case "request_too_large":l.push(`${h}:failed:request_too_large`);break;case "transient":this.markDegraded(h,"transient_exhausted"),l.push(`${h}:failed:transient_exhausted`);break;default:l.push(ce(h,E));break}if(r?.subscriptionOnly&&h==="claude-cli"){l.push("subscription_only:cascade_halted");break}}}if(!p||!c)throw I("engine.cascade-exhausted",{chain:l,mode:"stream"}),at(l)?new de(l):new F(l);let m=this,y=r?.maxMidStreamFailovers??2,b=new Set([p]);async function*d(){let u=p,h=c[Symbol.asyncIterator](),v={role:"assistant",content:[]},E={segments:[]},k=ut(u.type);E.segments.push(k);let Ue=0,z=null,X=false,Ee=y,V="",G="";for(m.emitEngineEvent({kind:"segment_start",callId:s,id:randomUUID(),ts:Date.now(),provider:u.type});;)try{for(;;){let T=await h.next();if(T.done)break;let U=T.value,x=tn(U,Ue,v,X,z);if(x.action==="suppress"){"coalesceMode"in x&&(z=x.coalesceMode),x.clearedJustFailedOver&&(X=!1);continue}x.coalesceModeCleared&&(z=null),x.clearedJustFailedOver&&(X=!1);let R=x.event;if(en(v,R),R.type==="message_start"){if(E.segments.length>1)continue;V=R.message?.model||V,R.message?.usage?.input_tokens!=null&&(k.inputTokens=R.message.usage.input_tokens);}if(R.type==="message_delta"&&(R.delta?.stop_reason&&(G=R.delta.stop_reason),R.usage)){Zt(k,u.type,R.usage),yield {...R,usage:void 0};continue}if(R.type==="message_stop")break;yield R;}if(v.content.length===0&&k.outputTokens===0)throw new Error("stream ended without producing any content");m.markHealthy(u.type),m.emitEngineEvent({kind:"segment_complete",callId:s,id:randomUUID(),ts:Date.now(),provider:u.type,usage:{...k}});let S=dt(E.segments);yield {type:"message_delta",delta:{stop_reason:G||"end_turn"},usage:S},yield {type:"message_stop"},m.emitEngineEvent({kind:"stream_complete",callId:s,id:randomUUID(),ts:Date.now(),stitched:E.segments.length>1,segments:E.segments.map(T=>({...T})),provider:E.segments.map(T=>T.provider).join("+"),model:V,inputTokens:S.input_tokens,outputTokens:S.output_tokens,costUsd:E.segments.reduce((T,U)=>T+U.costUsd,0),userCostUsd:E.segments.reduce((T,U)=>T+U.userCostUsd,0),durationMs:Date.now()-o,stopReason:G||"end_turn",fallbackChain:l,rateLimitHit:!1,securityState:r?.licenseState});return}catch(S){if(S?.name==="AbortError"||r?.signal?.aborted)throw S;let T=ue(S);try{await h.return?.();}catch{}if(m.markUnhealthy(u.type,String(S)),m.emitEngineEvent({kind:"mid_stream_failover_attempt",callId:s,id:randomUUID(),ts:Date.now(),from:u.type,bytesBuffered:pt(v),errorClass:T,retriesLeft:Ee}),l.push(`${u.type}:partial(${pt(v)}b)`),Ee<=0)throw m.emitTerminalExhaustion(s,E,V,G,l,o,r?.licenseState),S;let U=nn(v.content),x=[...e.messages,{role:"assistant",content:U}],R=null,Q=null,Ne=u;for(;;){let D=m.nextHealthyProvider(a,Ne,i,b);if(!D)break;Ne=D,b.add(D);let Pt={...e,messages:x,...D.type!=="anthropic-api"&&D.type!=="claude-cli"?{system:rn(e.system,"[SYSTEM]: CONTINUE_LAST_RESPONSE_WITHOUT_REPEATING")}:{}};try{Q=await D.streamRaw(Pt,{signal:r?.signal}),R=D;break}catch(Fe){m.markUnhealthy(D.type,String(Fe)),l.push(`${D.type}:failed_connect:${String(Fe).slice(0,mt)}`);}}if(!R||!Q)throw m.emitTerminalExhaustion(s,E,V,G,l,o,r?.licenseState),S;l.push(`${R.type}:stitched`),m.emitEngineEvent({kind:"mid_stream_failover_success",callId:s,id:randomUUID(),ts:Date.now(),from:u.type,to:R.type}),Ue=sn(v)+1,Ee--,u=R,h=Q[Symbol.asyncIterator](),X=true,z=null,k=ut(u.type),E.segments.push(k),m.emitEngineEvent({kind:"segment_start",callId:s,id:randomUUID(),ts:Date.now(),provider:u.type});}}let f=d();return r?.licenseState==="SEC_DEGRADED"&&(f=an(f)),Z(f)}nextHealthyProvider(e,t,r,s){let a=e.indexOf(t);if(a===-1)return null;for(let i=a+1;i<e.length;i++){let o=e[i];if(!s.has(o)&&!(r&&!o.supportsMultimodal)&&o.supportsStreaming)return o}return null}emitEngineEvent(e){this.engineEvents.emitTyped(e);}emitTerminalExhaustion(e,t,r,s,a,i,o){let l=dt(t.segments);this.emitEngineEvent({kind:"stream_complete",callId:e,id:randomUUID(),ts:Date.now(),stitched:t.segments.length>1,segments:t.segments.map(p=>({...p})),provider:t.segments.map(p=>p.provider).join("+"),model:r,inputTokens:l.input_tokens,outputTokens:l.output_tokens,costUsd:t.segments.reduce((p,c)=>p+c.costUsd,0),userCostUsd:t.segments.reduce((p,c)=>p+c.userCostUsd,0),durationMs:Date.now()-i,stopReason:s||"error",fallbackChain:a,rateLimitHit:false,securityState:o});}};});function ht(n,e){if(e==="prefer-user"){let s=n.filter(i=>i.type==="claude-cli"),a=n.filter(i=>i.type!=="claude-cli");return [...s,...a]}if(e==="prefer-app"){let s=n.filter(i=>i.type==="claude-cli");return [...n.filter(i=>i.type!=="claude-cli"),...s]}let t=n.filter(s=>s.type===e),r=n.filter(s=>s.type!==e);return [...t,...r]}function gt(n){return (e,t)=>n.maxCostPerCall!==void 0&&t.estimatedCost>n.maxCostPerCall?"prefer-user":n.preferLocal?"ollama":"prefer-user"}var yt=C(()=>{});function ft(n){if(me[n])return me[n];let e=null;for(let t of Object.keys(me))n.startsWith(t)&&(e===null||t.length>e.length)&&(e=t);return e!==null?me[e]:[3,15]}var me,_t=C(()=>{me={"claude-fable-5":[10,50],"claude-mythos-5":[10,50],"claude-opus-5-5":[4,20],"claude-opus-5":[5,25],"claude-opus-4-8":[5,25],"claude-opus-4-7":[5,25],"claude-opus-4-6":[5,25],"claude-opus-4-5":[5,25],"claude-opus-4":[15,75],"claude-sonnet-5":[2,10],"claude-sonnet-4":[3,15],"claude-haiku-5-5":[.1,.5],"claude-haiku-4-5":[1,5],"claude-3-5-haiku":[.8,4],"claude-3-haiku":[.25,1.25],"kimi-k3":[3,15],"kimi-k2.7-code":[.95,4],"kimi-for-coding":[.95,4],"gpt-4o":[2.5,10],"gpt-4o-mini":[.15,.6],"gpt-4-turbo":[10,30],"gpt-3.5-turbo":[.5,1.5],llama:[0,0],mistral:[0,0],codellama:[0,0]};});function bt(n){let e=0;for(let o of n.messages)if(typeof o.content=="string")e+=o.content.length;else if(Array.isArray(o.content))for(let l of o.content)l.type==="text"&&l.text&&(e+=l.text.length);n.system&&(e+=n.system.length);let t=Math.ceil(e/4),r=Math.min(n.max_tokens||1024,4096),[s,a]=ft(n.model),i=(t*s+r*a)/1e6;return {estimatedInputTokens:t,estimatedCost:Math.round(i*1e4)/1e4,model:n.model,provider:""}}var Et=C(()=>{_t();});var he,vt=C(()=>{he=class{endpoint;enabled;keyId;lineageBuffer=new Map;unsubscribers=[];constructor(e){this.endpoint=e.endpoint||"https://api.inference-relay.com/v1/events",this.enabled=e.enabled??true,this.keyId=e.keyId||"";}subscribeToEngine(e){let t=s=>this.bufferLineageEvent(s),r=s=>{s.kind==="stream_complete"&&this.flushLineageForCall(s);};e.engineEvents.onTyped("segment_start",t),e.engineEvents.onTyped("segment_complete",t),e.engineEvents.onTyped("mid_stream_failover_attempt",t),e.engineEvents.onTyped("mid_stream_failover_success",t),e.engineEvents.onTyped("stream_complete",r),this.unsubscribers.push(()=>{e.engineEvents.offTyped("segment_start",t),e.engineEvents.offTyped("segment_complete",t),e.engineEvents.offTyped("mid_stream_failover_attempt",t),e.engineEvents.offTyped("mid_stream_failover_success",t),e.engineEvents.offTyped("stream_complete",r);});}unsubscribe(){for(let e of this.unsubscribers)e();this.unsubscribers=[],this.lineageBuffer.clear();}bufferLineageEvent(e){let t=this.lineageBuffer.get(e.callId)??[];t.push(e),this.lineageBuffer.set(e.callId,t);}flushLineageForCall(e){let t=this.lineageBuffer.get(e.callId)??[];this.lineageBuffer.delete(e.callId);let r={timestamp:e.ts,provider:e.provider,model:e.model,inputTokens:e.inputTokens,outputTokens:e.outputTokens,costUsd:e.costUsd,userCostUsd:e.userCostUsd,durationMs:e.durationMs,stopReason:e.stopReason,fallbackChain:e.fallbackChain,rateLimitHit:e.rateLimitHit,securityState:e.securityState,stitched:e.stitched,segments:e.segments,lineage:t.map(s=>s.id),promptContent:false,completionContent:false};this.report(r);}report(e){!this.enabled||!this.keyId||fetch(this.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({keyId:this.keyId,provider:e.provider,model:e.model,inputTokens:e.inputTokens,outputTokens:e.outputTokens,costUsd:e.costUsd,...e.userCostUsd!==void 0?{userCostUsd:e.userCostUsd}:{},durationMs:e.durationMs,fallback:e.fallbackChain.length>1,timestamp:e.timestamp,...e.stitched?{stitched:true,segmentCount:e.segments?.length??0}:{},...e.lineage?{lineageIds:e.lineage}:{}})}).catch(()=>{});}};});async function ge(n,e){if(!n)return {valid:false,error:"License key required. Get one at inference-relay.com"};let t=H.get(n);if(t&&Date.now()-t.cachedAt<t.ttl)return t.result;let s=!H.has(n)?1e4:3e3,a=(e||on)+ln,i=async()=>{let p=new AbortController,c=setTimeout(()=>p.abort(),s);try{return await(await fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({key:n}),signal:p.signal})).json()}finally{clearTimeout(c);}},o;try{o=await i();}catch{try{if(t)throw new Error("cached answer stands in");o=await i();}catch{return t&&Date.now()-t.cachedAt<un?t.result:{valid:false,error:"License validation failed (network error). Visit inference-relay.com"}}}let l;if(o.jws)try{let{compactVerify:p,importSPKI:c}=await import('jose'),g=await c(dn,"RS256"),{payload:m}=await p(o.jws,g);l=JSON.parse(new TextDecoder().decode(m));}catch{return H.delete(n),{valid:false,error:"License validation signature invalid. Possible MITM \u2014 refusing to start."}}else if(l=o,l.valid)return H.delete(n),{valid:false,error:"License validation response not signed. Possible MITM."};return H.set(n,{result:l,cachedAt:Date.now(),ttl:l.valid?cn:6e4}),l}var on,ln,cn,un,dn,H,Oe,ye,Ct=C(()=>{ve();Je();Ze();rt();st();Me();te();yt();Et();Re();vt();on="https://api.inference-relay.com",ln="/v1/validate",cn=1440*60*1e3,un=10080*60*1e3,dn=`-----BEGIN PUBLIC KEY-----
16
+ ${e}`:e}function ht(n){let e=0;for(let t of n.content)t.type==="text"?e+=t.text.length:t.type==="tool_use"&&(e+=(t._partialJson||"").length);return e}function cn(n){return Math.max(0,n.content.length-1)}async function*un(n){for await(let e of n)await new Promise(t=>setTimeout(t,50+Math.random()*50)),yield e;}var gt,ct,F,de,pe,Me=v(()=>{Ce();ot();xe();Pe();we();gt=200;ct=new Set(["anthropic-api","openai-api","ollama"]),F=class extends Error{code="ALL_PROVIDERS_FAILED";fallbackChain;constructor(e){super(`All providers failed. Chain: ${e.join(" \u2192 ")}`),this.name="RelayError",this.fallbackChain=e;}},de=class extends F{constructor(e){super(e);}};pe=class n{healthMap=new Map;engineEvents=new le;static UNHEALTHY_TTL_DEFAULT_MS=300*1e3;static UNHEALTHY_TTL_AUTH_MS=30*1e3;getHealthStatus(e){let t=this.healthMap.get(e);if(!t)return "healthy";let r=t.ttlMs??n.UNHEALTHY_TTL_DEFAULT_MS;if(t.status==="unhealthy"&&Date.now()-t.updatedAt>=r){let s=Date.now()-t.updatedAt;return this.healthMap.delete(e),I("engine.recovered",{providerType:e,ageMs:s,ttlMs:r}),"healthy"}return t.status}markUnhealthy(e,t,r){this.healthMap.set(e,{status:"unhealthy",lastError:t,updatedAt:Date.now(),ttlMs:r}),I("engine.unhealthy",{providerType:e,reason:t,ttlMs:r});}markDegraded(e,t){this.healthMap.set(e,{status:"degraded",lastError:t,updatedAt:Date.now()});}markHealthy(e){this.healthMap.set(e,{status:"healthy",updatedAt:Date.now()});}resetHealth(){this.healthMap.clear();}async execute(e,t,r){let s=dt(t),a=[],i=ut(e),o=randomUUID(),l=Date.now();for(let p of s){let c=p.type;if(this.getHealthStatus(c)==="unhealthy"){a.push(`${c}:skipped:unhealthy`);continue}if(i&&!p.supportsMultimodal){a.push(`${c}:skipped:no_multimodal`);continue}let m=Le(e.model);if(m&&m!==c&&ct.has(c)){a.push(`${c}:skipped:wrong_provider`);continue}let y=r?.maxSameProviderRetries??2,b=0,d=null,f=false;for(;!f;)try{let u=await p.execute(e,{signal:r?.signal});return f=!0,this.markHealthy(c),b>0&&a.push(`${c}:retry_success:${b}`),a.push(`${c}:success`),this.emitEngineEvent({kind:"stream_complete",callId:o,id:randomUUID(),ts:Date.now(),stitched:!1,segments:[{provider:c,inputTokens:u.usage.input_tokens,outputTokens:u.usage.output_tokens,costUsd:u.costUsd,userCostUsd:u.userCostUsd??0}],provider:c,model:u.model,inputTokens:u.usage.input_tokens,outputTokens:u.usage.output_tokens,costUsd:u.costUsd,userCostUsd:u.userCostUsd,durationMs:u.durationMs??Date.now()-l,stopReason:u.stop_reason,fallbackChain:a,rateLimitHit:!1,securityState:r?.licenseState}),{...u,fallbackChain:a}}catch(u){if(u?.name==="AbortError"||r?.signal?.aborted)throw u;if(ue(u)==="transient"&&b<y){b++;let R=250*Math.pow(2,b-1);I("engine.transient-retry",{id:c,attempt:b,backoffMs:R,msg:String(u?.message||"").slice(0,120)}),a.push(`${c}:retry:${b}`),await new Promise(E=>setTimeout(E,R));continue}d=u;break}if(!f){let u=d;switch(ue(u)){case "rate_limited":p.reportRateLimit({provider:c,utilization:1,resetsAt:Date.now()+6e4}),this.markDegraded(c,"rate_limited"),a.push(`${c}:failed:rate_limited`);break;case "auth_failed":this.markUnhealthy(c,"auth_failed",n.UNHEALTHY_TTL_AUTH_MS),a.push(`${c}:failed:auth_failed`);break;case "timeout":a.push(`${c}:failed:timeout`);break;case "provider_incompatible":a.push(`${c}:incompatible`);break;case "gateway_unavailable":this.markUnhealthy(c,"gateway_unavailable"),a.push(ce(c,u));break;case "request_too_large":a.push(`${c}:failed:request_too_large`);break;case "transient":this.markDegraded(c,"transient_exhausted"),a.push(`${c}:failed:transient_exhausted`);break;default:a.push(ce(c,u));break}if(r?.subscriptionOnly&&c==="claude-cli"){a.push("subscription_only:cascade_halted");break}}}throw I("engine.cascade-exhausted",{chain:a,mode:"execute"}),lt(a)?new de(a):new F(a)}async stream(e,t,r){let s=randomUUID(),a=dt(t),i=ut(e),o=Date.now(),l=[],p=null,c=null;for(let u of a){let h=u.type;if(this.getHealthStatus(h)==="unhealthy"){l.push(`${h}:skipped:unhealthy`);continue}if(i&&!u.supportsMultimodal){l.push(`${h}:skipped:no_multimodal`);continue}if(!u.supportsStreaming){l.push(`${h}:skipped:no_streaming`);continue}let R=Le(e.model);if(R&&R!==h&&ct.has(h)){l.push(`${h}:skipped:wrong_provider`);continue}try{c=await u.streamRaw(e,{signal:r?.signal}),p=u,l.push(`${h}:success`);break}catch(E){if(E?.name==="AbortError"||r?.signal?.aborted)throw E;switch(ue(E)){case "rate_limited":u.reportRateLimit({provider:h,utilization:1,resetsAt:Date.now()+6e4}),this.markDegraded(h,"rate_limited"),l.push(`${h}:failed:rate_limited`);break;case "auth_failed":this.markUnhealthy(h,"auth_failed",n.UNHEALTHY_TTL_AUTH_MS),l.push(`${h}:failed:auth_failed`);break;case "timeout":l.push(`${h}:failed:timeout`);break;case "provider_incompatible":l.push(`${h}:incompatible`);break;case "gateway_unavailable":this.markUnhealthy(h,"gateway_unavailable"),l.push(ce(h,E));break;case "request_too_large":l.push(`${h}:failed:request_too_large`);break;case "transient":this.markDegraded(h,"transient_exhausted"),l.push(`${h}:failed:transient_exhausted`);break;default:l.push(ce(h,E));break}if(r?.subscriptionOnly&&h==="claude-cli"){l.push("subscription_only:cascade_halted");break}}}if(!p||!c)throw I("engine.cascade-exhausted",{chain:l,mode:"stream"}),lt(l)?new de(l):new F(l);let m=this,y=r?.maxMidStreamFailovers??2,b=new Set([p]);async function*d(){let u=p,h=c[Symbol.asyncIterator](),R={role:"assistant",content:[]},E={segments:[]},k=pt(u.type);E.segments.push(k);let Fe=0,z=null,X=false,ve=y,V="",Y="";for(m.emitEngineEvent({kind:"segment_start",callId:s,id:randomUUID(),ts:Date.now(),provider:u.type});;)try{for(;;){let T=await h.next();if(T.done)break;let N=T.value,x=an(N,Fe,R,X,z);if(x.action==="suppress"){"coalesceMode"in x&&(z=x.coalesceMode),x.clearedJustFailedOver&&(X=!1);continue}x.coalesceModeCleared&&(z=null),x.clearedJustFailedOver&&(X=!1);let A=x.event;if(sn(R,A),A.type==="message_start"){if(E.segments.length>1)continue;V=A.message?.model||V,A.message?.usage?.input_tokens!=null&&(k.inputTokens=A.message.usage.input_tokens);}if(A.type==="message_delta"&&(A.delta?.stop_reason&&(Y=A.delta.stop_reason),A.usage)){rn(k,u.type,A.usage),yield {...A,usage:void 0};continue}if(A.type==="message_stop")break;yield A;}if(R.content.length===0&&k.outputTokens===0)throw new Error("stream ended without producing any content");m.markHealthy(u.type),m.emitEngineEvent({kind:"segment_complete",callId:s,id:randomUUID(),ts:Date.now(),provider:u.type,usage:{...k}});let P=mt(E.segments);yield {type:"message_delta",delta:{stop_reason:Y||"end_turn"},usage:P},yield {type:"message_stop"},m.emitEngineEvent({kind:"stream_complete",callId:s,id:randomUUID(),ts:Date.now(),stitched:E.segments.length>1,segments:E.segments.map(T=>({...T})),provider:E.segments.map(T=>T.provider).join("+"),model:V,inputTokens:P.input_tokens,outputTokens:P.output_tokens,costUsd:E.segments.reduce((T,N)=>T+N.costUsd,0),userCostUsd:E.segments.reduce((T,N)=>T+N.userCostUsd,0),durationMs:Date.now()-o,stopReason:Y||"end_turn",fallbackChain:l,rateLimitHit:!1,securityState:r?.licenseState});return}catch(P){if(P?.name==="AbortError"||r?.signal?.aborted)throw P;let T=ue(P);try{await h.return?.();}catch{}if(m.markUnhealthy(u.type,String(P)),m.emitEngineEvent({kind:"mid_stream_failover_attempt",callId:s,id:randomUUID(),ts:Date.now(),from:u.type,bytesBuffered:ht(R),errorClass:T,retriesLeft:ve}),l.push(`${u.type}:partial(${ht(R)}b)`),ve<=0)throw m.emitTerminalExhaustion(s,E,V,Y,l,o,r?.licenseState),P;let N=on(R.content),x=[...e.messages,{role:"assistant",content:N}],A=null,Q=null,He=u;for(;;){let O=m.nextHealthyProvider(a,He,i,b);if(!O)break;He=O,b.add(O);let Ot={...e,messages:x,...O.type!=="anthropic-api"&&O.type!=="claude-cli"?{system:ln(e.system,"[SYSTEM]: CONTINUE_LAST_RESPONSE_WITHOUT_REPEATING")}:{}};try{Q=await O.streamRaw(Ot,{signal:r?.signal}),A=O;break}catch(Be){m.markUnhealthy(O.type,String(Be)),l.push(`${O.type}:failed_connect:${String(Be).slice(0,gt)}`);}}if(!A||!Q)throw m.emitTerminalExhaustion(s,E,V,Y,l,o,r?.licenseState),P;l.push(`${A.type}:stitched`),m.emitEngineEvent({kind:"mid_stream_failover_success",callId:s,id:randomUUID(),ts:Date.now(),from:u.type,to:A.type}),Fe=cn(R)+1,ve--,u=A,h=Q[Symbol.asyncIterator](),X=true,z=null,k=pt(u.type),E.segments.push(k),m.emitEngineEvent({kind:"segment_start",callId:s,id:randomUUID(),ts:Date.now(),provider:u.type});}}let f=d();return r?.licenseState==="SEC_DEGRADED"&&(f=un(f)),Z(f)}nextHealthyProvider(e,t,r,s){let a=e.indexOf(t);if(a===-1)return null;for(let i=a+1;i<e.length;i++){let o=e[i];if(!s.has(o)&&!(r&&!o.supportsMultimodal)&&o.supportsStreaming)return o}return null}emitEngineEvent(e){this.engineEvents.emitTyped(e);}emitTerminalExhaustion(e,t,r,s,a,i,o){let l=mt(t.segments);this.emitEngineEvent({kind:"stream_complete",callId:e,id:randomUUID(),ts:Date.now(),stitched:t.segments.length>1,segments:t.segments.map(p=>({...p})),provider:t.segments.map(p=>p.provider).join("+"),model:r,inputTokens:l.input_tokens,outputTokens:l.output_tokens,costUsd:t.segments.reduce((p,c)=>p+c.costUsd,0),userCostUsd:t.segments.reduce((p,c)=>p+c.userCostUsd,0),durationMs:Date.now()-i,stopReason:s||"error",fallbackChain:a,rateLimitHit:false,securityState:o});}};});function yt(n,e){if(e==="prefer-user"){let s=n.filter(i=>i.type==="claude-cli"),a=n.filter(i=>i.type!=="claude-cli");return [...s,...a]}if(e==="prefer-app"){let s=n.filter(i=>i.type==="claude-cli");return [...n.filter(i=>i.type!=="claude-cli"),...s]}let t=n.filter(s=>s.type===e),r=n.filter(s=>s.type!==e);return [...t,...r]}function ft(n){return (e,t)=>n.maxCostPerCall!==void 0&&t.estimatedCost>n.maxCostPerCall?"prefer-user":n.preferLocal?"ollama":"prefer-user"}var _t=v(()=>{});function bt(n){if(me[n])return me[n];let e=null;for(let t of Object.keys(me))n.startsWith(t)&&(e===null||t.length>e.length)&&(e=t);return e!==null?me[e]:[3,15]}var me,Et=v(()=>{me={"claude-fable-5":[10,50],"claude-mythos-5":[10,50],"claude-opus-5-5":[4,20],"claude-opus-5":[5,25],"claude-opus-4-8":[5,25],"claude-opus-4-7":[5,25],"claude-opus-4-6":[5,25],"claude-opus-4-5":[5,25],"claude-opus-4":[15,75],"claude-sonnet-5":[2,10],"claude-sonnet-4":[3,15],"claude-haiku-5-5":[.1,.5],"claude-haiku-4-5":[1,5],"claude-3-5-haiku":[.8,4],"claude-3-haiku":[.25,1.25],"kimi-k3":[3,15],"kimi-k2.7-code":[.95,4],"kimi-for-coding":[.95,4],"gpt-4o":[2.5,10],"gpt-4o-mini":[.15,.6],"gpt-4-turbo":[10,30],"gpt-3.5-turbo":[.5,1.5],llama:[0,0],mistral:[0,0],codellama:[0,0]};});function vt(n){let e=0;for(let o of n.messages)if(typeof o.content=="string")e+=o.content.length;else if(Array.isArray(o.content))for(let l of o.content)l.type==="text"&&l.text&&(e+=l.text.length);n.system&&(e+=n.system.length);let t=Math.ceil(e/4),r=Math.min(n.max_tokens||1024,4096),[s,a]=bt(n.model),i=(t*s+r*a)/1e6;return {estimatedInputTokens:t,estimatedCost:Math.round(i*1e4)/1e4,model:n.model,provider:""}}var Rt=v(()=>{Et();});var he,Ct=v(()=>{he=class{endpoint;enabled;keyId;lineageBuffer=new Map;unsubscribers=[];constructor(e){this.endpoint=e.endpoint||"https://api.inference-relay.com/v1/events",this.enabled=e.enabled??true,this.keyId=e.keyId||"";}subscribeToEngine(e){let t=s=>this.bufferLineageEvent(s),r=s=>{s.kind==="stream_complete"&&this.flushLineageForCall(s);};e.engineEvents.onTyped("segment_start",t),e.engineEvents.onTyped("segment_complete",t),e.engineEvents.onTyped("mid_stream_failover_attempt",t),e.engineEvents.onTyped("mid_stream_failover_success",t),e.engineEvents.onTyped("stream_complete",r),this.unsubscribers.push(()=>{e.engineEvents.offTyped("segment_start",t),e.engineEvents.offTyped("segment_complete",t),e.engineEvents.offTyped("mid_stream_failover_attempt",t),e.engineEvents.offTyped("mid_stream_failover_success",t),e.engineEvents.offTyped("stream_complete",r);});}unsubscribe(){for(let e of this.unsubscribers)e();this.unsubscribers=[],this.lineageBuffer.clear();}bufferLineageEvent(e){let t=this.lineageBuffer.get(e.callId)??[];t.push(e),this.lineageBuffer.set(e.callId,t);}flushLineageForCall(e){let t=this.lineageBuffer.get(e.callId)??[];this.lineageBuffer.delete(e.callId);let r={timestamp:e.ts,provider:e.provider,model:e.model,inputTokens:e.inputTokens,outputTokens:e.outputTokens,costUsd:e.costUsd,userCostUsd:e.userCostUsd,durationMs:e.durationMs,stopReason:e.stopReason,fallbackChain:e.fallbackChain,rateLimitHit:e.rateLimitHit,securityState:e.securityState,stitched:e.stitched,segments:e.segments,lineage:t.map(s=>s.id),promptContent:false,completionContent:false};this.report(r);}report(e){!this.enabled||!this.keyId||fetch(this.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({keyId:this.keyId,provider:e.provider,model:e.model,inputTokens:e.inputTokens,outputTokens:e.outputTokens,costUsd:e.costUsd,...e.userCostUsd!==void 0?{userCostUsd:e.userCostUsd}:{},durationMs:e.durationMs,fallback:e.fallbackChain.length>1,timestamp:e.timestamp,...e.stitched?{stitched:true,segmentCount:e.segments?.length??0}:{},...e.lineage?{lineageIds:e.lineage}:{}})}).catch(()=>{});}};});function At(){return {name:"inference-relay",version:ge,features:Ne}}var ge,Ne,kt=v(()=>{ge="1.6.10",Ne=Object.freeze({streamKeepsHistory:true,streamToolBlocks:true,streamBareToolNames:true});});async function ye(n,e){if(!n)return {valid:false,error:"License key required. Get one at inference-relay.com"};let t=H.get(n);if(t&&Date.now()-t.cachedAt<t.ttl)return t.result;let s=!H.has(n)?1e4:3e3,a=(e||dn)+pn,i=async()=>{let p=new AbortController,c=setTimeout(()=>p.abort(),s);try{return await(await fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({key:n}),signal:p.signal})).json()}finally{clearTimeout(c);}},o;try{o=await i();}catch{try{if(t)throw new Error("cached answer stands in");o=await i();}catch{return t&&Date.now()-t.cachedAt<hn?t.result:{valid:false,error:"License validation failed (network error). Visit inference-relay.com"}}}let l;if(o.jws)try{let{compactVerify:p,importSPKI:c}=await import('jose'),g=await c(gn,"RS256"),{payload:m}=await p(o.jws,g);l=JSON.parse(new TextDecoder().decode(m));}catch{return H.delete(n),{valid:false,error:"License validation signature invalid. Possible MITM \u2014 refusing to start."}}else if(l=o,l.valid)return H.delete(n),{valid:false,error:"License validation response not signed. Possible MITM."};return H.set(n,{result:l,cachedAt:Date.now(),ttl:l.valid?mn:6e4}),l}var dn,pn,mn,hn,gn,H,Ue,fe,wt=v(()=>{Re();Xe();tt();it();at();Me();te();_t();Rt();ke();Ct();kt();dn="https://api.inference-relay.com",pn="/v1/validate",mn=1440*60*1e3,hn=10080*60*1e3,gn=`-----BEGIN PUBLIC KEY-----
17
17
  MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzk88Bt9LZSmuSd8ulKqy
18
18
  EGNiPB+r8u1ZinBvMM4qX8dp4kzJEC/47L1RYrrxCphD05HToREjljbj+upH6rZH
19
19
  t6D/5funYPi2TO1IOSC6BRVRwMqqTmJGVJcLcG/WF3gTE+2UQ3q5EppWJCEKcz6x
@@ -21,4 +21,4 @@ kfynZEzOcLikoQALIxEjxRfi6g83wNJS+WBwAJQ68s7N9FHE3rkLzEqv3FJRP+ZR
21
21
  7lqwqIyuCLr9j9yc4XqF6VY9yooD2hyw/n1EVFejzjDgntWTqIkaCIXwh8lDzRrK
22
22
  Rxn07gcI6ea2Eym9sXh4xZLFudXfAT2DFsH/XboDUuMKAV1YHc1NsIGApesWe2M+
23
23
  UQIDAQAB
24
- -----END PUBLIC KEY-----`,H=new Map,Oe=new Set;ye=class n{providers=[];config;fallbackEngine;telemetryReporter;routingFn=null;license=null;licensePromise=null;licenseValidatedAt=0;callsSinceValidation=0;manifestDecryptor=new K;capProbeTimer=null;capProbeTicksRemaining=0;messages;constructor(e){if(this.config=e,this.fallbackEngine=new pe,this.telemetryReporter=new he({endpoint:e.endpoint?`${e.endpoint}/v1/events`:void 0,enabled:e.telemetry!==false,keyId:e.licenseKey}),this.telemetryReporter.subscribeToEngine(this.fallbackEngine),e.routing&&(this.routingFn=gt(e.routing)),e.providers)for(let s of e.providers){let a=typeof s=="string"?{type:s}:s,i=this.createProvider(a);i&&(a.priority!==void 0&&(i.priority=a.priority),this.providers.push(i));}let t=100,r=3600*1e3;this.messages={create:async(s,a)=>{let i=this.license&&(this.callsSinceValidation>=t||Date.now()-this.licenseValidatedAt>=r);if(i&&(this.license=null),!this.license){this.licensePromise||(this.licensePromise=ge(this.config.licenseKey,this.config.endpoint));try{this.license=await this.licensePromise;}finally{this.licensePromise=null;}if(this.licenseValidatedAt=Date.now(),this.callsSinceValidation=0,this.license.valid){if(this.license.capExceeded)throw this.startCapProbe(),new $({tier:this.license.tier||"solo",baseCap:this.license.baseCap??this.license.usageCap??null,topUps:this.license.topUpGrants??0,effectiveCap:this.license.usageCap??null,usedThisCycle:this.license.usageThisMonth??0});!i&&!Oe.has(this.config.licenseKey)&&(Oe.add(this.config.licenseKey),console.log(`[inference-relay] LICENSE AUTHORIZED [${(this.license.tier||"unknown").toUpperCase()} TIER] \u2014 READY.`));}else throw new Error(`[inference-relay] ${this.license.error||"License key invalid or expired. Visit inference-relay.com"}`)}return this.callsSinceValidation++,s.stream?this.streamMessage(s,a):this.executeMessage(s,a)}};}startCapProbe(){if(this.capProbeTimer!==null)return;let e=15e3,t=20,r=4;this.capProbeTicksRemaining=t;let s=async()=>{this.capProbeTicksRemaining-=1;let a=Math.ceil(this.capProbeTicksRemaining*e/6e4);this.capProbeTicksRemaining>0&&this.capProbeTicksRemaining%r===0&&console.log(`[inference-relay] cap exceeded \u2014 checking for top-up every 15s (${a}m remaining)`),this.config.licenseKey&&H.delete(this.config.licenseKey);try{let i=await this.probeValidate();if(i.valid&&i.capExceeded===!1){console.log("[inference-relay] cap cleared \u2014 probe exiting, inference resuming"),this.license=i,this.licenseValidatedAt=Date.now(),this.callsSinceValidation=0,this.stopCapProbe();return}}catch{}this.capProbeTicksRemaining<=0&&(console.log("[inference-relay] cap probe exhausted (5 min) \u2014 stopping"),this.stopCapProbe());};this.capProbeTimer=setInterval(s,e),typeof this.capProbeTimer.unref=="function"&&this.capProbeTimer.unref();}async probeValidate(){return ge(this.config.licenseKey,this.config.endpoint)}stopCapProbe(){this.capProbeTimer!==null&&(clearInterval(this.capProbeTimer),this.capProbeTimer=null),this.capProbeTicksRemaining=0;}static async autoDetect(e){let t=[],r=await B();r.available&&r.authenticated!==false&&t.push({type:"claude-cli",priority:1});let s=e?.subscriptionOnly===true||process.env.IR_SUBSCRIPTION_ONLY==="1";return process.env.ANTHROPIC_API_KEY&&!s&&t.push({type:"anthropic-api",priority:2,apiKey:process.env.ANTHROPIC_API_KEY}),new n({licenseKey:e?.licenseKey||process.env.IR_LICENSE_KEY||"",providers:t,fallback:e?.fallback??true,subscriptionOnly:s,...e})}async warmup(){let e=this.providers.find(t=>t.type==="claude-cli");e&&"warmup"in e&&typeof e.warmup=="function"&&await e.warmup();}resetHealth(){this.fallbackEngine.resetHealth();}markHealthy(e){this.fallbackEngine.markHealthy(e);}dispose(){this.providers=[],this.config.licenseKey&&(H.delete(this.config.licenseKey),Oe.delete(this.config.licenseKey)),this.license=null,this.licensePromise=null,this.callsSinceValidation=0,this.stopCapProbe(),this.telemetryReporter.unsubscribe(),this.manifestDecryptor.clearCache(),Be();}resolveProviders(e){if(!this.routingFn)return this.providers;let t=bt(e),r=this.routingFn(e,t);return ht(this.providers,r)}async executeMessage(e,t){let r=this.resolveProviders(e);return this.fallbackEngine.execute(e,r,{signal:t?.signal,licenseState:this.manifestDecryptor.getSecurityState(),subscriptionOnly:this.config.subscriptionOnly,maxSameProviderRetries:this.config.maxSameProviderRetries})}async streamMessage(e,t){let r=this.resolveProviders(e);return this.fallbackEngine.stream(e,r,{signal:t?.signal,licenseState:this.manifestDecryptor.getSecurityState(),subscriptionOnly:this.config.subscriptionOnly,maxSameProviderRetries:this.config.maxSameProviderRetries})}createProvider(e){switch(e.type){case "claude-cli":return new ne(this.config.licenseKey,{retryDelaysMs:this.config.gatewayRetryDelaysMs});case "kimi-cli":return new re(this.config.licenseKey,{retryDelaysMs:this.config.gatewayRetryDelaysMs});case "anthropic-api":return e.apiKey?new ie({apiKey:e.apiKey,baseUrl:e.baseUrl}):null;case "openai-api":return e.apiKey?new ae({apiKey:e.apiKey,baseUrl:e.baseUrl}):null;case "ollama":return new oe({baseUrl:e.baseUrl});default:return null}}};});var At=C(()=>{te();});var kt={};He(kt,{runVerify:()=>fn});function w(n,e){let t=n.padEnd(13);console.log(`${_("[ir]")} ${t}${e}`);}function _e(n){if(n instanceof $)return {label:"CAP_EXCEEDED",hint:"Monthly cap reached. Buy a top-up at https://inference-relay.com/dashboard/billing",code:1};if(n instanceof F)return {label:"ALL_PROVIDERS_FAILED",hint:`Fallback chain exhausted: ${n.fallbackChain.join(" \u2192 ")}`,code:1};if(!(n instanceof Error))return {label:"FAILED",hint:String(n).slice(0,120),code:1};let e=n.message.toLowerCase(),t=n.name.toLowerCase();return e.includes("keychain_access_denied")||e.includes("keychain access denied")?{label:"KEYCHAIN_DENIED",hint:'macOS denied keychain access. Re-run and click "Always Allow" on the prompt.',code:1}:e.includes("rate limit")||e.includes("429")||t.includes("ratelimit")?{label:"RATE_LIMITED",hint:"Claude subscription is currently rate-limited. Wait a minute and re-run.",code:1}:e.includes("auth")||e.includes("401")||e.includes("403")||e.includes("unauthorized")||e.includes("forbidden")?{label:"AUTH_FAILED",hint:"Claude CLI OAuth token rejected. Run `claude` to refresh, then re-run verify.",code:1}:e.includes("timeout")||e.includes("timed out")||e.includes("aborted")||e.includes("etimedout")||e.includes("econnrefused")||e.includes("econnreset")||t==="aborterror"||t==="timeouterror"?{label:"TIMEOUT",hint:`No response within ${J/1e3}s. Network issue, hung CLI, or keychain prompt waiting for input. Try \`curl -I api.anthropic.com\` to test connectivity.`,code:1}:e.includes("empty response")||e.includes("returned empty")?{label:"EMPTY_RESPONSE",hint:"CLI returned an empty body \u2014 possible truncation, model error, or stale CLI version.",code:1}:{label:"FAILED",hint:n.message.slice(0,120),code:1}}function Rt(n){if(n.usageCap!==null&&n.usageCap!==void 0){let e=n.usageThisMonth??0,t=n.usageCap;if(t===0)console.log(_(` Usage: ${e.toLocaleString()} (unmetered)`));else {let r=Math.round(e/t*1e3)/10;console.log(_(` Usage: ${e.toLocaleString()} / ${t.toLocaleString()} (${r}%)`));}}}async function fn(n=process.argv.slice(2),e=process.env){let t=n.includes("--credentials-only"),r=e.IR_LICENSE_KEY;if(!r)return console.error(M("[ir] IR_LICENSE_KEY environment variable is not set.")),console.error(" Get a key at https://inference-relay.com/pricing"),console.error(" Then: export IR_LICENSE_KEY=ir_live_xxxx"),2;if(!/^ir_(live|test)_[a-f0-9]{32}$/.test(r))return console.error(M("[ir] IR_LICENSE_KEY does not look like a valid key.")),console.error(" Expected format: ir_live_<32 hex chars>"),console.error(` Got: ${r.slice(0,8)}... (${r.length} chars)`),2;let s;try{s=await ge(r);}catch(b){return w("IDENTITY:",M("FAILED")),console.error(` ${b.message||"unknown error"}`),1}if(!s.valid)return w("IDENTITY:",M("REJECTED")),s.error&&console.error(` ${s.error}`),1;w("IDENTITY:",j("VALIDATED"));let a=(s.tier??"unknown").toUpperCase();w("TIER:",j(a));let i;try{i=await B();}catch{i=null;}if(!i||!i.available)return w("RELAY:",fe("INACTIVE")),console.log(_(" Claude CLI not detected. The relay will fall back")),console.log(_(" to direct API providers using your API keys.")),console.log(_(" For zero-cost routing, install Claude Code:")),console.log(_(" npm install -g @anthropic-ai/claude-code")),1;if(!i.authenticated)return w("RELAY:",fe("CLI_UNAUTHED")),console.log(_(" Claude CLI is installed but not authenticated.")),console.log(_(" Run `claude` once to sign in, then re-run verify.")),1;if(i.versionWarning&&console.log(fe(` Warning: ${i.versionWarning}`)),t)return w("RELAY:",j("READY")),console.log(_(" Credentials present. Round-trip skipped (--credentials-only).")),i.cliVersion&&console.log(_(` Claude CLI: v${i.cliVersion}`)),i.subscriptionType&&i.subscriptionType!=="unknown"&&console.log(_(` Tier: ${i.subscriptionType}`)),Rt(s),0;let o=new ye({licenseKey:r,providers:[{type:"claude-cli",priority:1}],fallback:false,telemetry:false}),l=new AbortController,p=setTimeout(()=>l.abort(),J),c=Date.now(),g;try{g=await o.messages.create(mn,{signal:l.signal});}catch(b){clearTimeout(p),o.dispose();let{label:d,hint:f}=_e(b);return w("RELAY:",M(`DEGRADED \u2014 ${d}`)),console.log(_(` ${f}`)),i.cliVersion&&console.log(_(` Claude CLI: v${i.cliVersion}`)),1}if(clearTimeout(p),process.platform==="win32"){let b=new AbortController,d=setTimeout(()=>b.abort(),J);try{await o.messages.create(hn,{signal:b.signal});}catch(E){clearTimeout(d),o.dispose();let{hint:k}=_e(E);return w("RELAY:",M("DEGRADED \u2014 LONG_PROMPT_FAILED")),console.log(_(` Long-system-prompt round-trip failed: ${k}`)),console.log(_(" This is the cmd.exe arg-length regression class.")),console.log(_(" Ensure inference-relay is at version >=1.5.3 (closes the bug).")),i.cliVersion&&console.log(_(` Claude CLI: v${i.cliVersion}`)),1}clearTimeout(d);let f=new AbortController,u=setTimeout(()=>f.abort(),J);try{await o.messages.create(gn,{signal:f.signal});}catch(E){clearTimeout(u),o.dispose();let{hint:k}=_e(E);return w("RELAY:",M("DEGRADED \u2014 TOOLS_DISPATCH_FAILED")),console.log(_(` Tools round-trip failed: ${k}`)),console.log(_(" The claude-cli provider couldn't forward params.tools.")),console.log(_(" Ensure inference-relay is at version >=1.6.0 (closes the bug).")),i.cliVersion&&console.log(_(` Claude CLI: v${i.cliVersion}`)),1}clearTimeout(u);let h=new AbortController,v=setTimeout(()=>h.abort(),J);try{await o.messages.create(yn,{signal:h.signal});}catch(E){clearTimeout(v),o.dispose();let{hint:k}=_e(E);return w("RELAY:",M("DEGRADED \u2014 MULTITURN_DISPATCH_FAILED")),console.log(_(` Multi-turn round-trip failed: ${k}`)),console.log(_(" The CLI rejected an assistant-role stream-json envelope.")),console.log(_(" Ensure inference-relay is at version >=1.6.0 (closes the bug),")),console.log(_(" OR ensure Claude CLI version is >=2.1.x (stream-json input floor).")),i.cliVersion&&console.log(_(` Claude CLI: v${i.cliVersion}`)),1}clearTimeout(v);}o.dispose();let m=Date.now()-c;return g.fallbackChain?.[0]?.startsWith("claude-cli:success")?(w("RELAY:",j("ACTIVE")),console.log(_(` Round-trip: ${m}ms via ${g.provider}`)),console.log(_(` Model echo: ${g.model}`)),console.log(_(` Tokens: ${g.usage.input_tokens} in / ${g.usage.output_tokens} out`)),i.cliVersion&&console.log(_(` Claude CLI: v${i.cliVersion}`)),console.log(_(` Multimodal: ${j("\u2713")} via claude-cli (subscription)`)),i.subscriptionType&&i.subscriptionType!=="unknown"&&console.log(_(` Tier: ${i.subscriptionType}`)),Rt(s),0):(w("RELAY:",fe("UNEXPECTED")),console.log(_(` Native Gateway did not handle the call. Chain: ${g.fallbackChain?.join(" \u2192 ")}`)),1)}var pn,be,j,M,fe,_,J,mn,hn,gn,yn,wt=C(()=>{Ct();Me();ve();At();pn=process.stdout.isTTY===true,be=(n,e)=>pn?`\x1B[${n}m${e}\x1B[0m`:e,j=n=>be("32",n),M=n=>be("31",n),fe=n=>be("33",n),_=n=>be("2",n);J=15e3,mn={model:"claude-haiku-4-5",max_tokens:1,messages:[{role:"user",content:"Reply with exactly the single character k and nothing else."}]},hn={model:"claude-haiku-4-5",max_tokens:1,system:"Sentence. ".repeat(800),messages:[{role:"user",content:"Reply with exactly the single character k and nothing else."}]},gn={model:"claude-haiku-4-5",max_tokens:50,messages:[{role:"user",content:"Reply with the single word: ok"}],tools:[{type:"web_search_20250305",name:"web_search",max_uses:1}]},yn={model:"claude-haiku-4-5",max_tokens:10,messages:[{role:"user",content:"Reply with: hello"},{role:"assistant",content:[{type:"text",text:"hello"}]},{role:"user",content:"Reply with: ok"}]};});var Tt={verify:async()=>{let{runVerify:n}=await Promise.resolve().then(()=>(wt(),kt));return n()}};function It(){console.error("Usage: inference-relay <command>"),console.error(""),console.error("Commands:"),console.error(" verify Smoke-test your installation (license + relay availability)"),console.error(""),console.error("Docs: https://inference-relay.com/docs");}var O=process.argv[2];(!O||O==="--help"||O==="-h")&&(It(),process.exit(O?0:2));O in Tt||(console.error(`Unknown command: ${O}`),console.error(""),It(),process.exit(1));Tt[O]().then(n=>process.exit(n)).catch(n=>{console.error(`[ir] failed to run command "${O}":`),console.error(n),process.exit(99);});
24
+ -----END PUBLIC KEY-----`,H=new Map,Ue=new Set;fe=class n{static version=ge;get version(){return ge}get features(){return Ne}hello(){return At()}providers=[];config;fallbackEngine;telemetryReporter;routingFn=null;license=null;licensePromise=null;licenseValidatedAt=0;callsSinceValidation=0;manifestDecryptor=new K;capProbeTimer=null;capProbeTicksRemaining=0;messages;constructor(e){if(this.config=e,this.fallbackEngine=new pe,this.telemetryReporter=new he({endpoint:e.endpoint?`${e.endpoint}/v1/events`:void 0,enabled:e.telemetry!==false,keyId:e.licenseKey}),this.telemetryReporter.subscribeToEngine(this.fallbackEngine),e.routing&&(this.routingFn=ft(e.routing)),e.providers)for(let s of e.providers){let a=typeof s=="string"?{type:s}:s,i=this.createProvider(a);i&&(a.priority!==void 0&&(i.priority=a.priority),this.providers.push(i));}let t=100,r=3600*1e3;this.messages={create:async(s,a)=>{let i=this.license&&(this.callsSinceValidation>=t||Date.now()-this.licenseValidatedAt>=r);if(i&&(this.license=null),!this.license){this.licensePromise||(this.licensePromise=ye(this.config.licenseKey,this.config.endpoint));try{this.license=await this.licensePromise;}finally{this.licensePromise=null;}if(this.licenseValidatedAt=Date.now(),this.callsSinceValidation=0,this.license.valid){if(this.license.capExceeded)throw this.startCapProbe(),new B({tier:this.license.tier||"solo",baseCap:this.license.baseCap??this.license.usageCap??null,topUps:this.license.topUpGrants??0,effectiveCap:this.license.usageCap??null,usedThisCycle:this.license.usageThisMonth??0});!i&&!Ue.has(this.config.licenseKey)&&(Ue.add(this.config.licenseKey),console.log(`[inference-relay] LICENSE AUTHORIZED [${(this.license.tier||"unknown").toUpperCase()} TIER] \u2014 READY.`));}else throw new Error(`[inference-relay] ${this.license.error||"License key invalid or expired. Visit inference-relay.com"}`)}return this.callsSinceValidation++,s.stream?this.streamMessage(s,a):this.executeMessage(s,a)}};}startCapProbe(){if(this.capProbeTimer!==null)return;let e=15e3,t=20,r=4;this.capProbeTicksRemaining=t;let s=async()=>{this.capProbeTicksRemaining-=1;let a=Math.ceil(this.capProbeTicksRemaining*e/6e4);this.capProbeTicksRemaining>0&&this.capProbeTicksRemaining%r===0&&console.log(`[inference-relay] cap exceeded \u2014 checking for top-up every 15s (${a}m remaining)`),this.config.licenseKey&&H.delete(this.config.licenseKey);try{let i=await this.probeValidate();if(i.valid&&i.capExceeded===!1){console.log("[inference-relay] cap cleared \u2014 probe exiting, inference resuming"),this.license=i,this.licenseValidatedAt=Date.now(),this.callsSinceValidation=0,this.stopCapProbe();return}}catch{}this.capProbeTicksRemaining<=0&&(console.log("[inference-relay] cap probe exhausted (5 min) \u2014 stopping"),this.stopCapProbe());};this.capProbeTimer=setInterval(s,e),typeof this.capProbeTimer.unref=="function"&&this.capProbeTimer.unref();}async probeValidate(){return ye(this.config.licenseKey,this.config.endpoint)}stopCapProbe(){this.capProbeTimer!==null&&(clearInterval(this.capProbeTimer),this.capProbeTimer=null),this.capProbeTicksRemaining=0;}static async autoDetect(e){let t=[],r=await $();r.available&&r.authenticated!==false&&t.push({type:"claude-cli",priority:1});let s=e?.subscriptionOnly===true||process.env.IR_SUBSCRIPTION_ONLY==="1";return process.env.ANTHROPIC_API_KEY&&!s&&t.push({type:"anthropic-api",priority:2,apiKey:process.env.ANTHROPIC_API_KEY}),new n({licenseKey:e?.licenseKey||process.env.IR_LICENSE_KEY||"",providers:t,fallback:e?.fallback??true,subscriptionOnly:s,...e})}async warmup(){let e=this.providers.find(t=>t.type==="claude-cli");e&&"warmup"in e&&typeof e.warmup=="function"&&await e.warmup();}resetHealth(){this.fallbackEngine.resetHealth();}markHealthy(e){this.fallbackEngine.markHealthy(e);}dispose(){this.providers=[],this.config.licenseKey&&(H.delete(this.config.licenseKey),Ue.delete(this.config.licenseKey)),this.license=null,this.licensePromise=null,this.callsSinceValidation=0,this.stopCapProbe(),this.telemetryReporter.unsubscribe(),this.manifestDecryptor.clearCache(),Ye();}resolveProviders(e){if(!this.routingFn)return this.providers;let t=vt(e),r=this.routingFn(e,t);return yt(this.providers,r)}async executeMessage(e,t){let r=this.resolveProviders(e);return this.fallbackEngine.execute(e,r,{signal:t?.signal,licenseState:this.manifestDecryptor.getSecurityState(),subscriptionOnly:this.config.subscriptionOnly,maxSameProviderRetries:this.config.maxSameProviderRetries})}async streamMessage(e,t){let r=this.resolveProviders(e);return this.fallbackEngine.stream(e,r,{signal:t?.signal,licenseState:this.manifestDecryptor.getSecurityState(),subscriptionOnly:this.config.subscriptionOnly,maxSameProviderRetries:this.config.maxSameProviderRetries})}createProvider(e){switch(e.type){case "claude-cli":return new ne(this.config.licenseKey,{retryDelaysMs:this.config.gatewayRetryDelaysMs});case "kimi-cli":return new re(this.config.licenseKey,{retryDelaysMs:this.config.gatewayRetryDelaysMs});case "anthropic-api":return e.apiKey?new ie({apiKey:e.apiKey,baseUrl:e.baseUrl}):null;case "openai-api":return e.apiKey?new ae({apiKey:e.apiKey,baseUrl:e.baseUrl}):null;case "ollama":return new oe({baseUrl:e.baseUrl});default:return null}}};});var Tt=v(()=>{te();});var St={};$e(St,{runVerify:()=>vn});function w(n,e){let t=n.padEnd(13);console.log(`${_("[ir]")} ${t}${e}`);}function be(n){if(n instanceof B)return {label:"CAP_EXCEEDED",hint:"Monthly cap reached. Buy a top-up at https://inference-relay.com/dashboard/billing",code:1};if(n instanceof F)return {label:"ALL_PROVIDERS_FAILED",hint:`Fallback chain exhausted: ${n.fallbackChain.join(" \u2192 ")}`,code:1};if(!(n instanceof Error))return {label:"FAILED",hint:String(n).slice(0,120),code:1};let e=n.message.toLowerCase(),t=n.name.toLowerCase();return e.includes("keychain_access_denied")||e.includes("keychain access denied")?{label:"KEYCHAIN_DENIED",hint:'macOS denied keychain access. Re-run and click "Always Allow" on the prompt.',code:1}:e.includes("rate limit")||e.includes("429")||t.includes("ratelimit")?{label:"RATE_LIMITED",hint:"Claude subscription is currently rate-limited. Wait a minute and re-run.",code:1}:e.includes("auth")||e.includes("401")||e.includes("403")||e.includes("unauthorized")||e.includes("forbidden")?{label:"AUTH_FAILED",hint:"Claude CLI OAuth token rejected. Run `claude` to refresh, then re-run verify.",code:1}:e.includes("timeout")||e.includes("timed out")||e.includes("aborted")||e.includes("etimedout")||e.includes("econnrefused")||e.includes("econnreset")||t==="aborterror"||t==="timeouterror"?{label:"TIMEOUT",hint:`No response within ${J/1e3}s. Network issue, hung CLI, or keychain prompt waiting for input. Try \`curl -I api.anthropic.com\` to test connectivity.`,code:1}:e.includes("empty response")||e.includes("returned empty")?{label:"EMPTY_RESPONSE",hint:"CLI returned an empty body \u2014 possible truncation, model error, or stale CLI version.",code:1}:{label:"FAILED",hint:n.message.slice(0,120),code:1}}function It(n){if(n.usageCap!==null&&n.usageCap!==void 0){let e=n.usageThisMonth??0,t=n.usageCap;if(t===0)console.log(_(` Usage: ${e.toLocaleString()} (unmetered)`));else {let r=Math.round(e/t*1e3)/10;console.log(_(` Usage: ${e.toLocaleString()} / ${t.toLocaleString()} (${r}%)`));}}}async function vn(n=process.argv.slice(2),e=process.env){let t=n.includes("--credentials-only"),r=e.IR_LICENSE_KEY;if(!r)return console.error(D("[ir] IR_LICENSE_KEY environment variable is not set.")),console.error(" Get a key at https://inference-relay.com/pricing"),console.error(" Then: export IR_LICENSE_KEY=ir_live_xxxx"),2;if(!/^ir_(live|test)_[a-f0-9]{32}$/.test(r))return console.error(D("[ir] IR_LICENSE_KEY does not look like a valid key.")),console.error(" Expected format: ir_live_<32 hex chars>"),console.error(` Got: ${r.slice(0,8)}... (${r.length} chars)`),2;let s;try{s=await ye(r);}catch(b){return w("IDENTITY:",D("FAILED")),console.error(` ${b.message||"unknown error"}`),1}if(!s.valid)return w("IDENTITY:",D("REJECTED")),s.error&&console.error(` ${s.error}`),1;w("IDENTITY:",j("VALIDATED"));let a=(s.tier??"unknown").toUpperCase();w("TIER:",j(a));let i;try{i=await $();}catch{i=null;}if(!i||!i.available)return w("RELAY:",_e("INACTIVE")),console.log(_(" Claude CLI not detected. The relay will fall back")),console.log(_(" to direct API providers using your API keys.")),console.log(_(" For zero-cost routing, install Claude Code:")),console.log(_(" npm install -g @anthropic-ai/claude-code")),1;if(!i.authenticated)return w("RELAY:",_e("CLI_UNAUTHED")),console.log(_(" Claude CLI is installed but not authenticated.")),console.log(_(" Run `claude` once to sign in, then re-run verify.")),1;if(i.versionWarning&&console.log(_e(` Warning: ${i.versionWarning}`)),t)return w("RELAY:",j("READY")),console.log(_(" Credentials present. Round-trip skipped (--credentials-only).")),i.cliVersion&&console.log(_(` Claude CLI: v${i.cliVersion}`)),i.subscriptionType&&i.subscriptionType!=="unknown"&&console.log(_(` Tier: ${i.subscriptionType}`)),It(s),0;let o=new fe({licenseKey:r,providers:[{type:"claude-cli",priority:1}],fallback:false,telemetry:false}),l=new AbortController,p=setTimeout(()=>l.abort(),J),c=Date.now(),g;try{g=await o.messages.create(fn,{signal:l.signal});}catch(b){clearTimeout(p),o.dispose();let{label:d,hint:f}=be(b);return w("RELAY:",D(`DEGRADED \u2014 ${d}`)),console.log(_(` ${f}`)),i.cliVersion&&console.log(_(` Claude CLI: v${i.cliVersion}`)),1}if(clearTimeout(p),process.platform==="win32"){let b=new AbortController,d=setTimeout(()=>b.abort(),J);try{await o.messages.create(_n,{signal:b.signal});}catch(E){clearTimeout(d),o.dispose();let{hint:k}=be(E);return w("RELAY:",D("DEGRADED \u2014 LONG_PROMPT_FAILED")),console.log(_(` Long-system-prompt round-trip failed: ${k}`)),console.log(_(" This is the cmd.exe arg-length regression class.")),console.log(_(" Ensure inference-relay is at version >=1.5.3 (closes the bug).")),i.cliVersion&&console.log(_(` Claude CLI: v${i.cliVersion}`)),1}clearTimeout(d);let f=new AbortController,u=setTimeout(()=>f.abort(),J);try{await o.messages.create(bn,{signal:f.signal});}catch(E){clearTimeout(u),o.dispose();let{hint:k}=be(E);return w("RELAY:",D("DEGRADED \u2014 TOOLS_DISPATCH_FAILED")),console.log(_(` Tools round-trip failed: ${k}`)),console.log(_(" The claude-cli provider couldn't forward params.tools.")),console.log(_(" Ensure inference-relay is at version >=1.6.0 (closes the bug).")),i.cliVersion&&console.log(_(` Claude CLI: v${i.cliVersion}`)),1}clearTimeout(u);let h=new AbortController,R=setTimeout(()=>h.abort(),J);try{await o.messages.create(En,{signal:h.signal});}catch(E){clearTimeout(R),o.dispose();let{hint:k}=be(E);return w("RELAY:",D("DEGRADED \u2014 MULTITURN_DISPATCH_FAILED")),console.log(_(` Multi-turn round-trip failed: ${k}`)),console.log(_(" The CLI rejected an assistant-role stream-json envelope.")),console.log(_(" Ensure inference-relay is at version >=1.6.0 (closes the bug),")),console.log(_(" OR ensure Claude CLI version is >=2.1.x (stream-json input floor).")),i.cliVersion&&console.log(_(` Claude CLI: v${i.cliVersion}`)),1}clearTimeout(R);}o.dispose();let m=Date.now()-c;return g.fallbackChain?.[0]?.startsWith("claude-cli:success")?(w("RELAY:",j("ACTIVE")),console.log(_(` Round-trip: ${m}ms via ${g.provider}`)),console.log(_(` Model echo: ${g.model}`)),console.log(_(` Tokens: ${g.usage.input_tokens} in / ${g.usage.output_tokens} out`)),i.cliVersion&&console.log(_(` Claude CLI: v${i.cliVersion}`)),console.log(_(` Multimodal: ${j("\u2713")} via claude-cli (subscription)`)),i.subscriptionType&&i.subscriptionType!=="unknown"&&console.log(_(` Tier: ${i.subscriptionType}`)),It(s),0):(w("RELAY:",_e("UNEXPECTED")),console.log(_(` Native Gateway did not handle the call. Chain: ${g.fallbackChain?.join(" \u2192 ")}`)),1)}var yn,Ee,j,D,_e,_,J,fn,_n,bn,En,Pt=v(()=>{wt();Me();Re();Tt();yn=process.stdout.isTTY===true,Ee=(n,e)=>yn?`\x1B[${n}m${e}\x1B[0m`:e,j=n=>Ee("32",n),D=n=>Ee("31",n),_e=n=>Ee("33",n),_=n=>Ee("2",n);J=15e3,fn={model:"claude-haiku-4-5",max_tokens:1,messages:[{role:"user",content:"Reply with exactly the single character k and nothing else."}]},_n={model:"claude-haiku-4-5",max_tokens:1,system:"Sentence. ".repeat(800),messages:[{role:"user",content:"Reply with exactly the single character k and nothing else."}]},bn={model:"claude-haiku-4-5",max_tokens:50,messages:[{role:"user",content:"Reply with the single word: ok"}],tools:[{type:"web_search_20250305",name:"web_search",max_uses:1}]},En={model:"claude-haiku-4-5",max_tokens:10,messages:[{role:"user",content:"Reply with: hello"},{role:"assistant",content:[{type:"text",text:"hello"}]},{role:"user",content:"Reply with: ok"}]};});var Lt={verify:async()=>{let{runVerify:n}=await Promise.resolve().then(()=>(Pt(),St));return n()}};function xt(){console.error("Usage: inference-relay <command>"),console.error(""),console.error("Commands:"),console.error(" verify Smoke-test your installation (license + relay availability)"),console.error(""),console.error("Docs: https://inference-relay.com/docs");}var M=process.argv[2];(!M||M==="--help"||M==="-h")&&(xt(),process.exit(M?0:2));M in Lt||(console.error(`Unknown command: ${M}`),console.error(""),xt(),process.exit(1));Lt[M]().then(n=>process.exit(n)).catch(n=>{console.error(`[ir] failed to run command "${M}":`),console.error(n),process.exit(99);});
@@ -65,6 +65,14 @@ interface RelayResult {
65
65
  usage: {
66
66
  input_tokens: number;
67
67
  output_tokens: number;
68
+ /**
69
+ * Prompt-cache tokens, when the provider reports them (Claude CLI, Anthropic API).
70
+ * `input_tokens` alone is the UNCACHED remainder: for a Claude CLI call it is often 3 to 10
71
+ * while tens of thousands of tokens ride in the cache fields. Cost accounting adds all three.
72
+ * Added 2026-09-10 (cache-usage-2026-09-10, ec8c30e); ported 2026-10-05.
73
+ */
74
+ cache_creation_input_tokens?: number;
75
+ cache_read_input_tokens?: number;
68
76
  };
69
77
  stop_reason: string;
70
78
  provider: string;
@@ -65,6 +65,14 @@ interface RelayResult {
65
65
  usage: {
66
66
  input_tokens: number;
67
67
  output_tokens: number;
68
+ /**
69
+ * Prompt-cache tokens, when the provider reports them (Claude CLI, Anthropic API).
70
+ * `input_tokens` alone is the UNCACHED remainder: for a Claude CLI call it is often 3 to 10
71
+ * while tens of thousands of tokens ride in the cache fields. Cost accounting adds all three.
72
+ * Added 2026-09-10 (cache-usage-2026-09-10, ec8c30e); ported 2026-10-05.
73
+ */
74
+ cache_creation_input_tokens?: number;
75
+ cache_read_input_tokens?: number;
68
76
  };
69
77
  stop_reason: string;
70
78
  provider: string;