inference-relay 1.6.1 → 1.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analytics/index.d.cts +1 -1
- package/dist/analytics/index.d.ts +1 -1
- package/dist/cli/main.js +7 -7
- package/dist/{index-B20BqToz.d.cts → index-jtUnTOMz.d.cts} +11 -0
- package/dist/{index-B20BqToz.d.ts → index-jtUnTOMz.d.ts} +11 -0
- package/dist/index.cjs +8 -8
- package/dist/index.d.cts +53 -4
- package/dist/index.d.ts +53 -4
- package/dist/index.js +8 -8
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
export { A as AuditEvent } from '../index-
|
|
1
|
+
export { A as AuditEvent } from '../index-jtUnTOMz.cjs';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { A as AuditEvent } from '../index-
|
|
1
|
+
export { A as AuditEvent } from '../index-jtUnTOMz.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
|
|
3
|
+
var kt=Object.defineProperty;var v=(n,e)=>()=>(n&&(e=n(n=0)),e);var Ue=(n,e)=>{for(var t in e)kt(n,t,{get:e[t],enumerable:true});};var B,ye=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 Q(n,e){let t=new Map,r=null,i=null,o=new Promise((u,y)=>{r=u,i=y;});o.catch(()=>{});let s=[],a=null,l="",p="";function d(u,...y){let g=t.get(u);g&&g.forEach(f=>f(...y));}async function*h(){try{for await(let u of n)if(yield u,u.type==="content_block_start")s[u.index]=u.content_block;else if(u.type==="content_block_delta"){let y=s[u.index];y&&u.delta?.type==="text_delta"&&(y.text=(y.text||"")+u.delta.text,d("text",u.delta.text));}else if(u.type==="message_start")l=u.message?.model||"",a=u.message?.usage;else if(u.type==="message_delta")p=u.delta?.stop_reason||"",u.usage&&(a={...a,...u.usage});else if(u.type==="message_stop"){let y={role:"assistant",model:l,content:s.filter(Boolean),usage:a,stop_reason:p};d("message",y),r&&(r(y),r=null),e&&e(y);}if(r){let u={role:"assistant",model:l,content:s.filter(Boolean),usage:a,stop_reason:p||"end_turn"};d("message",u),r(u),r=null,e&&e(u);}}catch(u){throw d("error",u),i&&(i(u),i=null),u}}let m=h(),c=false,b={[Symbol.asyncIterator](){if(c)throw new Error("[inference-relay] RelayStream can only be iterated once");return c=true,m},on(u,y){return t.has(u)||t.set(u,[]),t.get(u).push(y),b},finalMessage(){let u,y=new Promise((g,f)=>{u=setTimeout(()=>f(new Error("[inference-relay] finalMessage() timed out \u2014 no message_stop received after 5 minutes")),3e5);});return Promise.race([o,y]).finally(()=>clearTimeout(u))}};return b}var _e=v(()=>{});var P,Y=v(()=>{_e();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 Q(await this.streamRaw(e,t))}};});function Fe(){wt.clearCache();}var Ee,Ne,W,wt,be=v(()=>{Ee=`-----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-----`,Me={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>"},G=class{verificationFailures=0;cachedManifest=null;currentSecurityState="SEC_NOMINAL";async verifyManifest(e){try{let{compactVerify:t,importSPKI:r}=await import('jose'),s=await r(ye,"RS256"),{payload:o}=await t(e,s),i=JSON.parse(new TextDecoder().decode(o));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:Me,securityState:"SEC_DEGRADED"}}return this.cachedManifest?(this.currentSecurityState="SEC_CACHE",{manifest:this.cachedManifest,securityState:"SEC_CACHE"}):(this.currentSecurityState="SEC_RECOVERY",{manifest:Me,securityState:"SEC_RECOVERY"})}}getSecurityState(){return this.currentSecurityState}clearCache(){this.cachedManifest=null,this.verificationFailures=0,this.currentSecurityState="SEC_NOMINAL";}},At=new G;});function ve(n){return join(homedir(),".inference-relay","gateway",n)}function Fe(n){return join(ve(n),"bundle.js")}function He(n){return join(ve(n),"meta.json")}var wt,v,Y,X,Ce=C(()=>{_e();wt=process.env.IR_GATEWAY_URL||"https://api.inference-relay.com";v=class extends Error{constructor(t,r,s){super(t);this.code=r;this.cause=s;this.name="GatewayLoaderError";}code;cause},Y=new Map,X=class{static async load(e,t,r=wt){let s=`${t}:${e.slice(-8)}`;if(Y.has(s))return Y.get(s);try{let d=await this.tryLoadFromDisk(t);if(d)return Y.set(s,d),d}catch{}let{bytes:o,sha256:i,signature:a,libraryVersion:l}=await this.fetchFromAuthority(e,t,r);if(createHash("sha256").update(o).digest("hex")!==i)throw new v("[ir-system]: GATEWAY_VERIFICATION_FAILED (REASON: HASH_MISMATCH)","GATEWAY_VERIFICATION_FAILED");await this.verifySignature(a,l,i);try{let d=ve(t);mkdirSync(d,{recursive:!0}),writeFileSync(Fe(t),o),writeFileSync(He(t),JSON.stringify({sha256:i,signature:a,libraryVersion:l}));}catch{}let c=this.loadIntoVm(o.toString("utf-8"));return Y.set(s,c),c}static async loadFromDisk(e){if(!existsSync(e))throw new v(`[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=Fe(e),r=He(e);if(!existsSync(t)||!existsSync(r))return null;let s=readFileSync(t),o=JSON.parse(readFileSync(r,"utf-8"));return createHash("sha256").update(s).digest("hex")!==o.sha256?null:(await this.verifySignature(o.signature,o.libraryVersion,o.sha256),this.loadIntoVm(s.toString("utf-8")))}static async fetchFromAuthority(e,t,r){let s,o=[0,1e3,4e3],i;for(let c of o){c>0&&await new Promise(d=>setTimeout(d,c));try{let d=await fetch(`${r}/v1/gateway/fetch`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({libraryVersion:t})});if(d.status===401||d.status===403)throw new v("[ir-system]: LICENSE_REJECTED (REASON: GATEWAY_FETCH_UNAUTHORIZED)","LICENSE_REJECTED");if(d.status>=500&&d.status<600){i=new v(`[ir-system]: GATEWAY_FETCH_FAILED (REASON: HTTP_${d.status})`,"GATEWAY_FETCH_FAILED");continue}if(!d.ok)throw new v(`[ir-system]: GATEWAY_FETCH_FAILED (REASON: HTTP_${d.status})`,"GATEWAY_FETCH_FAILED");s=await d.json(),i=null;break}catch(d){if(d instanceof v&&d.code==="LICENSE_REJECTED")throw d;i=d;}}if(i||!s)throw i instanceof v?i:new v("[ir-system]: GATEWAY_FETCH_FAILED (REASON: NETWORK_ERROR)","GATEWAY_FETCH_FAILED",i);let a;try{a=await fetch(s.bundleUrl);}catch(c){throw new v("[ir-system]: GATEWAY_FETCH_FAILED (REASON: BUNDLE_DOWNLOAD_FAILED)","GATEWAY_FETCH_FAILED",c)}if(!a.ok)throw new v(`[ir-system]: GATEWAY_FETCH_FAILED (REASON: BUNDLE_HTTP_${a.status})`,"GATEWAY_FETCH_FAILED");let l=await a.arrayBuffer();return {bytes:Buffer.from(l),sha256:s.sha256,signature:s.signature,libraryVersion:s.libraryVersion,bundleVersion:s.bundleVersion}}static async verifySignature(e,t,r){try{let{compactVerify:s,importSPKI:o}=await import('jose'),i=await o(ye,"RS256"),{payload:a}=await s(e,i),l=JSON.parse(new TextDecoder().decode(a));if(l.purpose!=="gateway-bundle")throw new v("[ir-system]: GATEWAY_VERIFICATION_FAILED (REASON: PURPOSE_MISMATCH)","GATEWAY_VERIFICATION_FAILED");if(l.libraryVersion!==t)throw new v("[ir-system]: GATEWAY_VERIFICATION_FAILED (REASON: LIBRARY_VERSION_MISMATCH)","GATEWAY_VERIFICATION_FAILED");if(l.sha256!==r)throw new v("[ir-system]: GATEWAY_VERIFICATION_FAILED (REASON: SHA256_MISMATCH)","GATEWAY_VERIFICATION_FAILED")}catch(s){throw s instanceof v?s:new v("[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),o={exports:{}};compileFunction(e,["exports","require","module","__filename","__dirname"],{filename:"<gateway-bundle>"})(o.exports,s,o,t,r);let a=o.exports;if(!a.ClaudeCLIProvider)throw new v("[ir-system]: GATEWAY_LOAD_FAILED (REASON: MISSING_CLAUDE_CLI_EXPORT)","GATEWAY_LOAD_FAILED");return a}catch(t){throw t instanceof v?t:new v("[ir-system]: GATEWAY_LOAD_FAILED (REASON: VM_EXECUTION_ERROR)","GATEWAY_LOAD_FAILED",t)}}static clearCache(){Y.clear();}};});var $e={};De($e,{detectCLI:()=>F});function Dt(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(o=>o.toLowerCase()):[""];for(let o of e.split(r))if(o)for(let i of s){let a=join(o,n+i);if(existsSync(a))return a}return null}async function F(){if(!Dt("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&&!xt.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 xt,Z=C(()=>{xt=["2.1.87"];});var Mt,ee,Ve=C(()=>{V();Ce();Mt="1.6.1",ee=class extends S{type="claude-cli";supportsStreaming=true;supportsMultimodal=true;platformRequirement="desktop";licenseKey;loadedProvider=null;loadingPromise=null;health={status:"healthy",lastCheckAt:Date.now(),errorCount:0};constructor(e){super(),this.licenseKey=e;}async ensureLoaded(){return this.loadedProvider?this.loadedProvider:this.loadingPromise?this.loadingPromise:(this.loadingPromise=(async()=>{try{let t=(await X.load(this.licenseKey,Mt)).ClaudeCLIProvider,r=new t;return this.loadedProvider=r,r}catch(e){throw this.loadingPromise=null,this.health.status="unhealthy",this.health.errorCount++,e instanceof v?this.health.lastError=e.message:e instanceof Error&&(this.health.lastError=e.message),e}})(),this.loadingPromise)}async probe(){let{detectCLI:e}=await Promise.resolve().then(()=>(Z(),$e));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());}};});function Ye(n){return te[n]||n}function Ae(n){return Ge.find(e=>e.canonical===n)?.provider}var Ge,te,Re=C(()=>{Ge=[{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}}],te=Object.fromEntries(Ge.filter(n=>n.canonical!==n.apiId).map(n=>[n.canonical,n.apiId]));te["claude-sonnet-4"]="claude-sonnet-4-20250514";te["claude-opus-4"]="claude-opus-4-20250514";te["claude-haiku-4"]="claude-haiku-4-5-20251001";});function We(n){if(ke[n])return ke[n];for(let[e,t]of Object.entries(ke))if(n.startsWith(e.split("-20")[0]))return t;return [3,15]}var Ot,Ut,ke,ne,Ke=C(()=>{V();Re();Ot="https://api.anthropic.com/v1/messages",Ut="2023-06-01",ke={"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]};ne=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(/\/$/,"")||Ot,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),o=await fetch(this.baseUrl,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify(s),signal:t?.signal});if(!o.ok)throw this.handleErrorResponse(o),new Error("unreachable");let i=await o.json(),a=Date.now()-r;this.recordSuccess();let[l,p]=We(i.model||e.model),c=((i.usage?.input_tokens||0)*l+(i.usage?.output_tokens||0)*p)/1e6,d={},f=["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 m of f){let b=o.headers.get(m);b&&(d[m]=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:a,fallbackChain:["anthropic-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("ANTHROPIC_API_ERROR: Response body is null \u2014 streaming unavailable");let o=s.body.getReader(),i=new TextDecoder;return (async function*(){let a="",l=false;try{for(;;){let{done:p,value:c}=await o.read();if(p)break;a+=i.decode(c,{stream:!0});let d=a.split(`
|
|
12
|
-
`);a=
|
|
13
|
-
`);l=u.pop()||"";for(let y of u){if(!y.startsWith("data: "))continue;let
|
|
14
|
-
`);l=
|
|
11
|
+
-----END PUBLIC KEY-----`,Ne={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>"},W=class{verificationFailures=0;cachedManifest=null;currentSecurityState="SEC_NOMINAL";async verifyManifest(e){try{let{compactVerify:t,importSPKI:r}=await import('jose'),i=await r(Ee,"RS256"),{payload:o}=await t(e,i),s=JSON.parse(new TextDecoder().decode(o));return this.verificationFailures=0,this.cachedManifest=s,this.currentSecurityState="SEC_NOMINAL",{manifest:s,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:Ne,securityState:"SEC_DEGRADED"}}return this.cachedManifest?(this.currentSecurityState="SEC_CACHE",{manifest:this.cachedManifest,securityState:"SEC_CACHE"}):(this.currentSecurityState="SEC_RECOVERY",{manifest:Ne,securityState:"SEC_RECOVERY"})}}getSecurityState(){return this.currentSecurityState}clearCache(){this.cachedManifest=null,this.verificationFailures=0,this.currentSecurityState="SEC_NOMINAL";}},wt=new W;});function I(n,...e){process.env.IR_DEBUG==="1"&&console.error(`[ir-debug:${n}]`,...e);}var ve=v(()=>{});function Re(n){return join(homedir(),".inference-relay","gateway",n)}function He(n){return join(Re(n),"bundle.js")}function Ve(n){return join(Re(n),"meta.json")}function Dt(n){let e=(r,i)=>{if(!Array.isArray(r)||r.length===0)return null;let o=[];for(let s of r){let a=typeof s=="string"?Number(s):s;if(typeof a!="number"||!Number.isFinite(a)||a<0)return I("loader.retry-config-invalid",{source:i,badValue:s}),null;o.push(a);}return o};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(i=>i.trim()),"env");if(r)return r}return xt}var Lt,C,N,K,xt,Z,ke=v(()=>{be();ve();Lt=process.env.IR_GATEWAY_URL||"https://api.inference-relay.com";C=class extends Error{constructor(t,r,i){super(t);this.code=r;this.cause=i;this.name="GatewayLoaderError";}code;cause},N=class extends C{constructor(e,t){super(e,"GATEWAY_FETCH_FAILED",t);}},K=new Map,xt=[0,1e3,4e3];Z=class{static async load(e,t,r=Lt,i){let o=`${t}:${e.slice(-8)}`;if(K.has(o))return K.get(o);try{let m=await this.tryLoadFromDisk(t);if(m)return I("loader.cache-hit",{libraryVersion:t}),K.set(o,m),m}catch{}I("loader.cache-miss",{libraryVersion:t});let{bytes:s,sha256:a,signature:l,libraryVersion:p}=await this.fetchFromAuthority(e,t,r,i);if(createHash("sha256").update(s).digest("hex")!==a)throw new C("[ir-system]: GATEWAY_VERIFICATION_FAILED (REASON: HASH_MISMATCH)","GATEWAY_VERIFICATION_FAILED");await this.verifySignature(l,p,a);try{let m=Re(t);mkdirSync(m,{recursive:!0}),writeFileSync(He(t),s),writeFileSync(Ve(t),JSON.stringify({sha256:a,signature:l,libraryVersion:p}));}catch{}let h=this.loadIntoVm(s.toString("utf-8"));return K.set(o,h),h}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=He(e),r=Ve(e);if(!existsSync(t)||!existsSync(r))return null;let i=readFileSync(t),o=JSON.parse(readFileSync(r,"utf-8"));return createHash("sha256").update(i).digest("hex")!==o.sha256?null:(await this.verifySignature(o.signature,o.libraryVersion,o.sha256),this.loadIntoVm(i.toString("utf-8")))}static async fetchFromAuthority(e,t,r,i){let o,s=Dt(i?.retryDelaysMs),a;for(let h=0;h<s.length;h++){let m=s[h];m>0&&await new Promise(c=>setTimeout(c,m)),I("loader.fetch",{url:`${r}/v1/gateway/fetch`,libraryVersion:t,attempt:h+1,delayMs:m});try{let c=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:c.status,attempt:h+1}),c.status===401||c.status===403)throw new C("[ir-system]: LICENSE_REJECTED (REASON: GATEWAY_FETCH_UNAUTHORIZED)","LICENSE_REJECTED");if(c.status>=500&&c.status<600){a=new N(`[ir-system]: GATEWAY_FETCH_FAILED (REASON: HTTP_${c.status})`);continue}if(!c.ok)throw new N(`[ir-system]: GATEWAY_FETCH_FAILED (REASON: HTTP_${c.status})`);o=await c.json(),a=null;break}catch(c){if(c instanceof C&&c.code==="LICENSE_REJECTED")throw c;a=c;}}if(a||!o)throw a instanceof C?a:new N("[ir-system]: GATEWAY_FETCH_FAILED (REASON: NETWORK_ERROR)",a);let l;try{l=await fetch(o.bundleUrl);}catch(h){throw new N("[ir-system]: GATEWAY_FETCH_FAILED (REASON: BUNDLE_DOWNLOAD_FAILED)",h)}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:o.sha256,signature:o.signature,libraryVersion:o.libraryVersion,bundleVersion:o.bundleVersion}}static async verifySignature(e,t,r){try{let{compactVerify:i,importSPKI:o}=await import('jose'),s=await o(Ee,"RS256"),{payload:a}=await i(e,s),l=JSON.parse(new TextDecoder().decode(a));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(i){throw i instanceof C?i:new C("[ir-system]: GATEWAY_VERIFICATION_FAILED (REASON: SIGNATURE_INVALID)","GATEWAY_VERIFICATION_FAILED",i)}}static loadIntoVm(e){try{let t=join(homedir(),".inference-relay","gateway","runtime.cjs"),r=dirname(t),i=createRequire(t),o={exports:{}};compileFunction(e,["exports","require","module","__filename","__dirname"],{filename:"<gateway-bundle>"})(o.exports,i,o,t,r);let a=o.exports;if(!a.ClaudeCLIProvider)throw new C("[ir-system]: GATEWAY_LOAD_FAILED (REASON: MISSING_CLAUDE_CLI_EXPORT)","GATEWAY_LOAD_FAILED");return a}catch(t){throw t instanceof C?t:new C("[ir-system]: GATEWAY_LOAD_FAILED (REASON: VM_EXECUTION_ERROR)","GATEWAY_LOAD_FAILED",t)}}static clearCache(){K.clear();}};});var Ye={};Ue(Ye,{detectCLI:()=>$});function Ft(n){let e=process.env.PATH;if(!e)return null;let t=process.platform==="win32",r=t?";":":",i=t?(process.env.PATHEXT??".COM;.EXE;.BAT;.CMD").split(";").map(o=>o.toLowerCase()):[""];for(let o of e.split(r))if(o)for(let s of i){let a=join(o,n+s);if(existsSync(a))return a}return null}async function $(){if(!Ft("claude"))return {available:false,authenticated:false};let e=null;try{let r=execSync("claude --version",{encoding:"utf-8",timeout:5e3}).trim(),i=r.match(/(\d+\.\d+\.\d+)/);e=i?i[1]:r;}catch{}let t;return e&&!Nt.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 Nt,te=v(()=>{Nt=["2.1.87"];});var Bt,ne,We=v(()=>{Y();ke();Bt="1.6.2",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 Z.load(this.licenseKey,Bt,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(),Ye));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,i=(r*3+1e3*15)/1e6;return {estimatedInputTokens:Math.round(r),estimatedCost:Math.round(i*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());}};});function je(n){return re[n]||n}function we(n){return Ke.find(e=>e.canonical===n)?.provider}var Ke,re,Te=v(()=>{Ke=[{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}}],re=Object.fromEntries(Ke.filter(n=>n.canonical!==n.apiId).map(n=>[n.canonical,n.apiId]));re["claude-sonnet-4"]="claude-sonnet-4-20250514";re["claude-opus-4"]="claude-opus-4-20250514";re["claude-haiku-4"]="claude-haiku-4-5-20251001";});function qe(n){if(Ie[n])return Ie[n];for(let[e,t]of Object.entries(Ie))if(n.startsWith(e.split("-20")[0]))return t;return [3,15]}var $t,Ht,Ie,se,Je=v(()=>{Y();Te();$t="https://api.anthropic.com/v1/messages",Ht="2023-06-01",Ie={"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]};se=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(/\/$/,"")||$t,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(),i=this.buildRequestBody(e,false),o=await fetch(this.baseUrl,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify(i),signal:t?.signal});if(!o.ok)throw this.handleErrorResponse(o),new Error("unreachable");let s=await o.json(),a=Date.now()-r;this.recordSuccess();let[l,p]=qe(s.model||e.model),d=((s.usage?.input_tokens||0)*l+(s.usage?.output_tokens||0)*p)/1e6,h={},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 c of m){let b=o.headers.get(c);b&&(h[c]=b);}return {content:s.content||[],model:s.model||e.model,usage:{input_tokens:s.usage?.input_tokens||0,output_tokens:s.usage?.output_tokens||0},stop_reason:s.stop_reason||"end_turn",provider:"anthropic-api",costUsd:Math.round(d*1e6)/1e6,durationMs:a,fallbackChain:["anthropic-api:success"],headers:Object.keys(h).length>0?h:void 0}}async streamRaw(e,t){let r=this.buildRequestBody(e,true),i=await fetch(this.baseUrl,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify(r),signal:t?.signal});if(i.ok||this.handleErrorResponse(i),!i.body)throw new Error("ANTHROPIC_API_ERROR: Response body is null \u2014 streaming unavailable");let o=i.body.getReader(),s=new TextDecoder;return (async function*(){let a="",l=false;try{for(;;){let{done:p,value:d}=await o.read();if(p)break;a+=s.decode(d,{stream:!0});let h=a.split(`
|
|
12
|
+
`);a=h.pop()||"";let m=null;for(let c of h)if(c.startsWith("event: "))m=c.slice(7).trim();else if(c.startsWith("data: ")){let b=c.slice(6);if(m&&b)try{let u=JSON.parse(b);u.type==="message_stop"&&(l=!0),yield u;}catch{console.warn("[inference-relay] Skipped malformed SSE data:",b.substring(0,100));}m=null;}else c.trim()===""&&(m=null);}l||(yield {type:"message_stop"});}finally{try{o.releaseLock();}catch{}}})()}estimateCost(e){let t=Math.round(JSON.stringify(e.messages).length/4),r=e.system?Math.round(e.system.length/4):0,i=t+r,[o,s]=qe(e.model),a=(i*o+1e3*s)/1e6;return {estimatedInputTokens:i,estimatedCost:Math.round(a*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":Ht};return this.dangerousDirectBrowserAccess&&(e["anthropic-dangerous-direct-browser-access"]="true"),e}buildRequestBody(e,t){let r={model:je(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"),i=r?parseInt(r,10)*1e3:6e4;this.health.status="degraded",this.health.lastError=`Rate limited \u2014 retry after ${i}ms`,this.health.lastCheckAt=Date.now();let o=new Error(`ANTHROPIC_RATE_LIMIT: Too many requests (429). Retry after ${i}ms`);throw o.retryAfterMs=i,o}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 Xe(n){if(Se[n])return Se[n];for(let[e,t]of Object.entries(Se))if(n.startsWith(e))return t;return [2.5,10]}function Gt(n){return typeof n=="string"?n:n.filter(e=>e.type==="text"&&e.text).map(e=>e.text).join("")}function Yt(n,e){let t=[];e&&t.push({role:"system",content:e});for(let r of n){let i=Gt(r.content);if(r.role==="assistant"&&Array.isArray(r.content)){let o=r.content.filter(s=>s.type==="tool_use");if(o.length>0){t.push({role:"assistant",content:i||"",tool_calls:o.map(s=>({id:s.id||`call_${Math.random().toString(36).slice(2)}`,type:"function",function:{name:s.name,arguments:typeof s.input=="string"?s.input:JSON.stringify(s.input)}}))});continue}}t.push({role:r.role,content:i});}return t}function Qe(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 Vt,ze,Se,ie,Ze=v(()=>{Y();Vt="https://api.openai.com/v1/chat/completions",ze=["gpt-","o1","o3","o4","chatgpt-","text-","davinci","babbage","ft:"],Se={"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]};ie=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(/\/$/,"")||Vt;}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(),i=this.buildRequestBody(e,false),o=await fetch(this.baseUrl,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify(i),signal:t?.signal});if(!o.ok)throw this.handleErrorResponse(o),new Error("unreachable");let s=await o.json(),a=Date.now()-r;this.recordSuccess();let l=s.choices?.[0],p=[];if(l?.message?.content&&p.push({type:"text",text:l.message.content}),l?.message?.tool_calls)for(let g of l.message.tool_calls)p.push({type:"tool_use",id:g.id,name:g.function?.name,input:g.function?.arguments?JSON.parse(g.function.arguments):{}});let d=s.usage?.prompt_tokens||0,h=s.usage?.completion_tokens||0,[m,c]=Xe(s.model||e.model),b=(d*m+h*c)/1e6,u={},y=["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 g of y){let f=o.headers.get(g);f&&(u[g]=f);}return {content:p,model:s.model||e.model,usage:{input_tokens:d,output_tokens:h},stop_reason:Qe(l?.finish_reason),provider:"openai-api",costUsd:Math.round(b*1e6)/1e6,durationMs:a,fallbackChain:["openai-api:success"],headers:Object.keys(u).length>0?u:void 0}}async streamRaw(e,t){let r=this.buildRequestBody(e,true),i=await fetch(this.baseUrl,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify(r),signal:t?.signal});if(i.ok||this.handleErrorResponse(i),!i.body)throw new Error("OPENAI_API_ERROR: Response body is null \u2014 streaming unavailable");let o=i.body.getReader(),s=new TextDecoder,a=e.model;return (async function*(){let l="",p=false,d=false,h,m;yield {type:"message_start",message:{model:a,usage:{input_tokens:0,output_tokens:0}}};try{for(;;){let{done:c,value:b}=await o.read();if(c)break;l+=s.decode(b,{stream:!0});let u=l.split(`
|
|
13
|
+
`);l=u.pop()||"";for(let y of u){if(!y.startsWith("data: "))continue;let g=y.slice(6).trim();if(g==="[DONE]"){yield {type:"message_delta",delta:{stop_reason:m||"end_turn"},usage:h||{}},yield {type:"message_stop"},d=!0;return}try{let f=JSON.parse(g);f.usage&&(h={input_tokens:f.usage.prompt_tokens||0,output_tokens:f.usage.completion_tokens||0});let R=f.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=Qe(R.finish_reason));}catch{}}}d||(yield {type:"message_delta",delta:{stop_reason:m||"end_turn"},usage:h||{}},yield {type:"message_stop"});}finally{try{o.releaseLock();}catch{}}})()}estimateCost(e){let t=Math.round(JSON.stringify(e.messages).length/4),r=e.system?Math.round(e.system.length/4):0,i=t+r,[o,s]=Xe(e.model),a=(i*o+1e3*s)/1e6;return {estimatedInputTokens:i,estimatedCost:Math.round(a*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(!ze.some(a=>r.startsWith(a)))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 (${ze.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 o=Yt(e.messages,e.system),s={model:e.model,max_tokens:e.max_tokens,messages:o};return t&&(s.stream=true,s.stream_options={include_usage:true}),e.temperature!==void 0&&(s.temperature=e.temperature),e.tools&&e.tools.length>0&&(s.tools=e.tools),s}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"),i=r?parseInt(r,10)*1e3:6e4;this.health.status="degraded",this.health.lastError=`Rate limited \u2014 retry after ${i}ms`,this.health.lastCheckAt=Date.now();let o=new Error(`OPENAI_RATE_LIMIT: Too many requests (429). Retry after ${i}ms`);throw o.retryAfterMs=i,o}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 Kt(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)t.push({role:r.role,content:Kt(r.content)});return t}var Wt,oe,et=v(()=>{Y();Wt="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(/\/$/,"")||Wt;}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(),i=this.buildRequestBody(e,false),o=await fetch(`${this.baseUrl}/api/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i),signal:t?.signal});if(!o.ok)throw this.handleErrorResponse(o),new Error("unreachable");let s=await o.json(),a=Date.now()-r;this.recordSuccess();let l=[];s.message?.content&&l.push({type:"text",text:s.message.content});let p=s.prompt_eval_count||0,d=s.eval_count||0;return {content:l,model:s.model||e.model,usage:{input_tokens:p,output_tokens:d},stop_reason:(s.done,"end_turn"),provider:"ollama",costUsd:0,durationMs:a,fallbackChain:["ollama:success"]}}async streamRaw(e,t){let r=this.buildRequestBody(e,true),i=await fetch(`${this.baseUrl}/api/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r),signal:t?.signal});if(i.ok||this.handleErrorResponse(i),!i.body)throw new Error("OLLAMA_ERROR: Response body is null \u2014 streaming unavailable");let o=i.body.getReader(),s=new TextDecoder,a=e.model;return (async function*(){let l="",p=false,d=false;yield {type:"message_start",message:{model:a,usage:{input_tokens:0,output_tokens:0}}};try{for(;;){let{done:h,value:m}=await o.read();if(h)break;l+=s.decode(m,{stream:!0});let c=l.split(`
|
|
14
|
+
`);l=c.pop()||"";for(let b of c){let u=b.trim();if(u)try{let y=JSON.parse(u);if(y.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:y.message.content}}),y.done){p&&(yield {type:"content_block_stop",index:0}),yield {type:"message_delta",delta:{stop_reason:"end_turn"},usage:{input_tokens:y.prompt_eval_count||0,output_tokens:y.eval_count||0}},yield {type:"message_stop"},d=!0;return}}catch{}}}d||(yield {type:"message_stop"});}finally{try{o.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=jt(e.messages,e.system),i={model:e.model,messages:r,stream:t};return e.temperature!==void 0&&(i.options={temperature:e.temperature}),i}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 ae,tt=v(()=>{ae=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 le(n,e){if(e instanceof C)return `${n}:failed:${e.code}:${e.message}`;let t=e?.message;return `${n}:failed:${t?.slice(0,lt)||"unknown"}`}function rt(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 Pe(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.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 st(n){return [...n].sort((e,t)=>e.priority-t.priority)}function it(n){return {provider:n,inputTokens:0,outputTokens:0,costUsd:0,userCostUsd:0}}function Jt(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 ot(n){return {input_tokens:n[n.length-1]?.inputTokens??0,output_tokens:n.reduce((e,t)=>e+t.outputTokens,0)}}function zt(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 Xt(n,e,t,r,i){if(i&&n.type==="content_block_delta"&&n.index===i.fromIndex)return {action:"yield",event:{...n,index:i.toIndex}};if(i&&n.type==="content_block_stop"&&n.index===i.fromIndex)return {action:"suppress",coalesceMode:null,coalesceModeCleared:true};if(r&&n.type==="content_block_start"&&n.content_block?.type==="text"){let s=t.content[t.content.length-1];if(s?.type==="text"&&s.open===true)return {action:"suppress",coalesceMode:{fromIndex:n.index+e,toIndex:t.content.length-1},clearedJustFailedOver:true}}let o=r&&n.type==="content_block_start";return typeof n.index=="number"&&e>0?{action:"yield",event:{...n,index:n.index+e},clearedJustFailedOver:o}:{action:"yield",event:n,clearedJustFailedOver:o}}function Qt(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 Zt(n,e){return n?`${n}
|
|
15
15
|
|
|
16
|
-
${e}`:e}function st(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 Jt(n){return Math.max(0,n.content.length-1)}async function*zt(n){for await(let e of n)await new Promise(t=>setTimeout(t,50+Math.random()*50)),yield e;}var it,Ze,H,ae,we=C(()=>{fe();Qe();Re();Ce();it=200;Ze=new Set(["anthropic-api","openai-api","ollama"]),H=class extends Error{code="ALL_PROVIDERS_FAILED";fallbackChain;constructor(e){super(`All providers failed. Chain: ${e.join(" \u2192 ")}`),this.name="RelayError",this.fallbackChain=e;}};ae=class n{healthMap=new Map;engineEvents=new ie;static UNHEALTHY_TTL_MS=300*1e3;getHealthStatus(e){let t=this.healthMap.get(e);return t?t.status==="unhealthy"&&Date.now()-t.updatedAt>=n.UNHEALTHY_TTL_MS?(this.healthMap.delete(e),"healthy"):t.status:"healthy"}markUnhealthy(e,t){this.healthMap.set(e,{status:"unhealthy",lastError:t,updatedAt:Date.now()});}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=tt(t),o=[],i=et(e),a=randomUUID(),l=Date.now();for(let p of s){let c=p.type;if(this.getHealthStatus(c)==="unhealthy"){o.push(`${c}:skipped:unhealthy`);continue}if(i&&!p.supportsMultimodal){o.push(`${c}:skipped:no_multimodal`);continue}let f=Ae(e.model);if(f&&f!==c&&Ze.has(c)){o.push(`${c}:skipped:wrong_provider`);continue}try{let m=await p.execute(e,{signal:r?.signal});return this.markHealthy(c),o.push(`${c}:success`),this.emitEngineEvent({kind:"stream_complete",callId:a,id:randomUUID(),ts:Date.now(),stitched:!1,segments:[{provider:c,inputTokens:m.usage.input_tokens,outputTokens:m.usage.output_tokens,costUsd:m.costUsd,userCostUsd:m.userCostUsd??0}],provider:c,model:m.model,inputTokens:m.usage.input_tokens,outputTokens:m.usage.output_tokens,costUsd:m.costUsd,userCostUsd:m.userCostUsd,durationMs:m.durationMs??Date.now()-l,stopReason:m.stop_reason,fallbackChain:o,rateLimitHit:!1,securityState:r?.licenseState}),{...m,fallbackChain:o}}catch(m){if(m?.name==="AbortError"||r?.signal?.aborted)throw m;switch(Ie(m)){case "rate_limited":p.reportRateLimit({provider:c,utilization:1,resetsAt:Date.now()+6e4}),this.markDegraded(c,"rate_limited"),o.push(`${c}:failed:rate_limited`);break;case "auth_failed":this.markUnhealthy(c,"auth_failed"),o.push(`${c}:failed:auth_failed`);break;case "timeout":o.push(`${c}:failed:timeout`);break;case "provider_incompatible":o.push(`${c}:incompatible`);break;case "gateway_unavailable":this.markUnhealthy(c,"gateway_unavailable"),o.push(oe(c,m));break;default:o.push(oe(c,m));break}}}throw new H(o)}async stream(e,t,r){let s=randomUUID(),o=tt(t),i=et(e),a=Date.now(),l=[],p=null,c=null;for(let h of o){let g=h.type;if(this.getHealthStatus(g)==="unhealthy"){l.push(`${g}:skipped:unhealthy`);continue}if(i&&!h.supportsMultimodal){l.push(`${g}:skipped:no_multimodal`);continue}if(!h.supportsStreaming){l.push(`${g}:skipped:no_streaming`);continue}let R=Ae(e.model);if(R&&R!==g&&Ze.has(g)){l.push(`${g}:skipped:wrong_provider`);continue}try{c=await h.streamRaw(e,{signal:r?.signal}),p=h,l.push(`${g}:success`);break}catch(E){if(E?.name==="AbortError"||r?.signal?.aborted)throw E;switch(Ie(E)){case "rate_limited":h.reportRateLimit({provider:g,utilization:1,resetsAt:Date.now()+6e4}),this.markDegraded(g,"rate_limited"),l.push(`${g}:failed:rate_limited`);break;case "auth_failed":this.markUnhealthy(g,"auth_failed"),l.push(`${g}:failed:auth_failed`);break;case "timeout":l.push(`${g}:failed:timeout`);break;case "provider_incompatible":l.push(`${g}:incompatible`);break;case "gateway_unavailable":this.markUnhealthy(g,"gateway_unavailable"),l.push(oe(g,E));break;default:l.push(oe(g,E));break}}}if(!p||!c)throw new H(l);let f=this,m=r?.maxMidStreamFailovers??2,b=new Set([p]);async function*u(){let h=p,g=c[Symbol.asyncIterator](),R={role:"assistant",content:[]},E={segments:[]},k=nt(h.type);E.segments.push(k);let Pe=0,j=null,q=false,he=m,B="",$="";for(f.emitEngineEvent({kind:"segment_start",callId:s,id:randomUUID(),ts:Date.now(),provider:h.type});;)try{for(;;){let I=await g.next();if(I.done)break;let O=I.value,L=Kt(O,Pe,R,q,j);if(L.action==="suppress"){"coalesceMode"in L&&(j=L.coalesceMode),L.clearedJustFailedOver&&(q=!1);continue}L.coalesceModeCleared&&(j=null),L.clearedJustFailedOver&&(q=!1);let A=L.event;if(Wt(R,A),A.type==="message_start"){if(E.segments.length>1)continue;B=A.message?.model||B,A.message?.usage?.input_tokens!=null&&(k.inputTokens=A.message.usage.input_tokens);}if(A.type==="message_delta"&&(A.delta?.stop_reason&&($=A.delta.stop_reason),A.usage)){Yt(k,h.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");f.markHealthy(h.type),f.emitEngineEvent({kind:"segment_complete",callId:s,id:randomUUID(),ts:Date.now(),provider:h.type,usage:{...k}});let w=rt(E.segments);yield {type:"message_delta",delta:{stop_reason:$||"end_turn"},usage:w},yield {type:"message_stop"},f.emitEngineEvent({kind:"stream_complete",callId:s,id:randomUUID(),ts:Date.now(),stitched:E.segments.length>1,segments:E.segments.map(I=>({...I})),provider:E.segments.map(I=>I.provider).join("+"),model:B,inputTokens:w.input_tokens,outputTokens:w.output_tokens,costUsd:E.segments.reduce((I,O)=>I+O.costUsd,0),userCostUsd:E.segments.reduce((I,O)=>I+O.userCostUsd,0),durationMs:Date.now()-a,stopReason:$||"end_turn",fallbackChain:l,rateLimitHit:!1,securityState:r?.licenseState});return}catch(w){if(w?.name==="AbortError"||r?.signal?.aborted)throw w;let I=Ie(w);try{await g.return?.();}catch{}if(f.markUnhealthy(h.type,String(w)),f.emitEngineEvent({kind:"mid_stream_failover_attempt",callId:s,id:randomUUID(),ts:Date.now(),from:h.type,bytesBuffered:st(R),errorClass:I,retriesLeft:he}),l.push(`${h.type}:partial(${st(R)}b)`),he<=0)throw f.emitTerminalExhaustion(s,E,B,$,l,a,r?.licenseState),w;let O=jt(R.content),L=[...e.messages,{role:"assistant",content:O}],A=null,J=null,Le=h;for(;;){let x=f.nextHealthyProvider(o,Le,i,b);if(!x)break;Le=x,b.add(x);let vt={...e,messages:L,...x.type!=="anthropic-api"&&x.type!=="claude-cli"?{system:qt(e.system,"[SYSTEM]: CONTINUE_LAST_RESPONSE_WITHOUT_REPEATING")}:{}};try{J=await x.streamRaw(vt,{signal:r?.signal}),A=x;break}catch(xe){f.markUnhealthy(x.type,String(xe)),l.push(`${x.type}:failed_connect:${String(xe).slice(0,it)}`);}}if(!A||!J)throw f.emitTerminalExhaustion(s,E,B,$,l,a,r?.licenseState),w;l.push(`${A.type}:stitched`),f.emitEngineEvent({kind:"mid_stream_failover_success",callId:s,id:randomUUID(),ts:Date.now(),from:h.type,to:A.type}),Pe=Jt(R)+1,he--,h=A,g=J[Symbol.asyncIterator](),q=true,j=null,k=nt(h.type),E.segments.push(k),f.emitEngineEvent({kind:"segment_start",callId:s,id:randomUUID(),ts:Date.now(),provider:h.type});}}let y=u();return r?.licenseState==="SEC_DEGRADED"&&(y=zt(y)),z(y)}nextHealthyProvider(e,t,r,s){let o=e.indexOf(t);if(o===-1)return null;for(let i=o+1;i<e.length;i++){let a=e[i];if(!s.has(a)&&!(r&&!a.supportsMultimodal)&&a.supportsStreaming)return a}return null}emitEngineEvent(e){this.engineEvents.emitTyped(e);}emitTerminalExhaustion(e,t,r,s,o,i,a){let l=rt(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:o,rateLimitHit:false,securityState:a});}};});function ot(n,e){if(e==="prefer-user"){let s=n.filter(i=>i.type==="claude-cli"),o=n.filter(i=>i.type!=="claude-cli");return [...s,...o]}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 at(n){return (e,t)=>n.maxCostPerCall!==void 0&&t.estimatedCost>n.maxCostPerCall?"prefer-user":n.preferLocal?"ollama":"prefer-user"}var lt=C(()=>{});function ct(n){if(Se[n])return Se[n];for(let[e,t]of Object.entries(Se))if(n.startsWith(e))return t;return [3,15]}var Se,ut=C(()=>{Se={"claude-opus-4":[15,75],"claude-sonnet-4":[3,15],"claude-haiku-4":[.8,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 dt(n){let e=0;for(let a of n.messages)if(typeof a.content=="string")e+=a.content.length;else if(Array.isArray(a.content))for(let l of a.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,o]=ct(n.model),i=(t*s+r*o)/1e6;return {estimatedInputTokens:t,estimatedCost:Math.round(i*1e4)/1e4,model:n.model,provider:""}}var pt=C(()=>{ut();});var le,mt=C(()=>{le=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 ce(n,e){if(!n)return {valid:false,error:"License key required. Get one at inference-relay.com"};let t=U.get(n);if(t&&Date.now()-t.cachedAt<t.ttl)return t.result;let r=new AbortController,o=!U.has(n)?3e3:1e3,i=setTimeout(()=>r.abort(),o),a;try{let p=(e||Xt)+Qt;a=await(await fetch(p,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({key:n}),signal:r.signal})).json();}catch{return clearTimeout(i),t&&Date.now()-t.cachedAt<en?t.result:{valid:false,error:"License validation failed (network error). Visit inference-relay.com"}}clearTimeout(i);let l;if(a.jws)try{let{compactVerify:p,importSPKI:c}=await import('jose'),d=await c(tn,"RS256"),{payload:f}=await p(a.jws,d);l=JSON.parse(new TextDecoder().decode(f));}catch{return U.delete(n),{valid:false,error:"License validation signature invalid. Possible MITM \u2014 refusing to start."}}else if(l=a,l.valid)return U.delete(n),{valid:false,error:"License validation response not signed. Possible MITM."};return U.set(n,{result:l,cachedAt:Date.now(),ttl:l.valid?Zt:6e4}),l}var Xt,Qt,Zt,en,tn,U,ue,ht=C(()=>{ge();Ve();Ke();ze();Xe();we();Z();lt();pt();_e();mt();Xt="https://api.inference-relay.com",Qt="/v1/validate",Zt=1440*60*1e3,en=10080*60*1e3,tn=`-----BEGIN PUBLIC KEY-----
|
|
16
|
+
${e}`:e}function at(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 en(n){return Math.max(0,n.content.length-1)}async function*tn(n){for await(let e of n)await new Promise(t=>setTimeout(t,50+Math.random()*50)),yield e;}var lt,nt,H,ce,Le=v(()=>{_e();tt();Te();ke();ve();lt=200;nt=new Set(["anthropic-api","openai-api","ollama"]),H=class extends Error{code="ALL_PROVIDERS_FAILED";fallbackChain;constructor(e){super(`All providers failed. Chain: ${e.join(" \u2192 ")}`),this.name="RelayError",this.fallbackChain=e;}};ce=class n{healthMap=new Map;engineEvents=new ae;static UNHEALTHY_TTL_MS=300*1e3;getHealthStatus(e){let t=this.healthMap.get(e);if(!t)return "healthy";if(t.status==="unhealthy"&&Date.now()-t.updatedAt>=n.UNHEALTHY_TTL_MS){let r=Date.now()-t.updatedAt;return this.healthMap.delete(e),I("engine.recovered",{providerType:e,ageMs:r}),"healthy"}return t.status}markUnhealthy(e,t){this.healthMap.set(e,{status:"unhealthy",lastError:t,updatedAt:Date.now()}),I("engine.unhealthy",{providerType:e,reason:t});}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 i=st(t),o=[],s=rt(e),a=randomUUID(),l=Date.now();for(let p of i){let d=p.type;if(this.getHealthStatus(d)==="unhealthy"){o.push(`${d}:skipped:unhealthy`);continue}if(s&&!p.supportsMultimodal){o.push(`${d}:skipped:no_multimodal`);continue}let m=we(e.model);if(m&&m!==d&&nt.has(d)){o.push(`${d}:skipped:wrong_provider`);continue}try{let c=await p.execute(e,{signal:r?.signal});return this.markHealthy(d),o.push(`${d}:success`),this.emitEngineEvent({kind:"stream_complete",callId:a,id:randomUUID(),ts:Date.now(),stitched:!1,segments:[{provider:d,inputTokens:c.usage.input_tokens,outputTokens:c.usage.output_tokens,costUsd:c.costUsd,userCostUsd:c.userCostUsd??0}],provider:d,model:c.model,inputTokens:c.usage.input_tokens,outputTokens:c.usage.output_tokens,costUsd:c.costUsd,userCostUsd:c.userCostUsd,durationMs:c.durationMs??Date.now()-l,stopReason:c.stop_reason,fallbackChain:o,rateLimitHit:!1,securityState:r?.licenseState}),{...c,fallbackChain:o}}catch(c){if(c?.name==="AbortError"||r?.signal?.aborted)throw c;switch(Pe(c)){case "rate_limited":p.reportRateLimit({provider:d,utilization:1,resetsAt:Date.now()+6e4}),this.markDegraded(d,"rate_limited"),o.push(`${d}:failed:rate_limited`);break;case "auth_failed":this.markUnhealthy(d,"auth_failed"),o.push(`${d}:failed:auth_failed`);break;case "timeout":o.push(`${d}:failed:timeout`);break;case "provider_incompatible":o.push(`${d}:incompatible`);break;case "gateway_unavailable":this.markUnhealthy(d,"gateway_unavailable"),o.push(le(d,c));break;default:o.push(le(d,c));break}}}throw I("engine.cascade-exhausted",{chain:o,mode:"execute"}),new H(o)}async stream(e,t,r){let i=randomUUID(),o=st(t),s=rt(e),a=Date.now(),l=[],p=null,d=null;for(let g of o){let f=g.type;if(this.getHealthStatus(f)==="unhealthy"){l.push(`${f}:skipped:unhealthy`);continue}if(s&&!g.supportsMultimodal){l.push(`${f}:skipped:no_multimodal`);continue}if(!g.supportsStreaming){l.push(`${f}:skipped:no_streaming`);continue}let R=we(e.model);if(R&&R!==f&&nt.has(f)){l.push(`${f}:skipped:wrong_provider`);continue}try{d=await g.streamRaw(e,{signal:r?.signal}),p=g,l.push(`${f}:success`);break}catch(E){if(E?.name==="AbortError"||r?.signal?.aborted)throw E;switch(Pe(E)){case "rate_limited":g.reportRateLimit({provider:f,utilization:1,resetsAt:Date.now()+6e4}),this.markDegraded(f,"rate_limited"),l.push(`${f}:failed:rate_limited`);break;case "auth_failed":this.markUnhealthy(f,"auth_failed"),l.push(`${f}:failed:auth_failed`);break;case "timeout":l.push(`${f}:failed:timeout`);break;case "provider_incompatible":l.push(`${f}:incompatible`);break;case "gateway_unavailable":this.markUnhealthy(f,"gateway_unavailable"),l.push(le(f,E));break;default:l.push(le(f,E));break}}}if(!p||!d)throw I("engine.cascade-exhausted",{chain:l,mode:"stream"}),new H(l);let m=this,c=r?.maxMidStreamFailovers??2,b=new Set([p]);async function*u(){let g=p,f=d[Symbol.asyncIterator](),R={role:"assistant",content:[]},E={segments:[]},k=it(g.type);E.segments.push(k);let De=0,J=null,z=false,fe=c,V="",G="";for(m.emitEngineEvent({kind:"segment_start",callId:i,id:randomUUID(),ts:Date.now(),provider:g.type});;)try{for(;;){let T=await f.next();if(T.done)break;let U=T.value,x=Xt(U,De,R,z,J);if(x.action==="suppress"){"coalesceMode"in x&&(J=x.coalesceMode),x.clearedJustFailedOver&&(z=!1);continue}x.coalesceModeCleared&&(J=null),x.clearedJustFailedOver&&(z=!1);let A=x.event;if(zt(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&&(G=A.delta.stop_reason),A.usage)){Jt(k,g.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(g.type),m.emitEngineEvent({kind:"segment_complete",callId:i,id:randomUUID(),ts:Date.now(),provider:g.type,usage:{...k}});let S=ot(E.segments);yield {type:"message_delta",delta:{stop_reason:G||"end_turn"},usage:S},yield {type:"message_stop"},m.emitEngineEvent({kind:"stream_complete",callId:i,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()-a,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=Pe(S);try{await f.return?.();}catch{}if(m.markUnhealthy(g.type,String(S)),m.emitEngineEvent({kind:"mid_stream_failover_attempt",callId:i,id:randomUUID(),ts:Date.now(),from:g.type,bytesBuffered:at(R),errorClass:T,retriesLeft:fe}),l.push(`${g.type}:partial(${at(R)}b)`),fe<=0)throw m.emitTerminalExhaustion(i,E,V,G,l,a,r?.licenseState),S;let U=Qt(R.content),x=[...e.messages,{role:"assistant",content:U}],A=null,X=null,Me=g;for(;;){let D=m.nextHealthyProvider(o,Me,s,b);if(!D)break;Me=D,b.add(D);let Rt={...e,messages:x,...D.type!=="anthropic-api"&&D.type!=="claude-cli"?{system:Zt(e.system,"[SYSTEM]: CONTINUE_LAST_RESPONSE_WITHOUT_REPEATING")}:{}};try{X=await D.streamRaw(Rt,{signal:r?.signal}),A=D;break}catch(Oe){m.markUnhealthy(D.type,String(Oe)),l.push(`${D.type}:failed_connect:${String(Oe).slice(0,lt)}`);}}if(!A||!X)throw m.emitTerminalExhaustion(i,E,V,G,l,a,r?.licenseState),S;l.push(`${A.type}:stitched`),m.emitEngineEvent({kind:"mid_stream_failover_success",callId:i,id:randomUUID(),ts:Date.now(),from:g.type,to:A.type}),De=en(R)+1,fe--,g=A,f=X[Symbol.asyncIterator](),z=true,J=null,k=it(g.type),E.segments.push(k),m.emitEngineEvent({kind:"segment_start",callId:i,id:randomUUID(),ts:Date.now(),provider:g.type});}}let y=u();return r?.licenseState==="SEC_DEGRADED"&&(y=tn(y)),Q(y)}nextHealthyProvider(e,t,r,i){let o=e.indexOf(t);if(o===-1)return null;for(let s=o+1;s<e.length;s++){let a=e[s];if(!i.has(a)&&!(r&&!a.supportsMultimodal)&&a.supportsStreaming)return a}return null}emitEngineEvent(e){this.engineEvents.emitTyped(e);}emitTerminalExhaustion(e,t,r,i,o,s,a){let l=ot(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,d)=>p+d.costUsd,0),userCostUsd:t.segments.reduce((p,d)=>p+d.userCostUsd,0),durationMs:Date.now()-s,stopReason:i||"error",fallbackChain:o,rateLimitHit:false,securityState:a});}};});function ct(n,e){if(e==="prefer-user"){let i=n.filter(s=>s.type==="claude-cli"),o=n.filter(s=>s.type!=="claude-cli");return [...i,...o]}if(e==="prefer-app"){let i=n.filter(s=>s.type==="claude-cli");return [...n.filter(s=>s.type!=="claude-cli"),...i]}let t=n.filter(i=>i.type===e),r=n.filter(i=>i.type!==e);return [...t,...r]}function ut(n){return (e,t)=>n.maxCostPerCall!==void 0&&t.estimatedCost>n.maxCostPerCall?"prefer-user":n.preferLocal?"ollama":"prefer-user"}var dt=v(()=>{});function pt(n){if(xe[n])return xe[n];for(let[e,t]of Object.entries(xe))if(n.startsWith(e))return t;return [3,15]}var xe,mt=v(()=>{xe={"claude-opus-4":[15,75],"claude-sonnet-4":[3,15],"claude-haiku-4":[.8,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 ht(n){let e=0;for(let a of n.messages)if(typeof a.content=="string")e+=a.content.length;else if(Array.isArray(a.content))for(let l of a.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),[i,o]=pt(n.model),s=(t*i+r*o)/1e6;return {estimatedInputTokens:t,estimatedCost:Math.round(s*1e4)/1e4,model:n.model,provider:""}}var gt=v(()=>{mt();});var ue,ft=v(()=>{ue=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=i=>this.bufferLineageEvent(i),r=i=>{i.kind==="stream_complete"&&this.flushLineageForCall(i);};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(i=>i.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 de(n,e){if(!n)return {valid:false,error:"License key required. Get one at inference-relay.com"};let t=F.get(n);if(t&&Date.now()-t.cachedAt<t.ttl)return t.result;let r=new AbortController,o=!F.has(n)?3e3:1e3,s=setTimeout(()=>r.abort(),o),a;try{let p=(e||nn)+rn;a=await(await fetch(p,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({key:n}),signal:r.signal})).json();}catch{return clearTimeout(s),t&&Date.now()-t.cachedAt<on?t.result:{valid:false,error:"License validation failed (network error). Visit inference-relay.com"}}clearTimeout(s);let l;if(a.jws)try{let{compactVerify:p,importSPKI:d}=await import('jose'),h=await d(an,"RS256"),{payload:m}=await p(a.jws,h);l=JSON.parse(new TextDecoder().decode(m));}catch{return F.delete(n),{valid:false,error:"License validation signature invalid. Possible MITM \u2014 refusing to start."}}else if(l=a,l.valid)return F.delete(n),{valid:false,error:"License validation response not signed. Possible MITM."};return F.set(n,{result:l,cachedAt:Date.now(),ttl:l.valid?sn:6e4}),l}var nn,rn,sn,on,an,F,pe,yt=v(()=>{ye();We();Je();Ze();et();Le();te();dt();gt();be();ft();nn="https://api.inference-relay.com",rn="/v1/validate",sn=1440*60*1e3,on=10080*60*1e3,an=`-----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-----`,U=new Map;ue=class n{providers=[];config;fallbackEngine;telemetryReporter;routingFn=null;license=null;licensePromise=null;licenseValidatedAt=0;callsSinceValidation=0;manifestDecryptor=new G;capProbeTimer=null;capProbeTicksRemaining=0;messages;constructor(e){if(this.config=e,this.fallbackEngine=new ae,this.telemetryReporter=new le({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=at(e.routing)),e.providers)for(let s of e.providers){let o=typeof s=="string"?{type:s}:s,i=this.createProvider(o);i&&(o.priority!==void 0&&(i.priority=o.priority),this.providers.push(i));}let t=100,r=3600*1e3;this.messages={create:async(s,o)=>{let i=this.license&&(this.callsSinceValidation>=t||Date.now()-this.licenseValidatedAt>=r);if(i&&(this.license=null),!this.license){this.licensePromise||(this.licensePromise=ce(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 N({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||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,o):this.executeMessage(s,o)}};}startCapProbe(){if(this.capProbeTimer!==null)return;let e=15e3,t=20,r=4;this.capProbeTicksRemaining=t;let s=async()=>{this.capProbeTicksRemaining-=1;let o=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 (${o}m remaining)`),this.config.licenseKey&&U.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 ce(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 F();return r.available&&r.authenticated!==false&&t.push({type:"claude-cli",priority:1}),process.env.ANTHROPIC_API_KEY&&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,...e})}dispose(){this.providers=[],this.config.licenseKey&&U.delete(this.config.licenseKey),this.license=null,this.licensePromise=null,this.callsSinceValidation=0,this.stopCapProbe(),this.telemetryReporter.unsubscribe(),this.manifestDecryptor.clearCache(),Oe();}resolveProviders(e){if(!this.routingFn)return this.providers;let t=dt(e),r=this.routingFn(e,t);return ot(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()})}async streamMessage(e,t){let r=this.resolveProviders(e);return this.fallbackEngine.stream(e,r,{signal:t?.signal,licenseState:this.manifestDecryptor.getSecurityState()})}createProvider(e){switch(e.type){case "claude-cli":return new ee(this.config.licenseKey);case "anthropic-api":return e.apiKey?new ne({apiKey:e.apiKey,baseUrl:e.baseUrl}):null;case "openai-api":return e.apiKey?new re({apiKey:e.apiKey,baseUrl:e.baseUrl}):null;case "ollama":return new se({baseUrl:e.baseUrl});default:return null}}};});var gt=C(()=>{Z();});var yt={};De(yt,{runVerify:()=>ln});function T(n,e){let t=n.padEnd(13);console.log(`${_("[ir]")} ${t}${e}`);}function pe(n){if(n instanceof N)return {label:"CAP_EXCEEDED",hint:"Monthly cap reached. Buy a top-up at https://inference-relay.com/dashboard/billing",code:1};if(n instanceof H)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 ${K/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 ft(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 ln(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 ce(r);}catch(b){return T("IDENTITY:",D("FAILED")),console.error(` ${b.message||"unknown error"}`),1}if(!s.valid)return T("IDENTITY:",D("REJECTED")),s.error&&console.error(` ${s.error}`),1;T("IDENTITY:",W("VALIDATED"));let o=(s.tier??"unknown").toUpperCase();T("TIER:",W(o));let i;try{i=await F();}catch{i=null;}if(!i||!i.available)return T("RELAY:",de("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 T("RELAY:",de("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(de(` Warning: ${i.versionWarning}`)),t)return T("RELAY:",W("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}`)),ft(s),0;let a=new ue({licenseKey:r,providers:[{type:"claude-cli",priority:1}],fallback:false,telemetry:false}),l=new AbortController,p=setTimeout(()=>l.abort(),K),c=Date.now(),d;try{d=await a.messages.create(rn,{signal:l.signal});}catch(b){clearTimeout(p),a.dispose();let{label:u,hint:y}=pe(b);return T("RELAY:",D(`DEGRADED \u2014 ${u}`)),console.log(_(` ${y}`)),i.cliVersion&&console.log(_(` Claude CLI: v${i.cliVersion}`)),1}if(clearTimeout(p),process.platform==="win32"){let b=new AbortController,u=setTimeout(()=>b.abort(),K);try{await a.messages.create(sn,{signal:b.signal});}catch(E){clearTimeout(u),a.dispose();let{hint:k}=pe(E);return T("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(u);let y=new AbortController,h=setTimeout(()=>y.abort(),K);try{await a.messages.create(on,{signal:y.signal});}catch(E){clearTimeout(h),a.dispose();let{hint:k}=pe(E);return T("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(h);let g=new AbortController,R=setTimeout(()=>g.abort(),K);try{await a.messages.create(an,{signal:g.signal});}catch(E){clearTimeout(R),a.dispose();let{hint:k}=pe(E);return T("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);}a.dispose();let f=Date.now()-c;return d.fallbackChain?.[0]?.startsWith("claude-cli:success")?(T("RELAY:",W("ACTIVE")),console.log(_(` Round-trip: ${f}ms via ${d.provider}`)),console.log(_(` Model echo: ${d.model}`)),console.log(_(` Tokens: ${d.usage.input_tokens} in / ${d.usage.output_tokens} out`)),i.cliVersion&&console.log(_(` Claude CLI: v${i.cliVersion}`)),console.log(_(` Multimodal: ${W("\u2713")} via claude-cli (subscription)`)),i.subscriptionType&&i.subscriptionType!=="unknown"&&console.log(_(` Tier: ${i.subscriptionType}`)),ft(s),0):(T("RELAY:",de("UNEXPECTED")),console.log(_(` Native Gateway did not handle the call. Chain: ${d.fallbackChain?.join(" \u2192 ")}`)),1)}var nn,me,W,D,de,_,K,rn,sn,on,an,_t=C(()=>{ht();we();ge();gt();nn=process.stdout.isTTY===true,me=(n,e)=>nn?`\x1B[${n}m${e}\x1B[0m`:e,W=n=>me("32",n),D=n=>me("31",n),de=n=>me("33",n),_=n=>me("2",n);K=15e3,rn={model:"claude-haiku-4-5",max_tokens:1,messages:[{role:"user",content:"Reply with exactly the single character k and nothing else."}]},sn={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."}]},on={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}]},an={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 Et={verify:async()=>{let{runVerify:n}=await Promise.resolve().then(()=>(_t(),yt));return n()}};function bt(){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")&&(bt(),process.exit(M?0:2));M in Et||(console.error(`Unknown command: ${M}`),console.error(""),bt(),process.exit(1));Et[M]().then(n=>process.exit(n)).catch(n=>{console.error(`[ir] failed to run command "${M}":`),console.error(n),process.exit(99);});
|
|
24
|
+
-----END PUBLIC KEY-----`,F=new Map;pe=class n{providers=[];config;fallbackEngine;telemetryReporter;routingFn=null;license=null;licensePromise=null;licenseValidatedAt=0;callsSinceValidation=0;manifestDecryptor=new W;capProbeTimer=null;capProbeTicksRemaining=0;messages;constructor(e){if(this.config=e,this.fallbackEngine=new ce,this.telemetryReporter=new ue({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=ut(e.routing)),e.providers)for(let i of e.providers){let o=typeof i=="string"?{type:i}:i,s=this.createProvider(o);s&&(o.priority!==void 0&&(s.priority=o.priority),this.providers.push(s));}let t=100,r=3600*1e3;this.messages={create:async(i,o)=>{let s=this.license&&(this.callsSinceValidation>=t||Date.now()-this.licenseValidatedAt>=r);if(s&&(this.license=null),!this.license){this.licensePromise||(this.licensePromise=de(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});s||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++,i.stream?this.streamMessage(i,o):this.executeMessage(i,o)}};}startCapProbe(){if(this.capProbeTimer!==null)return;let e=15e3,t=20,r=4;this.capProbeTicksRemaining=t;let i=async()=>{this.capProbeTicksRemaining-=1;let o=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 (${o}m remaining)`),this.config.licenseKey&&F.delete(this.config.licenseKey);try{let s=await this.probeValidate();if(s.valid&&s.capExceeded===!1){console.log("[inference-relay] cap cleared \u2014 probe exiting, inference resuming"),this.license=s,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(i,e),typeof this.capProbeTimer.unref=="function"&&this.capProbeTimer.unref();}async probeValidate(){return de(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 $();return r.available&&r.authenticated!==false&&t.push({type:"claude-cli",priority:1}),process.env.ANTHROPIC_API_KEY&&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,...e})}async warmup(){let e=this.providers.find(t=>t.type==="claude-cli");e&&"warmup"in e&&typeof e.warmup=="function"&&await e.warmup();}dispose(){this.providers=[],this.config.licenseKey&&F.delete(this.config.licenseKey),this.license=null,this.licensePromise=null,this.callsSinceValidation=0,this.stopCapProbe(),this.telemetryReporter.unsubscribe(),this.manifestDecryptor.clearCache(),Fe();}resolveProviders(e){if(!this.routingFn)return this.providers;let t=ht(e),r=this.routingFn(e,t);return ct(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()})}async streamMessage(e,t){let r=this.resolveProviders(e);return this.fallbackEngine.stream(e,r,{signal:t?.signal,licenseState:this.manifestDecryptor.getSecurityState()})}createProvider(e){switch(e.type){case "claude-cli":return new ne(this.config.licenseKey,{retryDelaysMs:this.config.gatewayRetryDelaysMs});case "anthropic-api":return e.apiKey?new se({apiKey:e.apiKey,baseUrl:e.baseUrl}):null;case "openai-api":return e.apiKey?new ie({apiKey:e.apiKey,baseUrl:e.baseUrl}):null;case "ollama":return new oe({baseUrl:e.baseUrl});default:return null}}};});var _t=v(()=>{te();});var bt={};Ue(bt,{runVerify:()=>mn});function w(n,e){let t=n.padEnd(13);console.log(`${_("[ir]")} ${t}${e}`);}function he(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 H)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 ${q/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 Et(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 mn(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 i;try{i=await de(r);}catch(b){return w("IDENTITY:",M("FAILED")),console.error(` ${b.message||"unknown error"}`),1}if(!i.valid)return w("IDENTITY:",M("REJECTED")),i.error&&console.error(` ${i.error}`),1;w("IDENTITY:",j("VALIDATED"));let o=(i.tier??"unknown").toUpperCase();w("TIER:",j(o));let s;try{s=await $();}catch{s=null;}if(!s||!s.available)return w("RELAY:",me("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(!s.authenticated)return w("RELAY:",me("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(s.versionWarning&&console.log(me(` Warning: ${s.versionWarning}`)),t)return w("RELAY:",j("READY")),console.log(_(" Credentials present. Round-trip skipped (--credentials-only).")),s.cliVersion&&console.log(_(` Claude CLI: v${s.cliVersion}`)),s.subscriptionType&&s.subscriptionType!=="unknown"&&console.log(_(` Tier: ${s.subscriptionType}`)),Et(i),0;let a=new pe({licenseKey:r,providers:[{type:"claude-cli",priority:1}],fallback:false,telemetry:false}),l=new AbortController,p=setTimeout(()=>l.abort(),q),d=Date.now(),h;try{h=await a.messages.create(cn,{signal:l.signal});}catch(b){clearTimeout(p),a.dispose();let{label:u,hint:y}=he(b);return w("RELAY:",M(`DEGRADED \u2014 ${u}`)),console.log(_(` ${y}`)),s.cliVersion&&console.log(_(` Claude CLI: v${s.cliVersion}`)),1}if(clearTimeout(p),process.platform==="win32"){let b=new AbortController,u=setTimeout(()=>b.abort(),q);try{await a.messages.create(un,{signal:b.signal});}catch(E){clearTimeout(u),a.dispose();let{hint:k}=he(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).")),s.cliVersion&&console.log(_(` Claude CLI: v${s.cliVersion}`)),1}clearTimeout(u);let y=new AbortController,g=setTimeout(()=>y.abort(),q);try{await a.messages.create(dn,{signal:y.signal});}catch(E){clearTimeout(g),a.dispose();let{hint:k}=he(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).")),s.cliVersion&&console.log(_(` Claude CLI: v${s.cliVersion}`)),1}clearTimeout(g);let f=new AbortController,R=setTimeout(()=>f.abort(),q);try{await a.messages.create(pn,{signal:f.signal});}catch(E){clearTimeout(R),a.dispose();let{hint:k}=he(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).")),s.cliVersion&&console.log(_(` Claude CLI: v${s.cliVersion}`)),1}clearTimeout(R);}a.dispose();let m=Date.now()-d;return h.fallbackChain?.[0]?.startsWith("claude-cli:success")?(w("RELAY:",j("ACTIVE")),console.log(_(` Round-trip: ${m}ms via ${h.provider}`)),console.log(_(` Model echo: ${h.model}`)),console.log(_(` Tokens: ${h.usage.input_tokens} in / ${h.usage.output_tokens} out`)),s.cliVersion&&console.log(_(` Claude CLI: v${s.cliVersion}`)),console.log(_(` Multimodal: ${j("\u2713")} via claude-cli (subscription)`)),s.subscriptionType&&s.subscriptionType!=="unknown"&&console.log(_(` Tier: ${s.subscriptionType}`)),Et(i),0):(w("RELAY:",me("UNEXPECTED")),console.log(_(` Native Gateway did not handle the call. Chain: ${h.fallbackChain?.join(" \u2192 ")}`)),1)}var ln,ge,j,M,me,_,q,cn,un,dn,pn,vt=v(()=>{yt();Le();ye();_t();ln=process.stdout.isTTY===true,ge=(n,e)=>ln?`\x1B[${n}m${e}\x1B[0m`:e,j=n=>ge("32",n),M=n=>ge("31",n),me=n=>ge("33",n),_=n=>ge("2",n);q=15e3,cn={model:"claude-haiku-4-5",max_tokens:1,messages:[{role:"user",content:"Reply with exactly the single character k and nothing else."}]},un={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."}]},dn={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}]},pn={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 Ct={verify:async()=>{let{runVerify:n}=await Promise.resolve().then(()=>(vt(),bt));return n()}};function At(){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")&&(At(),process.exit(O?0:2));O in Ct||(console.error(`Unknown command: ${O}`),console.error(""),At(),process.exit(1));Ct[O]().then(n=>process.exit(n)).catch(n=>{console.error(`[ir] failed to run command "${O}":`),console.error(n),process.exit(99);});
|
|
@@ -13,6 +13,17 @@ interface InferenceRelayConfig {
|
|
|
13
13
|
* original error is rethrown to the consumer. Default: 2.
|
|
14
14
|
*/
|
|
15
15
|
maxMidStreamFailovers?: number;
|
|
16
|
+
/**
|
|
17
|
+
* Per-attempt delay budget (ms) for the gateway-bundle fetch retry loop.
|
|
18
|
+
* Defaults to `[0, 1000, 4000]` (3 attempts over ~5s). Env override:
|
|
19
|
+
* `IR_GATEWAY_RETRY_DELAYS_MS=0,5000,15000,60000`. Constructor option
|
|
20
|
+
* wins over env. Added in 1.6.2 to let ops ride out sustained
|
|
21
|
+
* Cloudflare/Convex 502s longer than the 5s default.
|
|
22
|
+
*
|
|
23
|
+
* Auto-mode (`import 'inference-relay/auto'`) reads the env var only —
|
|
24
|
+
* there's no constructor-options touchpoint in that flow.
|
|
25
|
+
*/
|
|
26
|
+
gatewayRetryDelaysMs?: number[];
|
|
16
27
|
}
|
|
17
28
|
/**
|
|
18
29
|
* Security state of the licence validation chain. Mirrors the state machine
|
|
@@ -13,6 +13,17 @@ interface InferenceRelayConfig {
|
|
|
13
13
|
* original error is rethrown to the consumer. Default: 2.
|
|
14
14
|
*/
|
|
15
15
|
maxMidStreamFailovers?: number;
|
|
16
|
+
/**
|
|
17
|
+
* Per-attempt delay budget (ms) for the gateway-bundle fetch retry loop.
|
|
18
|
+
* Defaults to `[0, 1000, 4000]` (3 attempts over ~5s). Env override:
|
|
19
|
+
* `IR_GATEWAY_RETRY_DELAYS_MS=0,5000,15000,60000`. Constructor option
|
|
20
|
+
* wins over env. Added in 1.6.2 to let ops ride out sustained
|
|
21
|
+
* Cloudflare/Convex 502s longer than the 5s default.
|
|
22
|
+
*
|
|
23
|
+
* Auto-mode (`import 'inference-relay/auto'`) reads the env var only —
|
|
24
|
+
* there's no constructor-options touchpoint in that flow.
|
|
25
|
+
*/
|
|
26
|
+
gatewayRetryDelaysMs?: number[];
|
|
16
27
|
}
|
|
17
28
|
/**
|
|
18
29
|
* Security state of the licence validation chain. Mirrors the state machine
|