@wengine-ai/llms 2.3.2412 → 2.3.2413

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  import { createRequire as __createRequire } from "node:module"; import { fileURLToPath as __fileURLToPath } from "node:url"; import { dirname as __pathDirname } from "node:path"; const require = __createRequire(import.meta.url); const __filename = __fileURLToPath(import.meta.url); const __dirname = __pathDirname(__filename);
2
2
  var to=Object.defineProperty;var nc=Object.getOwnPropertyDescriptor;var oc=Object.getOwnPropertyNames;var rc=Object.prototype.hasOwnProperty;var Xe=(n=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(n,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):n)(function(n){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+n+'" is not supported')});var E=(n,e)=>()=>(n&&(e=n(n=0)),e);var no=(n,e)=>{for(var t in e)to(n,t,{get:e[t],enumerable:!0})},sc=(n,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of oc(e))!rc.call(n,r)&&r!==t&&to(n,r,{get:()=>e[r],enumerable:!(o=nc(e,r))||o.enumerable});return n};var ic=n=>sc(to({},"__esModule",{value:!0}),n);import{ProxyAgent as ac}from"undici";function lc(n){if(n==null)return{ok:!0};let e=String(n).trim();if(!e)return{ok:!0};if(cc.test(e))return{ok:!0};try{let t=new URL(e);return t.protocol!=="http:"&&t.protocol!=="https:"?{ok:!1,error:`Unsupported proxy protocol: ${t.protocol}. Only http:// and https:// are allowed.`}:{ok:!0}}catch{return{ok:!1,error:`Invalid proxy URL: ${e}`}}}function Kr(n){let e=[];for(let t of Wr){let o=n[t];if(o==null)continue;let r=lc(o);r.ok||e.push({key:t,error:r.error})}return e}function Rt(n){for(let e of Wr){let t=n.get(e);if(t==null)continue;let o=String(t).trim();if(o)return o}}function Gr(n){if(n==null||n==="")return!0;if(typeof n=="string"){let e=n.trim().toLowerCase();return e==="false"||e==="0"?!1:e==="true"||e==="1"?!0:!!e}return n===!1||n===0?!1:n===!0||n===1?!0:!!n}function ce(n,e){let t=Rt(n);if(t)return Gr(n.get("PROXY_GLOBAL_ENABLED"))||e?.proxyEnabled===!0||e?.proxy_enabled===!0?t:void 0}function G(n){let e=uc(n),t=St.get(e);if(t)return t;let o=new ac(e);return St.set(e,o),o}async function oo(){let n=Array.from(St.values());St.clear(),await Promise.allSettled(n.map(e=>e.close()))}function uc(n){let e=n.trim();if(!e)throw new TypeError("Proxy URL must not be empty");let t=new URL(e);if(t.protocol!=="http:"&&t.protocol!=="https:")throw new TypeError(`Unsupported proxy protocol: ${t.protocol}`);return t.toString()}var Wr,cc,St,oe=E(()=>{"use strict";Wr=["HTTPS_PROXY","https_proxy","httpsProxy","PROXY_URL"],cc=/\$\{[^}]+\}|\$[A-Z_][A-Z0-9_]*/;St=new Map});import{readFileSync as dc,existsSync as Vr}from"fs";import{join as Qr}from"path";import{config as pc}from"dotenv";import fc from"json5";var Re,ro=E(()=>{"use strict";oe();Re=class{config={};options;constructor(e={jsonPath:"./config.json"}){this.options={envPath:e.envPath||".env",jsonPath:e.jsonPath,useEnvFile:!1,useJsonFile:e.useJsonFile!==!1,useEnvironmentVariables:e.useEnvironmentVariables!==!1,...e},this.loadConfig()}loadConfig(){this.options.useJsonFile&&this.options.jsonPath&&this.loadJsonConfig(),this.options.initialConfig&&(this.config={...this.config,...this.options.initialConfig}),this.options.useEnvFile&&this.loadEnvConfig(),this.config.LOG_FILE&&(process.env.LOG_FILE=this.config.LOG_FILE),this.config.LOG&&(process.env.LOG=this.config.LOG)}loadJsonConfig(){if(!this.options.jsonPath)return;let e=this.isAbsolutePath(this.options.jsonPath)?this.options.jsonPath:Qr(process.cwd(),this.options.jsonPath);if(Vr(e))try{let t=dc(e,"utf-8"),o=fc.parse(t);this.config={...this.config,...o},console.log(`Loaded JSON config from: ${e}`)}catch(t){console.warn(`Failed to load JSON config from ${e}:`,t)}else console.warn(`JSON config file not found: ${e}`)}loadEnvConfig(){let e=this.isAbsolutePath(this.options.envPath)?this.options.envPath:Qr(process.cwd(),this.options.envPath);if(Vr(e))try{let t=pc({path:e});t.parsed&&(this.config={...this.config,...this.parseEnvConfig(t.parsed)})}catch(t){console.warn(`Failed to load .env config from ${e}:`,t)}}loadEnvironmentVariables(){let e=this.parseEnvConfig(process.env);this.config={...this.config,...e}}parseEnvConfig(e){let t={};return Object.assign(t,e),t}isAbsolutePath(e){return e.startsWith("/")||e.includes(":")}get(e,t){let o=this.config[e];return o!==void 0?o:t}getAll(){return{...this.config}}getHttpsProxy(){return Rt(this)}has(e){return this.config[e]!==void 0}set(e,t){this.config[e]=t}reload(){this.config={},this.loadConfig()}getConfigSummary(){let e=[];return this.options.initialConfig&&e.push("Initial Config"),this.options.useJsonFile&&this.options.jsonPath&&e.push(`JSON: ${this.options.jsonPath}`),this.options.useEnvFile&&e.push(`ENV: ${this.options.envPath}`),this.options.useEnvironmentVariables&&e.push("Environment Variables"),`Config sources: ${e.join(", ")}`}}});function J(n,e=500,t="internal_error",o="api_error"){let r=new Error(n);return r.statusCode=e,r.code=t,r.type=o,r}async function Yr(n,e,t){e.log.error(n);let o=n.statusCode||500;if(n.rawBody)try{let s=JSON.parse(n.rawBody);return t.code(o).send(s)}catch{return t.code(o).send(n.rawBody)}let r={error:{message:n.message||"Internal Server Error",type:n.type||"api_error",code:n.code||"internal_error"}};return t.code(o).send(r)}var wt=E(()=>{"use strict"});function io(n){so=n}function Et(){return so}function Pt(n){return so||n.get("DEBUG_LOG")===!0}function qr(n){let e=n.get("DEBUG_LOG_OPTIONS");return!e||typeof e!="object"?we:{maxBodyLength:e.maxBodyLength??we.maxBodyLength,maxStreamChunks:e.maxStreamChunks??we.maxStreamChunks}}function Ot(n){let e={};for(let[t,o]of Object.entries(n))mc.has(t.toLowerCase())?e[t]="***MASKED***":e[t]=o;return e}function At(n,e){return n.length<=e?n:n.slice(0,e)+`...[truncated, total ${n.length} bytes]`}function es(n,e,t){let o=typeof t.body=="string"?t.body:JSON.stringify(t.body);n.info({debug_log:!0,reqId:e,phase:"provider_request",url:t.url,headers:Ot(t.headers),body:At(o,we.maxBodyLength)})}function ts(n,e,t){n.info({debug_log:!0,reqId:e,phase:"provider_response",status:t.status,headers:Ot(t.headers),...t.body!==void 0?{body:At(t.body,we.maxBodyLength)}:{}})}function Xr(n,e,t,o){let r=gc(o);n.info({debug_log:!0,reqId:e,phase:"provider_stream_chunk",chunkIndex:t,...r?{usage_monitor:r}:{},data:At(o,we.maxBodyLength)})}function gc(n){let e=[];for(let t of n.split(/\r?\n/)){if(!t.startsWith("data:"))continue;let o=t.slice(5).trim();if(!(!o||o==="[DONE]"))try{let r=JSON.parse(o),s=r?.usage||r?.response?.usage;s&&e.push({path:r?.usage?"usage":"response.usage",usage:s,choicesLength:Array.isArray(r?.choices)?r.choices.length:void 0,finishReason:r?.choices?.[0]?.finish_reason})}catch{e.push({parseError:!0,data:At(o,512)})}}if(e.length)return e.length===1?e[0]:e}function Zr(n,e,t){n.info({debug_log:!0,reqId:e,phase:"provider_stream_end",totalChunks:t})}function ns(n,e,t,o){(async()=>{let r=n.pipeThrough(new TextDecoderStream).getReader(),s=0;try{let i="";for(;;){let{done:a,value:l}=await r.read();if(a)break;i+=l;let c=i.split(`
3
3
 
4
- `);i=c.pop()||"";for(let u of c)u.trim()&&(s<o.maxStreamChunks?Xr(e,t,s,u):s===o.maxStreamChunks&&e.info({debug_log:!0,reqId:t,phase:"provider_stream_chunk_omitted",message:`[chunks after #${s} omitted, maxStreamChunks=${o.maxStreamChunks}]`}),s++)}i.trim()&&(s<o.maxStreamChunks&&Xr(e,t,s,i.trim()),s++),Zr(e,t,s)}catch(i){console.error(`[debug_log] Error reading debug stream for reqId=${t}:`,i),Zr(e,t,s)}finally{r.releaseLock()}})()}var mc,we,so,Ze=E(()=>{"use strict";mc=new Set(["authorization","x-api-key","x-goog-api-key","cookie","set-cookie"]),we={maxBodyLength:4096,maxStreamChunks:100},so=!1});function os(n,e,t,o,r){let s=new Headers({"Content-Type":"application/json"});t.headers&&Object.entries(t.headers).forEach(([c,u])=>{u&&s.set(c,u)});let i,a=AbortSignal.timeout(t.TIMEOUT??60*1e3*60);if(t.signal){let c=new AbortController,u=()=>c.abort();t.signal.addEventListener("abort",u),a.addEventListener("abort",u),i=c.signal}else i=a;let l={method:"POST",headers:s,body:JSON.stringify(e),signal:i};return t.httpsProxy&&(l.dispatcher=G(t.httpsProxy)),r?.debug({reqId:o.req.id,method:"POST",headers:Ot(Object.fromEntries(s.entries())),requestUrl:typeof n=="string"?n:n.toString(),useProxy:hc(t.httpsProxy)},"final request"),fetch(typeof n=="string"?n:n.toString(),l)}function hc(n){if(!(typeof n!="string"||!n.trim()))try{let e=new URL(n);return e.username||e.password?(e.username="",e.password="",`${e.toString()} (credentials redacted)`):e.toString()}catch{return"[invalid proxy URL]"}}var rs=E(()=>{oe();Ze()});var It,ao=E(()=>{It="2.3.2412"});var ss={};no(ss,{getFallbackPromotionStore:()=>Ee,resetFallbackPromotionStore:()=>kc});function Ee(n){return ve||(ve=new co,n&&ve.configure(n)),ve}function kc(){ve&&(ve.clearAll(),ve=null)}var _c,co,ve,Mt=E(()=>{"use strict";re();_c=600*1e3,co=class{promotions=new Map;enabled=!0;ttlMs=_c;configure(e){e?.enabled!==void 0&&(this.enabled=e.enabled),e?.ttlMinutes!==void 0&&(this.ttlMs=e.ttlMinutes*60*1e3)}getKey(e,t,o){return`${e},${t}:${o}`}promote(e,t,o,r,s,i){if(!this.enabled)return;let a=this.getKey(e,t,o),l=`${r},${s}`;this.promotions.set(a,{promotedModel:l,timestamp:Date.now(),ttlMs:i??this.ttlMs})}getPromotion(e,t,o,r){if(!this.enabled)return null;let s=this.getKey(e,t,o),i=this.promotions.get(s);if(!i)return null;if(Date.now()-i.timestamp>=i.ttlMs)return this.promotions.delete(s),null;let[l,...c]=i.promotedModel.split(","),u=c.join(",");if(!U().isAvailable(l,u))return this.promotions.delete(s),null;let p=r.find(h=>h.name.toLowerCase()===l.toLowerCase()),m=p?.models?.find(h=>String(h).toLowerCase()===u.toLowerCase());return!p||!m||p.enabled===!1?(this.promotions.delete(s),null):`${p.name},${m}`}clear(e,t,o){let r=this.getKey(e,t,o);this.promotions.delete(r)}clearByPrimary(e,t){let o=`${e},${t}:`,r=0;for(let s of this.promotions.keys())s.startsWith(o)&&(this.promotions.delete(s),r++);return r}clearAll(){this.promotions.clear()}clearExpired(){let e=Date.now();for(let[t,o]of this.promotions)e-o.timestamp>=o.ttlMs&&this.promotions.delete(t)}getAllPromotions(){let e=Date.now(),t=[];for(let[o,r]of this.promotions){let s=r.ttlMs-(e-r.timestamp);s>0&&t.push({key:o,promotedModel:r.promotedModel,remainingMs:s})}return t}},ve=null});import{existsSync as cs,mkdirSync as bc,readFileSync as Tc,writeFileSync as vc}from"fs";import{join as ls}from"path";import{HOME_DIR as xc}from"@wengine-ai/claude-code-router-shared";function wc(n){try{if(!cs(po))return;let e=JSON.parse(Tc(po,"utf-8"));if(!Array.isArray(e))return;let t=Date.now();for(let o of e){if(!o||!o.provider||!o.model)continue;let r=o.updatedAt||o.lastFailureTime||0;r&&t-r>1440*60*1e3||n.restore({provider:o.provider,model:o.model,status:o.status,failureCount:o.failureCount??0,successCount:o.successCount??0,lastFailureTime:o.lastFailureTime??0,lastProbeTime:o.lastProbeTime??0,lastError:o.lastError,rateLimitUntil:o.rateLimitUntil})}}catch{}}function as(n){try{let e=n.getAllStates();if(e.length===0)return;cs(uo)||bc(uo,{recursive:!0});let t=e.map(o=>({...o,updatedAt:Date.now()}));vc(po,JSON.stringify(t,null,2),"utf-8")}catch{}}function fo(){if(is)return;is=!0;let n=U();wc(n),Rc=setInterval(()=>as(n),6e4),process.on("exit",()=>as(n))}function U(n){return lo||(lo=new Nt(n)),lo}var Cc,Sc,Nt,uo,po,is,Rc,lo,re=E(()=>{"use strict";Cc=120,Sc={enabled:!0,failureThreshold:3,probeIntervalMinutes:5,halfOpenSuccessThreshold:2},Nt=class{states=new Map;config;probeTimer;constructor(e){this.config={...Sc,...e}}getKey(e,t){return!e||!t?null:`${e},${t}`}recordSuccess(e,t){if(!this.config.enabled)return;let o=this.getKey(e,t);if(!o)return;let r=this.states.get(o);r&&(r.successCount++,!r.rateLimitUntil&&(r.status==="half-open"?r.successCount>=this.config.halfOpenSuccessThreshold&&(this.clearPromotionsForPrimary(e,t),this.states.delete(o)):r.status==="open"&&(r.status="half-open",r.successCount=1,r.failureCount=0)))}clearPromotionsForPrimary(e,t){try{let{getFallbackPromotionStore:o}=(Mt(),ic(ss));o().clearByPrimary(e,t)}catch{}}recordFailure(e,t,o){if(!this.config.enabled)return;let r=this.getKey(e,t);if(!r)return;let s=this.states.get(r);s||(s={provider:e,model:t,status:"closed",failureCount:0,successCount:0,lastFailureTime:0,lastProbeTime:0},this.states.set(r,s)),s.failureCount++,s.lastFailureTime=Date.now(),s.lastError=o,s.status==="half-open"?(s.status="open",s.successCount=0,s.lastProbeTime=0):s.status==="closed"&&s.failureCount>=this.config.failureThreshold&&(s.status="open",s.lastProbeTime=0)}getState(e,t){let o=this.getKey(e,t);if(o)return this.states.get(o)}isAvailable(e,t){if(!this.config.enabled)return!0;if(!this.getKey(e,t))return!1;let r=this.getState(e,t);return r?r.status==="open"&&r.rateLimitUntil?!(Date.now()<r.rateLimitUntil):r.status!=="open":!0}getPriority(e,t){if(!this.config.enabled)return 0;if(!this.getKey(e,t))return 2;let r=this.getState(e,t);if(!r)return 0;switch(r.status){case"closed":return 0;case"half-open":return 1;case"open":return 2}}getHealthyModels(){return[]}getFailPoolModels(){let e=[];for(let[t,o]of this.states)o.status==="open"&&e.push(t);return e}getHalfOpenModels(){let e=[];for(let[t,o]of this.states)o.status==="half-open"&&e.push(t);return e}forceOpen(e,t,o){if(!this.config.enabled)return;let r=this.getKey(e,t);if(!r)return;let s=this.states.get(r);s?(s.status="open",s.failureCount=Math.max(s.failureCount,this.config.failureThreshold),s.lastFailureTime=Date.now(),s.lastError=o,s.lastProbeTime=0):(s={provider:e,model:t,status:"open",failureCount:this.config.failureThreshold,successCount:0,lastFailureTime:Date.now(),lastProbeTime:0,lastError:o},this.states.set(r,s))}markRateLimited(e,t,o,r){if(!this.config.enabled)return;let s=this.getKey(e,t);if(!s)return;let i=this.states.get(s);i?(i.status="open",i.lastFailureTime=Date.now(),i.lastError=r||"rate-limited",i.lastProbeTime=0):(i={provider:e,model:t,status:"open",failureCount:0,successCount:0,lastFailureTime:Date.now(),lastProbeTime:0,lastError:r||"rate-limited"},this.states.set(s,i));let a=(o??Cc)*1e3;i.rateLimitUntil=Date.now()+a}getRateLimitedModels(){let e=[];for(let[t,o]of this.states)o.status==="open"&&o.rateLimitUntil&&e.push(t);return e}needsProbe(e){return Date.now()-e.lastProbeTime>=this.config.probeIntervalMinutes*60*1e3}markProbeAttempt(e,t){let o=this.getKey(e,t);if(!o)return;let r=this.states.get(o);r&&r.status==="open"&&(r.lastProbeTime=Date.now())}clear(){this.states.clear()}recover(e,t){let o=this.getKey(e,t);o&&this.states.delete(o)}getAllStates(){return Array.from(this.states.values())}restore(e){let t=this.getKey(e.provider,e.model);t&&this.states.set(t,{...e})}stopProbeTimer(){this.probeTimer&&(clearInterval(this.probeTimer),this.probeTimer=void 0)}},uo=ls(xc,"runtime"),po=ls(uo,"provider-health.json"),is=!1,Rc=null;lo=null});import{existsSync as ms,mkdirSync as Ec,readFileSync as Pc,writeFileSync as Oc}from"fs";import{join as gs}from"path";import{HOME_DIR as Ac}from"@wengine-ai/claude-code-router-shared";function qe(n,e,t){let o=a=>{if(t instanceof Headers)return t.get(a);let l=Object.keys(t).find(c=>c.toLowerCase()===a);return l?t[l]:null},r=mo(o,Ic),s=mo(o,Mc),i=mo(o,Nc);(r||s||i)&&Pe.set(n,{provider:n,remaining:ps(r),limit:ps(s),reset:Lc(i),capturedAt:Date.now()})}function $c(n){return Pe.get(n)}function yo(){return Array.from(Pe.values())}function mo(n,e){for(let t of e){let o=n(t);if(o)return o}return null}function ps(n){if(!n)return null;let e=Number(n.trim().replace(/,/g,""));return Number.isFinite(e)?e:null}function Lc(n){if(!n)return null;let e=n.trim();if(!e)return null;let t=Number(e);if(Number.isFinite(t))return t>1e12?Math.floor(t/1e3):t>1e9?Math.floor(t):Math.floor(Date.now()/1e3+t);let o=Date.parse(e);if(Number.isFinite(o))return Math.floor(o/1e3);let r=Dc(e);return r===null?null:Math.floor((Date.now()+r)/1e3)}function Dc(n){let e=/(\d+(?:\.\d+)?)(ms|s|m|h|d)/gi,t=0,o=!1;for(let r of n.matchAll(e)){o=!0;let s=Number(r[1]),i=r[2].toLowerCase();if(Number.isFinite(s))switch(i){case"ms":t+=s;break;case"s":t+=s*1e3;break;case"m":t+=s*60*1e3;break;case"h":t+=s*60*60*1e3;break;case"d":t+=s*24*60*60*1e3;break}}return o?t:null}function Fc(){try{if(!ms(ho))return;let n=JSON.parse(Pc(ho,"utf-8"));if(!Array.isArray(n))return;let e=Date.now();for(let t of n)if(t&&t.provider){if(t.capturedAt&&e-t.capturedAt>3600*1e3)continue;Pe.set(t.provider,t)}}catch{}}function fs(){try{if(Pe.size===0)return;ms(go)||Ec(go,{recursive:!0}),Oc(ho,JSON.stringify(Array.from(Pe.values()),null,2),"utf-8")}catch{}}function et(){us||(us=!0,Fc(),ds=setInterval(fs,6e4),ds.unref?.(),process.on("exit",fs))}var go,ho,Pe,us,ds,Ic,Mc,Nc,Oe=E(()=>{"use strict";go=gs(Ac,"runtime"),ho=gs(go,"rate-limit.json"),Pe=new Map,us=!1,ds=null,Ic=["x-ratelimit-remaining-tokens","x-ratelimit-remaining-requests","x-ratelimit-remaining"],Mc=["x-ratelimit-limit-tokens","x-ratelimit-limit-requests","x-ratelimit-limit"],Nc=["x-ratelimit-reset-tokens","x-ratelimit-reset-requests","x-ratelimit-reset"]});function Lt(){return _o||(_o=new bo),_o}function vo(){return ko||(ko=new To),ko}function Uc(n){return n?.sessionId||n?.clientContext?.stableSessionId||void 0}function hs(n){let e=Uc(n);if(!e)return"";let t=typeof n?.modelFamily=="string"?n.modelFamily:"",o=typeof n?.scenarioType=="string"&&n.scenarioType?n.scenarioType:"default";return`${e}:${t}:${o}`}function ys(n,e){let t=Lt(),o=n?.[$t];if(o&&!o.released){if(o.key===e)return;t.release(o)}n[$t]=t.acquire(e)}function xo(n){let e=n?.[$t];e&&Lt().release(e)}function _s(n,e){let t=hs(n),o=n?.[$t],r=t?vo().get(t)!==void 0:!1;!o&&!r||(t&&vo().bind(t,e),ys(n,e))}function jc(n,e,t){let o=Lt(),r=null,s=1/0;for(let i of e){if(!i||typeof i!="string")continue;let a=t(i);if(!a||a===n)continue;let l=o.count(a);l<s&&(r=a,s=l)}return r}function ks(n,e,t){let o=hs(n),r=vo(),s=Lt(),i=Number.isFinite(t.threshold)&&t.threshold>0?Math.floor(t.threshold):3,a;if(o){let l=r.get(o);if(l&&l!==e){let c=t.resolve(l);c?(a=c,t.log?.(`Concurrency priority: session slot ${o} sticking to bound model ${c}`)):r.unbind(o)}else l&&(a=e)}if(!a){let l=s.count(e);if(l>=i){let c=jc(e,t.fallbackModels,t.resolve);c&&(a=c,t.log?.(`Concurrency priority: model ${e} has ${l} in-flight request(s) (>= ${i}); assigning ${o?`session slot ${o} `:"request "}to overflow model ${c}`))}a=a||e,o&&r.bind(o,a)}return ys(n,a),a}var bo,To,_o,ko,$t,Dt=E(()=>{"use strict";bo=class{leases=new Map;nextId=1;acquire(e){let t={id:this.nextId++,key:e,createdAt:Date.now(),released:!1};return this.leases.set(t.id,t),t}release(e){!e||e.released||(e.released=!0,this.leases.delete(e.id))}prune(){let e=Date.now();for(let[t,o]of this.leases)e-o.createdAt>18e5&&this.leases.delete(t)}count(e){this.prune();let t=0;for(let o of this.leases.values())o.key===e&&t++;return t}clear(){this.leases.clear()}},To=class{bindings=new Map;get(e){let t=this.bindings.get(e);if(t){if(Date.now()-t.updatedAt>864e5){this.bindings.delete(e);return}return t.updatedAt=Date.now(),this.bindings.delete(e),this.bindings.set(e,t),t.modelKey}}bind(e,t){for(this.bindings.delete(e),this.bindings.set(e,{modelKey:t,updatedAt:Date.now()});this.bindings.size>2e3;){let o=this.bindings.keys().next().value;if(o===void 0)break;this.bindings.delete(o)}}unbind(e){this.bindings.delete(e)}clear(){this.bindings.clear()}},_o=null,ko=null;$t="__concurrencyLease"});async function F(n){let e=await n.text();return Hc(e,n.status)}function Hc(n,e){let t=n.replace(/^/,"").trim();try{return JSON.parse(t)}catch{let o=t.length>200?`${t.slice(0,200)}...`:t,r=e!==void 0?` (HTTP ${e})`:"";throw new Error(`Upstream returned a non-JSON response${r}: ${o||"(empty body)"}`)}}function bs(n){return(n.headers.get("Content-Type")||"").includes("text/event-stream")}function tt(n){return/^\s*(event:|data:|:\s*[A-Z])/m.test(n)||n.startsWith("data:")}async function pe(n){if(!n.body||n.body.locked)return null;let[e,t]=n.body.tee(),o=e.getReader(),r=new TextDecoder,s="";try{for(let i=0;i<8;i++){let{value:a,done:l}=await o.read();if(l||(a&&(s+=r.decode(a,{stream:!0})),tt(s))||/^\s*[\[{]/.test(s))break}s+=r.decode()}finally{o.releaseLock()}return e.cancel().catch(()=>{}),{body:t,isSSE:tt(s)}}async function fe(n){try{let e=await n.text();if(tt(e)){let o=new TextEncoder,r=new ReadableStream({start(s){s.enqueue(o.encode(e)),s.close()}});return{response:new Response(r,{status:n.status,statusText:n.statusText,headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}}),isSSE:!0}}return{response:new Response(e,{status:n.status,statusText:n.statusText,headers:n.headers}),isSSE:!1}}catch{return{response:n,isSSE:!1}}}var V=E(()=>{"use strict"});var Ae,Co=E(()=>{"use strict";V();Ae=class{name="openai-responses";endPoint="/v1/responses";getCacheReadInputTokens(e){return e?.cache_read_input_tokens??e?.input_tokens_details?.cached_tokens??e?.prompt_tokens_details?.cached_tokens??0}getCacheCreationInputTokens(e){return e?.cache_creation_input_tokens??e?.input_tokens_details?.cache_creation_tokens??e?.input_tokens_details?.cache_write_tokens??e?.prompt_tokens_details?.cache_creation_tokens??e?.prompt_tokens_details?.cache_write_tokens??0}buildResponsesUsage(e){let t=e?.input_tokens??e?.prompt_tokens??0,o=e?.output_tokens??e?.completion_tokens??0,r=this.getCacheReadInputTokens(e),s=this.getCacheCreationInputTokens(e);return{input_tokens:t,output_tokens:o,total_tokens:e?.total_tokens??t+o,input_tokens_details:{cached_tokens:r,cache_creation_tokens:s},output_tokens_details:{reasoning_tokens:e?.output_tokens_details?.reasoning_tokens??0},cache_read_input_tokens:r,cache_creation_input_tokens:s}}async transformRequestIn(e){delete e.temperature,delete e.max_tokens,e.reasoning&&(e.reasoning={effort:e.reasoning.effort,summary:e.reasoning.summary||"auto"});let t=[],o=e.messages.filter(r=>r.role==="system");if(o.length>0){let r=o[0];Array.isArray(r.content)?r.content.forEach(s=>{let i="";typeof s=="string"?i=s:s&&typeof s=="object"&&"text"in s&&(i=s.text),t.push({role:"system",content:i})}):e.instructions=r.content}if(e.messages.forEach(r=>{if(r.role!=="system"){if(Array.isArray(r.content)){let s=r.content.map(i=>this.normalizeRequestContent(i,r.role)).filter(i=>i!==null);s.length>0?r.content=s:delete r.content}if(r.role==="tool"){let s={...r};s.type="function_call_output",s.call_id=r.tool_call_id,s.output=r.content,delete s.cache_control,delete s.role,delete s.tool_call_id,delete s.content,t.push(s);return}if(r.role==="assistant"&&Array.isArray(r.tool_calls)){r.tool_calls.forEach(s=>{t.push({type:"function_call",arguments:s.function.arguments,name:s.function.name,call_id:s.id})});return}t.push(r)}}),e.input=t,delete e.messages,Array.isArray(e.tools)){let r=e.tools.find(s=>s.function.name==="web_search");e.tools=e.tools.filter(s=>s.function.name!=="web_search").map(s=>(s.function.name==="WebSearch"&&delete s.function.parameters.properties.allowed_domains,s.function.name==="Edit"?{type:s.type,name:s.function.name,description:s.function.description,parameters:{...s.function.parameters,required:["file_path","old_string","new_string","replace_all"]},strict:!0}:{type:s.type,name:s.function.name,description:s.function.description,parameters:s.function.parameters})),r&&e.tools.push({type:"web_search"})}return e.parallel_tool_calls=!1,e}async transformResponseOut(e){let t=e.headers.get("Content-Type")||"";if(t.includes("application/json")){let o=await pe(e);if(o?.isSSE&&o.body){let r=new Response(o.body,{status:e.status,statusText:e.statusText,headers:new Headers({...Object.fromEntries(e.headers.entries()),"content-type":"text/event-stream"})});return this.transformResponseOut(r)}if(o?.body)e=new Response(o.body,{status:e.status,statusText:e.statusText,headers:e.headers});else if(o===null){let r=await fe(e);if(r.isSSE)return this.transformResponseOut(r.response);e=r.response}}if(t.includes("application/json")){let o=await F(e);if(o.object==="response"&&o.output){let r=this.convertResponseToChat(o);return new Response(JSON.stringify(r),{status:e.status,statusText:e.statusText,headers:e.headers})}return o.type==="message"&&Array.isArray(o.content)?new Response(JSON.stringify(o),{status:e.status,statusText:e.statusText,headers:e.headers}):new Response(JSON.stringify(o),{status:e.status,statusText:e.statusText,headers:e.headers})}else if(t.includes("text/event-stream")){if(!e.body)return e;let[o,r]=e.body.tee(),s=o.getReader(),i="";try{let{value:f,done:_}=await s.read();!_&&f&&(i=new TextDecoder().decode(f))}finally{s.releaseLock()}if(o.cancel().catch(()=>{}),i.includes("message_start")||i.includes("content_block_start")){let f=this.prependToStream(i,r);return new Response(f,{status:e.status,statusText:e.statusText,headers:e.headers})}if(i.includes("response.created")||i.includes("response.output_text.delta")||i.includes("response.in_progress")||i.includes("response.output_item.added")){let f=this.prependToStream(i,r);return new Response(f,{status:e.status,statusText:e.statusText,headers:e.headers})}let c=this.prependToStream(i,r),u=new TextDecoder,d=new TextEncoder,p="",m=!1,h=this,g=new ReadableStream({async start(f){let _=c.getReader(),k=-1,y="",b=T=>(T!==y&&(k++,y=T),k);try{for(;;){let{done:T,value:C}=await _.read();if(T){m||f.enqueue(d.encode(`data: [DONE]
4
+ `);i=c.pop()||"";for(let u of c)u.trim()&&(s<o.maxStreamChunks?Xr(e,t,s,u):s===o.maxStreamChunks&&e.info({debug_log:!0,reqId:t,phase:"provider_stream_chunk_omitted",message:`[chunks after #${s} omitted, maxStreamChunks=${o.maxStreamChunks}]`}),s++)}i.trim()&&(s<o.maxStreamChunks&&Xr(e,t,s,i.trim()),s++),Zr(e,t,s)}catch(i){console.error(`[debug_log] Error reading debug stream for reqId=${t}:`,i),Zr(e,t,s)}finally{r.releaseLock()}})()}var mc,we,so,Ze=E(()=>{"use strict";mc=new Set(["authorization","x-api-key","x-goog-api-key","cookie","set-cookie"]),we={maxBodyLength:4096,maxStreamChunks:100},so=!1});function os(n,e,t,o,r){let s=new Headers({"Content-Type":"application/json"});t.headers&&Object.entries(t.headers).forEach(([c,u])=>{u&&s.set(c,u)});let i,a=AbortSignal.timeout(t.TIMEOUT??60*1e3*60);if(t.signal){let c=new AbortController,u=()=>c.abort();t.signal.addEventListener("abort",u),a.addEventListener("abort",u),i=c.signal}else i=a;let l={method:"POST",headers:s,body:JSON.stringify(e),signal:i};return t.httpsProxy&&(l.dispatcher=G(t.httpsProxy)),r?.debug({reqId:o.req.id,method:"POST",headers:Ot(Object.fromEntries(s.entries())),requestUrl:typeof n=="string"?n:n.toString(),useProxy:hc(t.httpsProxy)},"final request"),fetch(typeof n=="string"?n:n.toString(),l)}function hc(n){if(!(typeof n!="string"||!n.trim()))try{let e=new URL(n);return e.username||e.password?(e.username="",e.password="",`${e.toString()} (credentials redacted)`):e.toString()}catch{return"[invalid proxy URL]"}}var rs=E(()=>{oe();Ze()});var It,ao=E(()=>{It="2.3.2413"});var ss={};no(ss,{getFallbackPromotionStore:()=>Ee,resetFallbackPromotionStore:()=>kc});function Ee(n){return ve||(ve=new co,n&&ve.configure(n)),ve}function kc(){ve&&(ve.clearAll(),ve=null)}var _c,co,ve,Mt=E(()=>{"use strict";re();_c=600*1e3,co=class{promotions=new Map;enabled=!0;ttlMs=_c;configure(e){e?.enabled!==void 0&&(this.enabled=e.enabled),e?.ttlMinutes!==void 0&&(this.ttlMs=e.ttlMinutes*60*1e3)}getKey(e,t,o){return`${e},${t}:${o}`}promote(e,t,o,r,s,i){if(!this.enabled)return;let a=this.getKey(e,t,o),l=`${r},${s}`;this.promotions.set(a,{promotedModel:l,timestamp:Date.now(),ttlMs:i??this.ttlMs})}getPromotion(e,t,o,r){if(!this.enabled)return null;let s=this.getKey(e,t,o),i=this.promotions.get(s);if(!i)return null;if(Date.now()-i.timestamp>=i.ttlMs)return this.promotions.delete(s),null;let[l,...c]=i.promotedModel.split(","),u=c.join(",");if(!U().isAvailable(l,u))return this.promotions.delete(s),null;let p=r.find(h=>h.name.toLowerCase()===l.toLowerCase()),m=p?.models?.find(h=>String(h).toLowerCase()===u.toLowerCase());return!p||!m||p.enabled===!1?(this.promotions.delete(s),null):`${p.name},${m}`}clear(e,t,o){let r=this.getKey(e,t,o);this.promotions.delete(r)}clearByPrimary(e,t){let o=`${e},${t}:`,r=0;for(let s of this.promotions.keys())s.startsWith(o)&&(this.promotions.delete(s),r++);return r}clearAll(){this.promotions.clear()}clearExpired(){let e=Date.now();for(let[t,o]of this.promotions)e-o.timestamp>=o.ttlMs&&this.promotions.delete(t)}getAllPromotions(){let e=Date.now(),t=[];for(let[o,r]of this.promotions){let s=r.ttlMs-(e-r.timestamp);s>0&&t.push({key:o,promotedModel:r.promotedModel,remainingMs:s})}return t}},ve=null});import{existsSync as cs,mkdirSync as bc,readFileSync as Tc,writeFileSync as vc}from"fs";import{join as ls}from"path";import{HOME_DIR as xc}from"@wengine-ai/claude-code-router-shared";function wc(n){try{if(!cs(po))return;let e=JSON.parse(Tc(po,"utf-8"));if(!Array.isArray(e))return;let t=Date.now();for(let o of e){if(!o||!o.provider||!o.model)continue;let r=o.updatedAt||o.lastFailureTime||0;r&&t-r>1440*60*1e3||n.restore({provider:o.provider,model:o.model,status:o.status,failureCount:o.failureCount??0,successCount:o.successCount??0,lastFailureTime:o.lastFailureTime??0,lastProbeTime:o.lastProbeTime??0,lastError:o.lastError,rateLimitUntil:o.rateLimitUntil})}}catch{}}function as(n){try{let e=n.getAllStates();if(e.length===0)return;cs(uo)||bc(uo,{recursive:!0});let t=e.map(o=>({...o,updatedAt:Date.now()}));vc(po,JSON.stringify(t,null,2),"utf-8")}catch{}}function fo(){if(is)return;is=!0;let n=U();wc(n),Rc=setInterval(()=>as(n),6e4),process.on("exit",()=>as(n))}function U(n){return lo||(lo=new Nt(n)),lo}var Cc,Sc,Nt,uo,po,is,Rc,lo,re=E(()=>{"use strict";Cc=120,Sc={enabled:!0,failureThreshold:3,probeIntervalMinutes:5,halfOpenSuccessThreshold:2},Nt=class{states=new Map;config;probeTimer;constructor(e){this.config={...Sc,...e}}getKey(e,t){return!e||!t?null:`${e},${t}`}recordSuccess(e,t){if(!this.config.enabled)return;let o=this.getKey(e,t);if(!o)return;let r=this.states.get(o);r&&(r.successCount++,!r.rateLimitUntil&&(r.status==="half-open"?r.successCount>=this.config.halfOpenSuccessThreshold&&(this.clearPromotionsForPrimary(e,t),this.states.delete(o)):r.status==="open"&&(r.status="half-open",r.successCount=1,r.failureCount=0)))}clearPromotionsForPrimary(e,t){try{let{getFallbackPromotionStore:o}=(Mt(),ic(ss));o().clearByPrimary(e,t)}catch{}}recordFailure(e,t,o){if(!this.config.enabled)return;let r=this.getKey(e,t);if(!r)return;let s=this.states.get(r);s||(s={provider:e,model:t,status:"closed",failureCount:0,successCount:0,lastFailureTime:0,lastProbeTime:0},this.states.set(r,s)),s.failureCount++,s.lastFailureTime=Date.now(),s.lastError=o,s.status==="half-open"?(s.status="open",s.successCount=0,s.lastProbeTime=0):s.status==="closed"&&s.failureCount>=this.config.failureThreshold&&(s.status="open",s.lastProbeTime=0)}getState(e,t){let o=this.getKey(e,t);if(o)return this.states.get(o)}isAvailable(e,t){if(!this.config.enabled)return!0;if(!this.getKey(e,t))return!1;let r=this.getState(e,t);return r?r.status==="open"&&r.rateLimitUntil?!(Date.now()<r.rateLimitUntil):r.status!=="open":!0}getPriority(e,t){if(!this.config.enabled)return 0;if(!this.getKey(e,t))return 2;let r=this.getState(e,t);if(!r)return 0;switch(r.status){case"closed":return 0;case"half-open":return 1;case"open":return 2}}getHealthyModels(){return[]}getFailPoolModels(){let e=[];for(let[t,o]of this.states)o.status==="open"&&e.push(t);return e}getHalfOpenModels(){let e=[];for(let[t,o]of this.states)o.status==="half-open"&&e.push(t);return e}forceOpen(e,t,o){if(!this.config.enabled)return;let r=this.getKey(e,t);if(!r)return;let s=this.states.get(r);s?(s.status="open",s.failureCount=Math.max(s.failureCount,this.config.failureThreshold),s.lastFailureTime=Date.now(),s.lastError=o,s.lastProbeTime=0):(s={provider:e,model:t,status:"open",failureCount:this.config.failureThreshold,successCount:0,lastFailureTime:Date.now(),lastProbeTime:0,lastError:o},this.states.set(r,s))}markRateLimited(e,t,o,r){if(!this.config.enabled)return;let s=this.getKey(e,t);if(!s)return;let i=this.states.get(s);i?(i.status="open",i.lastFailureTime=Date.now(),i.lastError=r||"rate-limited",i.lastProbeTime=0):(i={provider:e,model:t,status:"open",failureCount:0,successCount:0,lastFailureTime:Date.now(),lastProbeTime:0,lastError:r||"rate-limited"},this.states.set(s,i));let a=(o??Cc)*1e3;i.rateLimitUntil=Date.now()+a}getRateLimitedModels(){let e=[];for(let[t,o]of this.states)o.status==="open"&&o.rateLimitUntil&&e.push(t);return e}needsProbe(e){return Date.now()-e.lastProbeTime>=this.config.probeIntervalMinutes*60*1e3}markProbeAttempt(e,t){let o=this.getKey(e,t);if(!o)return;let r=this.states.get(o);r&&r.status==="open"&&(r.lastProbeTime=Date.now())}clear(){this.states.clear()}recover(e,t){let o=this.getKey(e,t);o&&this.states.delete(o)}getAllStates(){return Array.from(this.states.values())}restore(e){let t=this.getKey(e.provider,e.model);t&&this.states.set(t,{...e})}stopProbeTimer(){this.probeTimer&&(clearInterval(this.probeTimer),this.probeTimer=void 0)}},uo=ls(xc,"runtime"),po=ls(uo,"provider-health.json"),is=!1,Rc=null;lo=null});import{existsSync as ms,mkdirSync as Ec,readFileSync as Pc,writeFileSync as Oc}from"fs";import{join as gs}from"path";import{HOME_DIR as Ac}from"@wengine-ai/claude-code-router-shared";function qe(n,e,t){let o=a=>{if(t instanceof Headers)return t.get(a);let l=Object.keys(t).find(c=>c.toLowerCase()===a);return l?t[l]:null},r=mo(o,Ic),s=mo(o,Mc),i=mo(o,Nc);(r||s||i)&&Pe.set(n,{provider:n,remaining:ps(r),limit:ps(s),reset:Lc(i),capturedAt:Date.now()})}function $c(n){return Pe.get(n)}function yo(){return Array.from(Pe.values())}function mo(n,e){for(let t of e){let o=n(t);if(o)return o}return null}function ps(n){if(!n)return null;let e=Number(n.trim().replace(/,/g,""));return Number.isFinite(e)?e:null}function Lc(n){if(!n)return null;let e=n.trim();if(!e)return null;let t=Number(e);if(Number.isFinite(t))return t>1e12?Math.floor(t/1e3):t>1e9?Math.floor(t):Math.floor(Date.now()/1e3+t);let o=Date.parse(e);if(Number.isFinite(o))return Math.floor(o/1e3);let r=Dc(e);return r===null?null:Math.floor((Date.now()+r)/1e3)}function Dc(n){let e=/(\d+(?:\.\d+)?)(ms|s|m|h|d)/gi,t=0,o=!1;for(let r of n.matchAll(e)){o=!0;let s=Number(r[1]),i=r[2].toLowerCase();if(Number.isFinite(s))switch(i){case"ms":t+=s;break;case"s":t+=s*1e3;break;case"m":t+=s*60*1e3;break;case"h":t+=s*60*60*1e3;break;case"d":t+=s*24*60*60*1e3;break}}return o?t:null}function Fc(){try{if(!ms(ho))return;let n=JSON.parse(Pc(ho,"utf-8"));if(!Array.isArray(n))return;let e=Date.now();for(let t of n)if(t&&t.provider){if(t.capturedAt&&e-t.capturedAt>3600*1e3)continue;Pe.set(t.provider,t)}}catch{}}function fs(){try{if(Pe.size===0)return;ms(go)||Ec(go,{recursive:!0}),Oc(ho,JSON.stringify(Array.from(Pe.values()),null,2),"utf-8")}catch{}}function et(){us||(us=!0,Fc(),ds=setInterval(fs,6e4),ds.unref?.(),process.on("exit",fs))}var go,ho,Pe,us,ds,Ic,Mc,Nc,Oe=E(()=>{"use strict";go=gs(Ac,"runtime"),ho=gs(go,"rate-limit.json"),Pe=new Map,us=!1,ds=null,Ic=["x-ratelimit-remaining-tokens","x-ratelimit-remaining-requests","x-ratelimit-remaining"],Mc=["x-ratelimit-limit-tokens","x-ratelimit-limit-requests","x-ratelimit-limit"],Nc=["x-ratelimit-reset-tokens","x-ratelimit-reset-requests","x-ratelimit-reset"]});function Lt(){return _o||(_o=new bo),_o}function vo(){return ko||(ko=new To),ko}function Uc(n){return n?.sessionId||n?.clientContext?.stableSessionId||void 0}function hs(n){let e=Uc(n);if(!e)return"";let t=typeof n?.modelFamily=="string"?n.modelFamily:"",o=typeof n?.scenarioType=="string"&&n.scenarioType?n.scenarioType:"default";return`${e}:${t}:${o}`}function ys(n,e){let t=Lt(),o=n?.[$t];if(o&&!o.released){if(o.key===e)return;t.release(o)}n[$t]=t.acquire(e)}function xo(n){let e=n?.[$t];e&&Lt().release(e)}function _s(n,e){let t=hs(n),o=n?.[$t],r=t?vo().get(t)!==void 0:!1;!o&&!r||(t&&vo().bind(t,e),ys(n,e))}function jc(n,e,t){let o=Lt(),r=null,s=1/0;for(let i of e){if(!i||typeof i!="string")continue;let a=t(i);if(!a||a===n)continue;let l=o.count(a);l<s&&(r=a,s=l)}return r}function ks(n,e,t){let o=hs(n),r=vo(),s=Lt(),i=Number.isFinite(t.threshold)&&t.threshold>0?Math.floor(t.threshold):3,a;if(o){let l=r.get(o);if(l&&l!==e){let c=t.resolve(l);c?(a=c,t.log?.(`Concurrency priority: session slot ${o} sticking to bound model ${c}`)):r.unbind(o)}else l&&(a=e)}if(!a){let l=s.count(e);if(l>=i){let c=jc(e,t.fallbackModels,t.resolve);c&&(a=c,t.log?.(`Concurrency priority: model ${e} has ${l} in-flight request(s) (>= ${i}); assigning ${o?`session slot ${o} `:"request "}to overflow model ${c}`))}a=a||e,o&&r.bind(o,a)}return ys(n,a),a}var bo,To,_o,ko,$t,Dt=E(()=>{"use strict";bo=class{leases=new Map;nextId=1;acquire(e){let t={id:this.nextId++,key:e,createdAt:Date.now(),released:!1};return this.leases.set(t.id,t),t}release(e){!e||e.released||(e.released=!0,this.leases.delete(e.id))}prune(){let e=Date.now();for(let[t,o]of this.leases)e-o.createdAt>18e5&&this.leases.delete(t)}count(e){this.prune();let t=0;for(let o of this.leases.values())o.key===e&&t++;return t}clear(){this.leases.clear()}},To=class{bindings=new Map;get(e){let t=this.bindings.get(e);if(t){if(Date.now()-t.updatedAt>864e5){this.bindings.delete(e);return}return t.updatedAt=Date.now(),this.bindings.delete(e),this.bindings.set(e,t),t.modelKey}}bind(e,t){for(this.bindings.delete(e),this.bindings.set(e,{modelKey:t,updatedAt:Date.now()});this.bindings.size>2e3;){let o=this.bindings.keys().next().value;if(o===void 0)break;this.bindings.delete(o)}}unbind(e){this.bindings.delete(e)}clear(){this.bindings.clear()}},_o=null,ko=null;$t="__concurrencyLease"});async function F(n){let e=await n.text();return Hc(e,n.status)}function Hc(n,e){let t=n.replace(/^/,"").trim();try{return JSON.parse(t)}catch{let o=t.length>200?`${t.slice(0,200)}...`:t,r=e!==void 0?` (HTTP ${e})`:"";throw new Error(`Upstream returned a non-JSON response${r}: ${o||"(empty body)"}`)}}function bs(n){return(n.headers.get("Content-Type")||"").includes("text/event-stream")}function tt(n){return/^\s*(event:|data:|:\s*[A-Z])/m.test(n)||n.startsWith("data:")}async function pe(n){if(!n.body||n.body.locked)return null;let[e,t]=n.body.tee(),o=e.getReader(),r=new TextDecoder,s="";try{for(let i=0;i<8;i++){let{value:a,done:l}=await o.read();if(l||(a&&(s+=r.decode(a,{stream:!0})),tt(s))||/^\s*[\[{]/.test(s))break}s+=r.decode()}finally{o.releaseLock()}return e.cancel().catch(()=>{}),{body:t,isSSE:tt(s)}}async function fe(n){try{let e=await n.text();if(tt(e)){let o=new TextEncoder,r=new ReadableStream({start(s){s.enqueue(o.encode(e)),s.close()}});return{response:new Response(r,{status:n.status,statusText:n.statusText,headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}}),isSSE:!0}}return{response:new Response(e,{status:n.status,statusText:n.statusText,headers:n.headers}),isSSE:!1}}catch{return{response:n,isSSE:!1}}}var V=E(()=>{"use strict"});var Ae,Co=E(()=>{"use strict";V();Ae=class{name="openai-responses";endPoint="/v1/responses";getCacheReadInputTokens(e){return e?.cache_read_input_tokens??e?.input_tokens_details?.cached_tokens??e?.prompt_tokens_details?.cached_tokens??0}getCacheCreationInputTokens(e){return e?.cache_creation_input_tokens??e?.input_tokens_details?.cache_creation_tokens??e?.input_tokens_details?.cache_write_tokens??e?.prompt_tokens_details?.cache_creation_tokens??e?.prompt_tokens_details?.cache_write_tokens??0}buildResponsesUsage(e){let t=e?.input_tokens??e?.prompt_tokens??0,o=e?.output_tokens??e?.completion_tokens??0,r=this.getCacheReadInputTokens(e),s=this.getCacheCreationInputTokens(e);return{input_tokens:t,output_tokens:o,total_tokens:e?.total_tokens??t+o,input_tokens_details:{cached_tokens:r,cache_creation_tokens:s},output_tokens_details:{reasoning_tokens:e?.output_tokens_details?.reasoning_tokens??0},cache_read_input_tokens:r,cache_creation_input_tokens:s}}async transformRequestIn(e){delete e.temperature,delete e.max_tokens,e.reasoning&&(e.reasoning={effort:e.reasoning.effort,summary:e.reasoning.summary||"auto"});let t=[],o=e.messages.filter(r=>r.role==="system");if(o.length>0){let r=o[0];Array.isArray(r.content)?r.content.forEach(s=>{let i="";typeof s=="string"?i=s:s&&typeof s=="object"&&"text"in s&&(i=s.text),t.push({role:"system",content:i})}):e.instructions=r.content}if(e.messages.forEach(r=>{if(r.role!=="system"){if(Array.isArray(r.content)){let s=r.content.map(i=>this.normalizeRequestContent(i,r.role)).filter(i=>i!==null);s.length>0?r.content=s:delete r.content}if(r.role==="tool"){let s={...r};s.type="function_call_output",s.call_id=r.tool_call_id,s.output=r.content,delete s.cache_control,delete s.role,delete s.tool_call_id,delete s.content,t.push(s);return}if(r.role==="assistant"&&Array.isArray(r.tool_calls)){r.tool_calls.forEach(s=>{t.push({type:"function_call",arguments:s.function.arguments,name:s.function.name,call_id:s.id})});return}t.push(r)}}),e.input=t,delete e.messages,Array.isArray(e.tools)){let r=e.tools.find(s=>s.function.name==="web_search");e.tools=e.tools.filter(s=>s.function.name!=="web_search").map(s=>(s.function.name==="WebSearch"&&delete s.function.parameters.properties.allowed_domains,s.function.name==="Edit"?{type:s.type,name:s.function.name,description:s.function.description,parameters:{...s.function.parameters,required:["file_path","old_string","new_string","replace_all"]},strict:!0}:{type:s.type,name:s.function.name,description:s.function.description,parameters:s.function.parameters})),r&&e.tools.push({type:"web_search"})}return e.parallel_tool_calls=!1,e}async transformResponseOut(e){let t=e.headers.get("Content-Type")||"";if(t.includes("application/json")){let o=await pe(e);if(o?.isSSE&&o.body){let r=new Response(o.body,{status:e.status,statusText:e.statusText,headers:new Headers({...Object.fromEntries(e.headers.entries()),"content-type":"text/event-stream"})});return this.transformResponseOut(r)}if(o?.body)e=new Response(o.body,{status:e.status,statusText:e.statusText,headers:e.headers});else if(o===null){let r=await fe(e);if(r.isSSE)return this.transformResponseOut(r.response);e=r.response}}if(t.includes("application/json")){let o=await F(e);if(o.object==="response"&&o.output){let r=this.convertResponseToChat(o);return new Response(JSON.stringify(r),{status:e.status,statusText:e.statusText,headers:e.headers})}return o.type==="message"&&Array.isArray(o.content)?new Response(JSON.stringify(o),{status:e.status,statusText:e.statusText,headers:e.headers}):new Response(JSON.stringify(o),{status:e.status,statusText:e.statusText,headers:e.headers})}else if(t.includes("text/event-stream")){if(!e.body)return e;let[o,r]=e.body.tee(),s=o.getReader(),i="";try{let{value:f,done:_}=await s.read();!_&&f&&(i=new TextDecoder().decode(f))}finally{s.releaseLock()}if(o.cancel().catch(()=>{}),i.includes("message_start")||i.includes("content_block_start")){let f=this.prependToStream(i,r);return new Response(f,{status:e.status,statusText:e.statusText,headers:e.headers})}if(i.includes("response.created")||i.includes("response.output_text.delta")||i.includes("response.in_progress")||i.includes("response.output_item.added")){let f=this.prependToStream(i,r);return new Response(f,{status:e.status,statusText:e.statusText,headers:e.headers})}let c=this.prependToStream(i,r),u=new TextDecoder,d=new TextEncoder,p="",m=!1,h=this,g=new ReadableStream({async start(f){let _=c.getReader(),k=-1,y="",b=T=>(T!==y&&(k++,y=T),k);try{for(;;){let{done:T,value:C}=await _.read();if(T){m||f.enqueue(d.encode(`data: [DONE]
5
5
 
6
6
  `));break}let v=u.decode(C,{stream:!0});p+=v;let S=p.split(/\r?\n/);p=S.pop()||"";for(let x of S)if(x.trim())try{if(x.startsWith("event: "))continue;if(x.startsWith("data: ")){let w=x.slice(5).trim();if(w==="[DONE]"){m=!0,f.enqueue(d.encode(`data: [DONE]
7
7
 
@@ -313,7 +313,7 @@ Stack: ${e.stack}`)}}async registerDefaultTransformersInternal(){try{Object.valu
313
313
  ${this.toMarkdown(r,t+1)}`:`${o}- ${r}`).join(`
314
314
  `):typeof e=="object"&&e!==null?Object.entries(e).map(([r,s])=>typeof s=="object"&&s!==null?`${o}${r}:
315
315
  ${this.toMarkdown(s,t+1)}`:`${o}${r}: ${s}`).join(`
316
- `):`${o}${e}`}async output(e,t={}){try{let o=this.formatData(e,t);switch(this.config.level||"log"){case"info":console.info(o);break;case"warn":console.warn(o);break;case"error":console.error(o);break;case"debug":console.debug(o);break;case"log":default:console.log(o);break}return!0}catch(o){return console.error("[ConsoleOutputHandler] Output failed:",o),!1}}}});var pt,ur=E(()=>{"use strict";pt=class{type="webhook";config;defaultTimeout=3e4;constructor(e){if(!e.url)throw new Error("Webhook URL is required");this.config={method:"POST",retry:{maxAttempts:3,backoffMs:1e3},silent:!1,...e}}buildHeaders(){let e={"Content-Type":"application/json",...this.config.headers||{}};if(this.config.auth)switch(this.config.auth.type){case"bearer":this.config.auth.token&&(e.Authorization=`Bearer ${this.config.auth.token}`);break;case"basic":if(this.config.auth.username&&this.config.auth.password){let t=Buffer.from(`${this.config.auth.username}:${this.config.auth.password}`).toString("base64");e.Authorization=`Basic ${t}`}break;case"custom":this.config.auth.custom&&(e[this.config.auth.custom.header]=this.config.auth.custom.value);break}return e}buildBody(e,t){let{format:o="json",timestamp:r=!0,prefix:s,metadata:i}=t||{},a={data:e};return r&&(a.timestamp=new Date().toISOString()),s&&(a.prefix=s),i&&Object.keys(i).length>0&&(a.metadata=i),a}async sendRequest(e,t,o,r,s){let i=new AbortController,a=setTimeout(()=>i.abort(),s);try{let l=await fetch(e,{method:t,headers:o,body:JSON.stringify(r),signal:i.signal});if(clearTimeout(a),!l.ok)throw new Error(`HTTP ${l.status}: ${l.statusText}`);return l}catch(l){throw clearTimeout(a),l}}delay(e){return new Promise(t=>setTimeout(t,e))}async sendWithRetry(e,t,o,r,s,i){let a=null;for(let l=1;l<=i.maxAttempts;l++)try{return await this.sendRequest(e,t,o,r,s)}catch(c){if(a=c,l===i.maxAttempts)break;let u=i.backoffMs*Math.pow(2,l-1);console.warn(`[WebhookOutputHandler] Request failed (attempt ${l}/${i.maxAttempts}), retrying in ${u}ms...`,c.message),await this.delay(u)}throw a}async output(e,t={}){let o=t.timeout||this.defaultTimeout;try{let r=this.buildHeaders(),s=this.buildBody(e,t),i=await this.sendWithRetry(this.config.url,this.config.method,r,s,o,this.config.retry);return!0}catch(r){let s=r instanceof Error?r.message:String(r);if(this.config.silent)return console.error(`[WebhookOutputHandler] Failed to send data: ${s}`),!1;throw new Error(`Webhook output failed: ${s}`)}}}});import{lstat as Mn,opendir as Ju,unlink as Wu}from"node:fs/promises";import{join as Zi,resolve as fr}from"node:path";import{tmpdir as Ku}from"node:os";async function Nn(n,e){let t=fr(n),o=In.get(t),r,s=new Promise(i=>{r=i});In.set(t,s);try{return await o,await e()}finally{r(),In.get(t)===s&&In.delete(t)}}function qi(n,e){return n.dev===e.dev&&n.ino===e.ino}async function Xi(n,e){try{let t=await Mn(n);return t.isDirectory()&&!t.isSymbolicLink()&&qi(e,t)}catch{return!1}}function Xu(){return new Promise(n=>{setTimeout(n,10).unref()})}async function ea(n,e,t,o){let r=fr(n);if(o?.aborted||dr.has(r))return 0;dr.add(r);let s=0;try{let i=await Mn(r);if(!i.isDirectory()||i.isSymbolicLink()||o?.aborted)return 0;let a=await Ju(r,{bufferSize:32});try{let l=0,c=!0;for await(let u of a){if(o?.aborted||!c)break;try{if(!u.isFile()||u.isSymbolicLink()||!t(u.name))continue;let d=Zi(r,u.name);try{let p=await Mn(d);if(!p.isFile()||p.isSymbolicLink()||p.mtimeMs>=e)continue;await Nn(d,async()=>{if(o?.aborted||!await Xi(r,i))return!1;let h=await Mn(d);return!h.isFile()||h.isSymbolicLink()||!qi(p,h)||h.mtimeMs!==p.mtimeMs||h.mtimeMs>=e||o?.aborted?!1:(await Wu(d),!0)})&&s++}catch{}}finally{++l%64===0&&(await Xu(),c=!o?.aborted&&await Xi(r,i))}}}finally{await a.close().catch(()=>{})}}catch{}finally{dr.delete(r)}return s}function ta(n,e,t,o,r){if(!Number.isFinite(o)||o<=0)return Promise.resolve(0);let s=`${e}-`,i=t?`.${t}`:"";return ea(n,Date.now()-o,a=>Yu.test(a)?!0:!a.endsWith(".tmp")&&a.startsWith(s)&&a.endsWith(i),r)}function Zu(n,e){let t=Date.now()-Gu;return ea(n,t,o=>{let r=Qu.exec(o);return r!==null&&Number(r[1])<t},e)}function mr(n,e,t){let o=pr.get(n);if(!o){let s=new AbortController,i,a=()=>{s.signal.aborted||Promise.resolve().then(()=>e(s.signal)).catch(()=>{})},l=setTimeout(()=>{s.signal.aborted||(a(),i=setInterval(a,Vu),i.unref())},t);l.unref(),o={users:0,stop:()=>{s.abort(),clearTimeout(l),i&&clearInterval(i)}},pr.set(n,o)}o.users++;let r=!1;return()=>{r||(r=!0,--o.users===0&&(o.stop(),pr.delete(n)))}}function na(n=Zi(Ku(),"claude-code-router")){return mr(`legacy:${fr(n)}`,e=>Zu(n,e),1e3)}var Gu,Vu,Qu,Yu,dr,In,pr,gr=E(()=>{"use strict";Gu=3600*1e3,Vu=600*1e3,Qu=/^session-[A-Za-z0-9_.-]+-(\d{13})\.json$/,Yu=/^\.ccr-tmp-[1-9]\d*-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\.tmp$/,dr=new Set,In=new Map,pr=new Map});import{lstat as qu,mkdir as ed,open as td,rename as nd,unlink as od}from"node:fs/promises";import{randomUUID as rd}from"node:crypto";import{sanitizeTempFileKey as sd}from"@wengine-ai/claude-code-router-shared";import{basename as id,join as hr,resolve as ad}from"node:path";import{tmpdir as cd}from"node:os";var ft,yr=E(()=>{"use strict";gr();ft=class{type="temp-file";config;baseDir;controller=new AbortController;stopSchedule;constructor(e={}){if(this.config={subdirectory:"claude-code-router",extension:"json",includeTimestamp:!1,prefix:"session",retentionMs:36e5,...e},this.baseDir=ad(hr(cd(),this.config.subdirectory)),Number.isFinite(this.config.retentionMs)&&this.config.retentionMs>0){let t=JSON.stringify([this.baseDir,this.config.prefix,this.config.extension,this.config.retentionMs]);this.stopSchedule=mr(`handler:${t}`,o=>this.pruneOldFiles(o),6e4)}}async ensureDir(){await ed(this.baseDir,{recursive:!0});let e=await qu(this.baseDir);if(!e.isDirectory()||e.isSymbolicLink())throw new Error("Unsafe temp output directory")}getFilePath(e){let t=this.config.prefix||"session",o=this.config.extension?`.${this.config.extension}`:"",r=this.config.includeTimestamp?`-${Date.now()}`:"",s=`${t}-${sd(e)}${r}${o}`;if(id(s)!==s||s.includes("\\"))throw new Error("Temp file configuration must not contain path separators");return hr(this.baseDir,s)}async output(e,t={}){try{let o=t.metadata?.sessionId;if(!o)return!1;let r=JSON.stringify({...e,timestamp:Date.now(),sessionId:o},null,2),s=this.getFilePath(o);return await Nn(s,async()=>{await this.ensureDir();let i=hr(this.baseDir,`.ccr-tmp-${process.pid}-${rd()}.tmp`);return Nn(i,async()=>{let a=!1;try{let l=await td(i,"wx");a=!0;try{await l.writeFile(r,"utf-8")}finally{await l.close()}return await nd(i,s),!0}finally{a&&await od(i).catch(()=>{})}})})}catch{return!1}}pruneOldFiles(e=this.controller.signal){return ta(this.baseDir,this.config.prefix||"session",this.config.extension||"",this.config.retentionMs,e)}dispose(){this.controller.abort(),this.stopSchedule?.()}getBaseDir(){return this.baseDir}}});var _r,Ge,oa=E(()=>{"use strict";lr();ur();yr();_r=class{handlers=new Map;defaultOptions={};registerHandler(e,t){this.handlers.set(e,t)}registerHandlers(e){for(let t of e)if(t.enabled!==!1)try{let o=this.createHandler(t),r=t.type+"_"+Date.now();this.registerHandler(r,o)}catch(o){console.error(`[OutputManager] Failed to register ${t.type} handler:`,o)}}createHandler(e){switch(e.type){case"console":return new dt(e.config);case"webhook":return new pt(e.config);case"temp-file":return new ft(e.config);default:throw new Error(`Unknown output handler type: ${e.type}`)}}unregisterHandler(e){return this.handlers.delete(e)}getHandler(e){return this.handlers.get(e)}getAllHandlers(){return new Map(this.handlers)}clearHandlers(){this.handlers.clear()}setDefaultOptions(e){this.defaultOptions={...this.defaultOptions,...e}}getDefaultOptions(){return{...this.defaultOptions}}async output(e,t){let o={...this.defaultOptions,...t},r={success:[],failed:[]},s=Array.from(this.handlers.entries()).map(async([i,a])=>{try{await a.output(e,o)?r.success.push(i):r.failed.push(i)}catch(l){console.error(`[OutputManager] Handler ${i} failed:`,l),r.failed.push(i)}});return await Promise.all(s),r}async outputTo(e,t,o){let r={...this.defaultOptions,...o},s={success:[],failed:[]},i=e.map(async a=>{let l=this.handlers.get(a);if(!l){console.warn(`[OutputManager] Handler ${a} not found`),s.failed.push(a);return}try{await l.output(t,r)?s.success.push(a):s.failed.push(a)}catch(c){console.error(`[OutputManager] Handler ${a} failed:`,c),s.failed.push(a)}});return await Promise.all(i),s}async outputToType(e,t,o){let r=Array.from(this.handlers.entries()).filter(([s,i])=>i.type===e).map(([s])=>s);return this.outputTo(r,t,o)}},Ge=new _r});var kr=E(()=>{"use strict";Yi();lr();ur();yr();oa()});import ld from"fastify-plugin";import{TOKEN_SPEED_TEMP_SUBDIRECTORY as ud}from"@wengine-ai/claude-code-router-shared";function $n(){return{subdirectory:ud,extension:"json",includeTimestamp:!1,prefix:"session"}}function ra(n,e,t=0){if(n<=0)return 0;let o=Math.max((e-t)/1e3,dd);return Math.round(n/o)}function gt(n){let e=(n.match(/[\u4e00-\u9fa5]/g)||[]).length,t=n.length-e;return Math.ceil(e/1.5+t/4)}async function sa(n,e,t,o=!1){let r=o?"[Token Speed Final]":"[Token Speed]",s={requestId:n.requestId.substring(0,8),sessionId:n.sessionId,stream:n.stream,tokenCount:n.tokenCount,tokensPerSecond:n.tokensPerSecond,timeToFirstToken:n.timeToFirstToken?`${n.timeToFirstToken}ms`:"N/A",duration:`${((n.lastTokenTime-n.startTime)/1e3).toFixed(2)}s`,timestamp:Date.now()},i={prefix:r,metadata:{sessionId:n.sessionId,statsKey:n.statsKey},...t};for(let a of e)try{await Ge.outputToType(a,s,i)}catch(l){console.error(`[TokenSpeedPlugin] Failed to output to ${a}:`,l)}}var mt,br,dd,Ln,ia=E(()=>{"use strict";cr();kr();Ne();mt=new Map,br=new Map,dd=1,Ln={name:"token-speed",version:"1.0.0",description:"Statistics for streaming response token generation speed",register:ld(async(n,e)=>{let t={reporter:["console","temp-file"],...e},o=Array.isArray(t.reporter)?t.reporter:[t.reporter];if(t.outputHandlers&&t.outputHandlers.length>0)Ge.registerHandlers(t.outputHandlers);else{let i=[];for(let a of o)a==="console"?i.push({type:"console",enabled:!0,config:{colors:!0,level:"log"}}):a==="temp-file"?i.push({type:"temp-file",enabled:!0,config:$n()}):a==="webhook"&&console.warn("[TokenSpeedPlugin] Webhook reporter requires explicit configuration in outputHandlers");i.length>0&&Ge.registerHandlers(i)}t.outputOptions&&Ge.setDefaultOptions(t.outputOptions);let r=async i=>{let a=n.tokenizerService;if(!a)return n.log?.warn("TokenizerService not available"),null;if(!i.provider||!i.model)return null;let l=i.provider,c=i.model,u=`${l}:${c}`;if(br.has(u))return br.get(u);let d=a.getTokenizerConfigForModel(l,c);if(!d)return n.log?.debug(`No tokenizer config for ${l}:${c}, using fallback`),null;try{let p=await a.getTokenizer(d,l);return br.set(u,p),n.log?.info(`Created tokenizer for ${l}:${c} - ${p.name}`),p}catch(p){return n.log?.warn(`Failed to create tokenizer for ${l}:${c}: ${p.message}`),null}},s=i=>{let a=new URL(`http://127.0.0.1${i}`).pathname;return a.endsWith("/v1/messages")||a.endsWith("/v1/responses")};n.addHook("onRequest",async i=>{s(i.url)&&(i.requestStartTime=performance.now())}),n.addHook("onSend",async(i,a,l)=>{let c=i.requestStartTime;if(!c)return;let u=i.id||Date.now().toString(),d=i.usageSessionId||u,p=i.sessionId;if(!p)try{p=ge(i.body?.metadata?.user_id)||d}catch{p=d}let m=await r(i);if(l instanceof ReadableStream){mt.set(u,{requestId:u,sessionId:p,statsKey:d,startTime:c,lastTokenTime:c,tokenCount:0,tokensPerSecond:0,stream:!0});let[_,k]=l.tee(),y=async()=>{let b=null,T=async C=>{let v=mt.get(u);if(!v)return;let S=v.firstTokenTime?v.firstTokenTime-v.startTime:0,w=(C?v.lastTokenTime:performance.now())-v.startTime;v.tokensPerSecond=ra(v.tokenCount,w,S),await sa(v,o,t.outputOptions,C).catch(R=>{n.log?.warn(`Failed to output streaming stats: ${R.message}`)})};try{let v=k.pipeThrough(new TextDecoderStream).pipeThrough(new ae).getReader();for(b=setInterval(async()=>{mt.get(u)&&await T(!1)},1e3);;){let{done:S,value:x}=await v.read();if(S)break;let w=x,R=mt.get(u);if(!R)continue;let O=performance.now(),P=w.event||w.data?.type,M=w.event==="content_block_start"||w.event==="content_block_delta"||w.event==="text_block"||w.event==="content_block"||P==="response.output_text.delta"||P==="response.function_call_arguments.delta"||P==="response.reasoning_summary_text.delta";!R.firstTokenTime&&M&&(R.firstTokenTime=O,R.timeToFirstToken=Math.round(O-R.startTime));let $="";if(w.event==="content_block_delta"&&w.data?.delta){let L=w.data.delta.type;L==="text_delta"?$=w.data.delta.text||"":L==="input_json_delta"?$=w.data.delta.partial_json||"":L==="thinking_delta"&&($=w.data.delta.thinking||"")}if((P==="response.output_text.delta"||P==="response.function_call_arguments.delta"||P==="response.reasoning_summary_text.delta")&&($=typeof w.data?.delta=="string"?w.data.delta:""),$){let L=m&&m.encodeText?m.encodeText($).length:gt($);R.tokenCount+=L,R.lastTokenTime=O}(w.event==="message_stop"||P==="response.completed"||P==="response.failed")&&(b&&(clearInterval(b),b=null),await T(!0),mt.delete(u))}}catch(C){b&&clearInterval(b),C.name!=="AbortError"&&C.code!=="ERR_STREAM_PREMATURE_CLOSE"&&n.log?.warn(`Error processing token stats: ${C.message}`)}};return i.tokenSpeedCapturePromise=y().catch(b=>{console.log(b),n.log?.warn(`Background stats processing failed: ${b.message}`)}),_}let h=performance.now(),g=0,f=!1;if(l&&typeof l=="string")try{let _=JSON.parse(l);if(typeof _.usage?.output_tokens=="number")g=_.usage.output_tokens,f=!0;else{let k=_.content??_.message?.content;if(k!==void 0)if(f=!0,m)Array.isArray(k)?g=k.reduce((y,b)=>{if(b.type==="text"){let T=b.text||"";return y+(m.encodeText?m.encodeText(T).length:gt(T))}return y},0):typeof k=="string"&&(g=m.encodeText?m.encodeText(k).length:gt(k));else{let y=Array.isArray(k)?k.map(b=>b.text).join(""):typeof k=="string"?k:"";g=gt(y)}}}catch{}if(f){let _=h-c,k={requestId:u,sessionId:p,statsKey:d,startTime:c,lastTokenTime:h,tokenCount:g,tokensPerSecond:ra(g,_),stream:!1};await sa(k,o,t.outputOptions,!0)}return l})})}});var Tr=E(()=>{"use strict";Vi();Qi();ia();kr()});import ee from"node:fs/promises";import aa from"json5";import Se from"node:path";import{CONFIG_FILE as te,HOME_DIR as Dn,PLUGINS_DIR as pd}from"@wengine-ai/claude-code-router-shared";function ca(){if(process.env.VITEST||process.env.CI)throw new Error("Config write attempted during test/CI. Set CCR_CONFIG_DIR to a temp dir to isolate.")}var vr,ht,Fn,xr,ne,Un,_e,fd,Cr,jn=E(()=>{"use strict";vr=n=>{if(typeof n=="string")return n.replace(/\$\{([^}]+)\}|\$([A-Z_][A-Z0-9_]*)/g,(e,t,o)=>{let r=t||o;return process.env[r]||e});if(Array.isArray(n))return n.map(vr);if(n!==null&&typeof n=="object"){let e={};for(let[t,o]of Object.entries(n))e[t]=vr(o);return e}return n},ht=async n=>{try{await ee.access(n)}catch{await ee.mkdir(n,{recursive:!0})}},Fn=async()=>{await ht(Dn),await ht(pd),await ht(Se.join(Dn,"logs"))},xr=async()=>{let n=await ee.readFile(te,"utf-8");return aa.parse(n)},ne=async()=>{try{let n=await ee.readFile(te,"utf-8");try{let e=aa.parse(n);return vr(e)}catch(e){console.error(`Failed to parse config file at ${te}`),console.error("Error details:",e.message),console.error("Please check your config file syntax."),process.exit(1)}}catch(n){if(n.code==="ENOENT")try{await Fn();let e=await Un();e&&console.log(`Backed up existing configuration file to ${e}`);let t={PORT:3456,Providers:[],Router:{}};return await _e(t),console.log("Created minimal default configuration file at ~/.claude-code-router/config.json"),console.log("Please edit this file with your actual configuration."),t}catch(e){console.error("Failed to create default configuration:",e.message),process.exit(1)}else console.error(`Failed to read config file at ${te}`),console.error("Error details:",n.message),process.exit(1)}};Un=async()=>{ca();try{if(await ee.access(te).then(()=>!0).catch(()=>!1)){let n=new Date().toISOString().replace(/[:.]/g,"-"),e=`${te}.${n}.bak`;await ee.copyFile(te,e);try{let t=Se.dirname(te),o=Se.basename(te),s=(await ee.readdir(t)).filter(i=>i.startsWith(o)&&i.endsWith(".bak")).sort().reverse();if(s.length>3)for(let i=3;i<s.length;i++){let a=Se.join(t,s[i]);await ee.unlink(a)}}catch(t){console.warn("Failed to clean up old backups:",t)}return e}}catch(n){console.error("Failed to backup config file:",n)}return null},_e=async n=>{ca(),await ht(Dn),await fd();let e=`${JSON.stringify(n,null,2)}`;await ee.writeFile(te,e)},fd=async()=>{if(!await ee.access(te).then(()=>!0).catch(()=>!1))return;let e=Se.join(Dn,"config-history");await ht(e);let t=new Date().toISOString().replace(/[:.]/g,"-"),o=Se.join(e,`config-${t}.json`);await ee.copyFile(te,o);try{let s=(await ee.readdir(e)).filter(i=>i.startsWith("config-")&&i.endsWith(".json")).sort().reverse();if(s.length>50)for(let i of s.slice(50))await ee.unlink(Se.join(e,i))}catch(r){console.warn("Failed to prune config-history:",r)}},Cr=async()=>{let n=await ne();return Object.assign(process.env,n),n}});function md(n){return n?.cache_read_input_tokens??n?.input_tokens_details?.cached_tokens??n?.prompt_tokens_details?.cached_tokens??0}function gd(n){return n?.cache_creation_input_tokens??n?.input_tokens_details?.cache_creation_tokens??n?.input_tokens_details?.cache_write_tokens??n?.prompt_tokens_details?.cache_creation_tokens??n?.prompt_tokens_details?.cache_write_tokens??0}function Ve(n){if(!(!n||typeof n!="object"))return{...n,input_tokens:n.input_tokens??n.prompt_tokens??0,output_tokens:n.output_tokens??n.completion_tokens??0,cache_read_input_tokens:md(n),cache_creation_input_tokens:gd(n)}}function Hn(n,e,t){let o=t?{}:n||{},r=e||{};return{...o,input_tokens:r.input_tokens||o.input_tokens||0,output_tokens:r.output_tokens||o.output_tokens||0,cache_read_input_tokens:r.cache_read_input_tokens||o.cache_read_input_tokens||0,cache_creation_input_tokens:r.cache_creation_input_tokens||o.cache_creation_input_tokens||0}}var Sr=E(()=>{"use strict"});function zn(n,e,t){if(n){if(typeof n=="string"){let o=n.indexOf(",");if(o>0){let r=n.slice(0,o).trim(),s=n.slice(o+1).trim();r&&s&&e.has(r)&&t.add(Rr(r,s))}return}if(Array.isArray(n)){for(let o of n)zn(o,e,t);return}if(typeof n=="object")for(let o of Object.values(n))zn(o,e,t)}}function la(n){let e=n?.Providers||n?.providers||[],t=new Set,o=new Set;for(let r of e){let s=r?.name;if(!s)continue;t.add(s);let i=Array.isArray(r?.models)?r.models:[];for(let a of i)a&&o.add(Rr(s,a))}return zn(n?.Router,t,o),zn(n?.fallback,t,o),o}function yt(n,e){try{let t=U();if(!t?.getAllStates||!t?.recover)return 0;let o=la(n),r=0;for(let s of t.getAllStates()||[]){let i=s?.provider,a=s?.model;!i||!a||o.has(Rr(i,a))||(t.recover(i,a),r++)}return r>0&&e?.info?.(`[health-reconcile] Pruned ${r} orphaned provider-health entr${r===1?"y":"ies"}`),r}catch(t){return e?.warn?.(`[health-reconcile] Failed to reconcile health store: ${t?.message||t}`),0}}function Bn(n,e){try{if(!n)return 0;let t=U();if(!t?.getAllStates||!t?.recover)return 0;let o=0;for(let r of t.getAllStates()||[])r?.provider===n&&r?.model&&(t.recover(n,r.model),o++);return o>0&&e?.info?.(`[health-reconcile] Cleared ${o} health entr${o===1?"y":"ies"} for probed provider ${n}`),o}catch(t){return e?.warn?.(`[health-reconcile] Failed to clear provider health for ${n}: ${t?.message||t}`),0}}var hd,Rr,Jn=E(()=>{"use strict";re();hd="\0",Rr=(n,e)=>`${n}${hd}${e}`});function yd(n){return/\[1m\]/i.test(n)?1e6:2e5}function _d(n){let e=n.toLowerCase();return e.includes("haiku")||e.includes("mini")?8192:32e3}function kd(n,e=n){let t=yd(n),o=_d(n);return{type:"model",id:n,display_name:e,created_at:"2024-01-01T00:00:00Z",context_window:t,contextWindow:t,max_input_tokens:t,maxInputTokens:t,max_tokens:o,maxTokens:o,max_output_tokens:o,maxOutputTokens:o,capabilities:{context_window:t,contextWindow:t,max_input_tokens:t,maxInputTokens:t,max_tokens:o,maxTokens:o,max_output_tokens:o,maxOutputTokens:o}}}function Wn(n){let e=new Map,t=(o,r=o)=>{!o||e.has(o)||e.set(o,kd(o,r))};t("ccr-opus","CCR Opus"),t("ccr-sonnet","CCR Sonnet"),t("ccr-haiku","CCR Haiku"),t("ccr-opus[1m]","CCR Opus 1M"),t("ccr-sonnet[1m]","CCR Sonnet 1M"),t("ccr-haiku[1m]","CCR Haiku 1M");for(let o of n.Providers||n.providers||[])if(!(!o?.name||!Array.isArray(o.models)))for(let r of o.models)typeof r!="string"||!r||(t(r,r),t(`${o.name},${r}`,`${o.name}/${r}`));return Array.from(e.values())}var wr=E(()=>{"use strict"});function bd(n){let e=n.ip||n.connection?.remoteAddress||"";return e==="127.0.0.1"||e==="::1"||e==="::ffff:127.0.0.1"}var Kn,Er=E(()=>{"use strict";Kn=n=>async(e,t,o)=>{if(["/","/health"].includes(e.url)||e.url.startsWith("/ui")||bd(e))return o();let s=n.Providers||n.providers||[];if(!s||s.length===0)return o();let i=n.APIKEY;if(!i){let u=[`http://127.0.0.1:${n.PORT||3456}`,`http://localhost:${n.PORT||3456}`];if(e.headers.origin&&!u.includes(e.headers.origin)){t.status(403).send("CORS not allowed for this origin");return}else t.header("Access-Control-Allow-Origin",`http://127.0.0.1:${n.PORT||3456}`),t.header("Access-Control-Allow-Origin",`http://localhost:${n.PORT||3456}`);return o()}let a=e.headers.authorization||e.headers["x-api-key"],l=Array.isArray(a)?a[0]:a||"";if(!l){t.log.warn({url:e.url,headers:Object.keys(e.headers)},"[AUTH] No auth header"),t.status(401).send("APIKEY is missing");return}let c="";if(l.startsWith("Bearer")?c=l.split(" ")[1]:c=l,c!==i){t.log.warn({url:e.url,gotPrefix:c.slice(0,10),gotSuffix:c.slice(-6),gotLen:c.length,expectedPrefix:i.slice(0,6),expectedSuffix:i.slice(-6),expectedLen:i.length},"[AUTH] Key mismatch"),t.status(401).send("Invalid API key");return}o()}});var ka={};no(ka,{append:()=>vt,clear:()=>Ir,close:()=>zd,getOldestRecordTimestamp:()=>Bd,query:()=>Ar,querySummary:()=>xt,readTokenSpeedStats:()=>Mr});import{existsSync as pa,mkdirSync as Td,readFileSync as fa}from"fs";import{join as Qn}from"path";import{tmpdir as vd}from"os";import{openSqliteDatabase as xd}from"@wengine-ai/claude-code-router-shared";import{HOME_DIR as Cd,sanitizeTempFileKey as Sd,TOKEN_SPEED_TEMP_SUBDIRECTORY as Rd}from"@wengine-ai/claude-code-router-shared";function Ad(){pa(Vn)||Td(Vn,{recursive:!0})}function Tt(){if(be)return be;Ad();let n=xd(wd),e=n.db;n.driver==="node:sqlite"&&console.error(`[usage] better-sqlite3 unavailable, using built-in node:sqlite fallback. Reason: ${n.fallbackReason}`),e.pragma("journal_mode = WAL"),e.pragma("synchronous = NORMAL"),e.pragma("busy_timeout = 5000");let t=e.pragma("user_version",{simple:!0})||0;return t<1&&(Id(e),e.pragma("user_version = 1")),t<2&&(e.prepare("PRAGMA table_info(usage_records)").all().some(r=>r.name==="upstream_model")||e.exec("ALTER TABLE usage_records ADD COLUMN upstream_model TEXT"),e.pragma("user_version = 2")),Nd(e),ha(e,!0),Or=e.prepare(`
316
+ `):`${o}${e}`}async output(e,t={}){try{let o=this.formatData(e,t);switch(this.config.level||"log"){case"info":console.info(o);break;case"warn":console.warn(o);break;case"error":console.error(o);break;case"debug":console.debug(o);break;case"log":default:console.log(o);break}return!0}catch(o){return console.error("[ConsoleOutputHandler] Output failed:",o),!1}}}});var pt,ur=E(()=>{"use strict";pt=class{type="webhook";config;defaultTimeout=3e4;constructor(e){if(!e.url)throw new Error("Webhook URL is required");this.config={method:"POST",retry:{maxAttempts:3,backoffMs:1e3},silent:!1,...e}}buildHeaders(){let e={"Content-Type":"application/json",...this.config.headers||{}};if(this.config.auth)switch(this.config.auth.type){case"bearer":this.config.auth.token&&(e.Authorization=`Bearer ${this.config.auth.token}`);break;case"basic":if(this.config.auth.username&&this.config.auth.password){let t=Buffer.from(`${this.config.auth.username}:${this.config.auth.password}`).toString("base64");e.Authorization=`Basic ${t}`}break;case"custom":this.config.auth.custom&&(e[this.config.auth.custom.header]=this.config.auth.custom.value);break}return e}buildBody(e,t){let{format:o="json",timestamp:r=!0,prefix:s,metadata:i}=t||{},a={data:e};return r&&(a.timestamp=new Date().toISOString()),s&&(a.prefix=s),i&&Object.keys(i).length>0&&(a.metadata=i),a}async sendRequest(e,t,o,r,s){let i=new AbortController,a=setTimeout(()=>i.abort(),s);try{let l=await fetch(e,{method:t,headers:o,body:JSON.stringify(r),signal:i.signal});if(clearTimeout(a),!l.ok)throw new Error(`HTTP ${l.status}: ${l.statusText}`);return l}catch(l){throw clearTimeout(a),l}}delay(e){return new Promise(t=>setTimeout(t,e))}async sendWithRetry(e,t,o,r,s,i){let a=null;for(let l=1;l<=i.maxAttempts;l++)try{return await this.sendRequest(e,t,o,r,s)}catch(c){if(a=c,l===i.maxAttempts)break;let u=i.backoffMs*Math.pow(2,l-1);console.warn(`[WebhookOutputHandler] Request failed (attempt ${l}/${i.maxAttempts}), retrying in ${u}ms...`,c.message),await this.delay(u)}throw a}async output(e,t={}){let o=t.timeout||this.defaultTimeout;try{let r=this.buildHeaders(),s=this.buildBody(e,t),i=await this.sendWithRetry(this.config.url,this.config.method,r,s,o,this.config.retry);return!0}catch(r){let s=r instanceof Error?r.message:String(r);if(this.config.silent)return console.error(`[WebhookOutputHandler] Failed to send data: ${s}`),!1;throw new Error(`Webhook output failed: ${s}`)}}}});import{lstat as Mn,opendir as Ju,unlink as Wu}from"node:fs/promises";import{join as Zi,resolve as fr}from"node:path";import{tmpdir as Ku}from"node:os";async function Nn(n,e){let t=fr(n),o=In.get(t),r,s=new Promise(i=>{r=i});In.set(t,s);try{return await o,await e()}finally{r(),In.get(t)===s&&In.delete(t)}}function qi(n,e){return n.dev===e.dev&&n.ino===e.ino}async function Xi(n,e){try{let t=await Mn(n);return t.isDirectory()&&!t.isSymbolicLink()&&qi(e,t)}catch{return!1}}function Xu(){return new Promise(n=>{setTimeout(n,10).unref()})}async function ea(n,e,t,o){let r=fr(n);if(o?.aborted||dr.has(r))return 0;dr.add(r);let s=0;try{let i=await Mn(r);if(!i.isDirectory()||i.isSymbolicLink()||o?.aborted)return 0;let a=await Ju(r,{bufferSize:32});try{let l=0,c=!0;for await(let u of a){if(o?.aborted||!c)break;try{if(!u.isFile()||u.isSymbolicLink()||!t(u.name))continue;let d=Zi(r,u.name);try{let p=await Mn(d);if(!p.isFile()||p.isSymbolicLink()||p.mtimeMs>=e)continue;await Nn(d,async()=>{if(o?.aborted||!await Xi(r,i))return!1;let h=await Mn(d);return!h.isFile()||h.isSymbolicLink()||!qi(p,h)||h.mtimeMs!==p.mtimeMs||h.mtimeMs>=e||o?.aborted?!1:(await Wu(d),!0)})&&s++}catch{}}finally{++l%64===0&&(await Xu(),c=!o?.aborted&&await Xi(r,i))}}}finally{await a.close().catch(()=>{})}}catch{}finally{dr.delete(r)}return s}function ta(n,e,t,o,r){if(!Number.isFinite(o)||o<=0)return Promise.resolve(0);let s=`${e}-`,i=t?`.${t}`:"";return ea(n,Date.now()-o,a=>Yu.test(a)?!0:!a.endsWith(".tmp")&&a.startsWith(s)&&a.endsWith(i),r)}function Zu(n,e){let t=Date.now()-Gu;return ea(n,t,o=>{let r=Qu.exec(o);return r!==null&&Number(r[1])<t},e)}function mr(n,e,t){let o=pr.get(n);if(!o){let s=new AbortController,i,a=()=>{s.signal.aborted||Promise.resolve().then(()=>e(s.signal)).catch(()=>{})},l=setTimeout(()=>{s.signal.aborted||(a(),i=setInterval(a,Vu),i.unref())},t);l.unref(),o={users:0,stop:()=>{s.abort(),clearTimeout(l),i&&clearInterval(i)}},pr.set(n,o)}o.users++;let r=!1;return()=>{r||(r=!0,--o.users===0&&(o.stop(),pr.delete(n)))}}function na(n=Zi(Ku(),"claude-code-router")){return mr(`legacy:${fr(n)}`,e=>Zu(n,e),1e3)}var Gu,Vu,Qu,Yu,dr,In,pr,gr=E(()=>{"use strict";Gu=3600*1e3,Vu=600*1e3,Qu=/^session-[A-Za-z0-9_.-]+-(\d{13})\.json$/,Yu=/^\.ccr-tmp-[1-9]\d*-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\.tmp$/,dr=new Set,In=new Map,pr=new Map});import{lstat as qu,mkdir as ed,open as td,rename as nd,unlink as od}from"node:fs/promises";import{randomUUID as rd}from"node:crypto";import{sanitizeTempFileKey as sd}from"@wengine-ai/claude-code-router-shared";import{basename as id,join as hr,resolve as ad}from"node:path";import{tmpdir as cd}from"node:os";var ft,yr=E(()=>{"use strict";gr();ft=class{type="temp-file";config;baseDir;controller=new AbortController;stopSchedule;constructor(e={}){if(this.config={subdirectory:"claude-code-router",extension:"json",includeTimestamp:!1,prefix:"session",retentionMs:36e5,...e},this.baseDir=ad(hr(cd(),this.config.subdirectory)),Number.isFinite(this.config.retentionMs)&&this.config.retentionMs>0){let t=JSON.stringify([this.baseDir,this.config.prefix,this.config.extension,this.config.retentionMs]);this.stopSchedule=mr(`handler:${t}`,o=>this.pruneOldFiles(o),6e4)}}async ensureDir(){await ed(this.baseDir,{recursive:!0});let e=await qu(this.baseDir);if(!e.isDirectory()||e.isSymbolicLink())throw new Error("Unsafe temp output directory")}getFilePath(e){let t=this.config.prefix||"session",o=this.config.extension?`.${this.config.extension}`:"",r=this.config.includeTimestamp?`-${Date.now()}`:"",s=`${t}-${sd(e)}${r}${o}`;if(id(s)!==s||s.includes("\\"))throw new Error("Temp file configuration must not contain path separators");return hr(this.baseDir,s)}async output(e,t={}){try{let o=typeof t.metadata?.statsKey=="string"&&t.metadata.statsKey?t.metadata.statsKey:t.metadata?.sessionId;if(!o)return!1;let r=t.metadata?.sessionId??o,s=JSON.stringify({...e,timestamp:Date.now(),sessionId:r},null,2),i=this.getFilePath(o);return await Nn(i,async()=>{await this.ensureDir();let a=hr(this.baseDir,`.ccr-tmp-${process.pid}-${rd()}.tmp`);return Nn(a,async()=>{let l=!1;try{let c=await td(a,"wx");l=!0;try{await c.writeFile(s,"utf-8")}finally{await c.close()}return await nd(a,i),!0}finally{l&&await od(a).catch(()=>{})}})})}catch{return!1}}pruneOldFiles(e=this.controller.signal){return ta(this.baseDir,this.config.prefix||"session",this.config.extension||"",this.config.retentionMs,e)}dispose(){this.controller.abort(),this.stopSchedule?.()}getBaseDir(){return this.baseDir}}});var _r,Ge,oa=E(()=>{"use strict";lr();ur();yr();_r=class{handlers=new Map;defaultOptions={};registerHandler(e,t){this.handlers.set(e,t)}registerHandlers(e){for(let t of e)if(t.enabled!==!1)try{let o=this.createHandler(t),r=t.type+"_"+Date.now();this.registerHandler(r,o)}catch(o){console.error(`[OutputManager] Failed to register ${t.type} handler:`,o)}}createHandler(e){switch(e.type){case"console":return new dt(e.config);case"webhook":return new pt(e.config);case"temp-file":return new ft(e.config);default:throw new Error(`Unknown output handler type: ${e.type}`)}}unregisterHandler(e){return this.handlers.delete(e)}getHandler(e){return this.handlers.get(e)}getAllHandlers(){return new Map(this.handlers)}clearHandlers(){this.handlers.clear()}setDefaultOptions(e){this.defaultOptions={...this.defaultOptions,...e}}getDefaultOptions(){return{...this.defaultOptions}}async output(e,t){let o={...this.defaultOptions,...t},r={success:[],failed:[]},s=Array.from(this.handlers.entries()).map(async([i,a])=>{try{await a.output(e,o)?r.success.push(i):r.failed.push(i)}catch(l){console.error(`[OutputManager] Handler ${i} failed:`,l),r.failed.push(i)}});return await Promise.all(s),r}async outputTo(e,t,o){let r={...this.defaultOptions,...o},s={success:[],failed:[]},i=e.map(async a=>{let l=this.handlers.get(a);if(!l){console.warn(`[OutputManager] Handler ${a} not found`),s.failed.push(a);return}try{await l.output(t,r)?s.success.push(a):s.failed.push(a)}catch(c){console.error(`[OutputManager] Handler ${a} failed:`,c),s.failed.push(a)}});return await Promise.all(i),s}async outputToType(e,t,o){let r=Array.from(this.handlers.entries()).filter(([s,i])=>i.type===e).map(([s])=>s);return this.outputTo(r,t,o)}},Ge=new _r});var kr=E(()=>{"use strict";Yi();lr();ur();yr();oa()});import ld from"fastify-plugin";import{TOKEN_SPEED_TEMP_SUBDIRECTORY as ud}from"@wengine-ai/claude-code-router-shared";function $n(){return{subdirectory:ud,extension:"json",includeTimestamp:!1,prefix:"session"}}function ra(n,e,t=0){if(n<=0)return 0;let o=Math.max((e-t)/1e3,dd);return Math.round(n/o)}function gt(n){let e=(n.match(/[\u4e00-\u9fa5]/g)||[]).length,t=n.length-e;return Math.ceil(e/1.5+t/4)}async function sa(n,e,t,o=!1){let r=o?"[Token Speed Final]":"[Token Speed]",s={requestId:n.requestId.substring(0,8),sessionId:n.sessionId,stream:n.stream,tokenCount:n.tokenCount,tokensPerSecond:n.tokensPerSecond,timeToFirstToken:n.timeToFirstToken?`${n.timeToFirstToken}ms`:"N/A",duration:`${((n.lastTokenTime-n.startTime)/1e3).toFixed(2)}s`,timestamp:Date.now()},i={prefix:r,metadata:{sessionId:n.sessionId,statsKey:n.statsKey},...t};for(let a of e)try{await Ge.outputToType(a,s,i)}catch(l){console.error(`[TokenSpeedPlugin] Failed to output to ${a}:`,l)}}var mt,br,dd,Ln,ia=E(()=>{"use strict";cr();kr();Ne();mt=new Map,br=new Map,dd=1,Ln={name:"token-speed",version:"1.0.0",description:"Statistics for streaming response token generation speed",register:ld(async(n,e)=>{let t={reporter:["console","temp-file"],...e},o=Array.isArray(t.reporter)?t.reporter:[t.reporter];if(t.outputHandlers&&t.outputHandlers.length>0)Ge.registerHandlers(t.outputHandlers);else{let i=[];for(let a of o)a==="console"?i.push({type:"console",enabled:!0,config:{colors:!0,level:"log"}}):a==="temp-file"?i.push({type:"temp-file",enabled:!0,config:$n()}):a==="webhook"&&console.warn("[TokenSpeedPlugin] Webhook reporter requires explicit configuration in outputHandlers");i.length>0&&Ge.registerHandlers(i)}t.outputOptions&&Ge.setDefaultOptions(t.outputOptions);let r=async i=>{let a=n.tokenizerService;if(!a)return n.log?.warn("TokenizerService not available"),null;if(!i.provider||!i.model)return null;let l=i.provider,c=i.model,u=`${l}:${c}`;if(br.has(u))return br.get(u);let d=a.getTokenizerConfigForModel(l,c);if(!d)return n.log?.debug(`No tokenizer config for ${l}:${c}, using fallback`),null;try{let p=await a.getTokenizer(d,l);return br.set(u,p),n.log?.info(`Created tokenizer for ${l}:${c} - ${p.name}`),p}catch(p){return n.log?.warn(`Failed to create tokenizer for ${l}:${c}: ${p.message}`),null}},s=i=>{let a=new URL(`http://127.0.0.1${i}`).pathname;return a.endsWith("/v1/messages")||a.endsWith("/v1/responses")};n.addHook("onRequest",async i=>{s(i.url)&&(i.requestStartTime=performance.now())}),n.addHook("onSend",async(i,a,l)=>{let c=i.requestStartTime;if(!c)return;let u=i.id||Date.now().toString(),d=i.usageSessionId||u,p=i.sessionId;if(!p)try{p=ge(i.body?.metadata?.user_id)||d}catch{p=d}let m=await r(i);if(l instanceof ReadableStream){mt.set(u,{requestId:u,sessionId:p,statsKey:d,startTime:c,lastTokenTime:c,tokenCount:0,tokensPerSecond:0,stream:!0});let[_,k]=l.tee(),y=async()=>{let b=null,T=async C=>{let v=mt.get(u);if(!v)return;let S=v.firstTokenTime?v.firstTokenTime-v.startTime:0,w=(C?v.lastTokenTime:performance.now())-v.startTime;v.tokensPerSecond=ra(v.tokenCount,w,S),await sa(v,o,t.outputOptions,C).catch(R=>{n.log?.warn(`Failed to output streaming stats: ${R.message}`)})};try{let v=k.pipeThrough(new TextDecoderStream).pipeThrough(new ae).getReader();for(b=setInterval(async()=>{mt.get(u)&&await T(!1)},1e3);;){let{done:S,value:x}=await v.read();if(S)break;let w=x,R=mt.get(u);if(!R)continue;let O=performance.now(),P=w.event||w.data?.type,M=w.event==="content_block_start"||w.event==="content_block_delta"||w.event==="text_block"||w.event==="content_block"||P==="response.output_text.delta"||P==="response.function_call_arguments.delta"||P==="response.reasoning_summary_text.delta";!R.firstTokenTime&&M&&(R.firstTokenTime=O,R.timeToFirstToken=Math.round(O-R.startTime));let $="";if(w.event==="content_block_delta"&&w.data?.delta){let L=w.data.delta.type;L==="text_delta"?$=w.data.delta.text||"":L==="input_json_delta"?$=w.data.delta.partial_json||"":L==="thinking_delta"&&($=w.data.delta.thinking||"")}if((P==="response.output_text.delta"||P==="response.function_call_arguments.delta"||P==="response.reasoning_summary_text.delta")&&($=typeof w.data?.delta=="string"?w.data.delta:""),$){let L=m&&m.encodeText?m.encodeText($).length:gt($);R.tokenCount+=L,R.lastTokenTime=O}(w.event==="message_stop"||P==="response.completed"||P==="response.failed")&&(b&&(clearInterval(b),b=null),await T(!0),mt.delete(u))}}catch(C){b&&clearInterval(b),C.name!=="AbortError"&&C.code!=="ERR_STREAM_PREMATURE_CLOSE"&&n.log?.warn(`Error processing token stats: ${C.message}`)}};return i.tokenSpeedCapturePromise=y().catch(b=>{console.log(b),n.log?.warn(`Background stats processing failed: ${b.message}`)}),_}let h=performance.now(),g=0,f=!1;if(l&&typeof l=="string")try{let _=JSON.parse(l);if(typeof _.usage?.output_tokens=="number")g=_.usage.output_tokens,f=!0;else{let k=_.content??_.message?.content;if(k!==void 0)if(f=!0,m)Array.isArray(k)?g=k.reduce((y,b)=>{if(b.type==="text"){let T=b.text||"";return y+(m.encodeText?m.encodeText(T).length:gt(T))}return y},0):typeof k=="string"&&(g=m.encodeText?m.encodeText(k).length:gt(k));else{let y=Array.isArray(k)?k.map(b=>b.text).join(""):typeof k=="string"?k:"";g=gt(y)}}}catch{}if(f){let _=h-c,k={requestId:u,sessionId:p,statsKey:d,startTime:c,lastTokenTime:h,tokenCount:g,tokensPerSecond:ra(g,_),stream:!1};await sa(k,o,t.outputOptions,!0)}return l})})}});var Tr=E(()=>{"use strict";Vi();Qi();ia();kr()});import ee from"node:fs/promises";import aa from"json5";import Se from"node:path";import{CONFIG_FILE as te,HOME_DIR as Dn,PLUGINS_DIR as pd}from"@wengine-ai/claude-code-router-shared";function ca(){if(process.env.VITEST||process.env.CI)throw new Error("Config write attempted during test/CI. Set CCR_CONFIG_DIR to a temp dir to isolate.")}var vr,ht,Fn,xr,ne,Un,_e,fd,Cr,jn=E(()=>{"use strict";vr=n=>{if(typeof n=="string")return n.replace(/\$\{([^}]+)\}|\$([A-Z_][A-Z0-9_]*)/g,(e,t,o)=>{let r=t||o;return process.env[r]||e});if(Array.isArray(n))return n.map(vr);if(n!==null&&typeof n=="object"){let e={};for(let[t,o]of Object.entries(n))e[t]=vr(o);return e}return n},ht=async n=>{try{await ee.access(n)}catch{await ee.mkdir(n,{recursive:!0})}},Fn=async()=>{await ht(Dn),await ht(pd),await ht(Se.join(Dn,"logs"))},xr=async()=>{let n=await ee.readFile(te,"utf-8");return aa.parse(n)},ne=async()=>{try{let n=await ee.readFile(te,"utf-8");try{let e=aa.parse(n);return vr(e)}catch(e){console.error(`Failed to parse config file at ${te}`),console.error("Error details:",e.message),console.error("Please check your config file syntax."),process.exit(1)}}catch(n){if(n.code==="ENOENT")try{await Fn();let e=await Un();e&&console.log(`Backed up existing configuration file to ${e}`);let t={PORT:3456,Providers:[],Router:{}};return await _e(t),console.log("Created minimal default configuration file at ~/.claude-code-router/config.json"),console.log("Please edit this file with your actual configuration."),t}catch(e){console.error("Failed to create default configuration:",e.message),process.exit(1)}else console.error(`Failed to read config file at ${te}`),console.error("Error details:",n.message),process.exit(1)}};Un=async()=>{ca();try{if(await ee.access(te).then(()=>!0).catch(()=>!1)){let n=new Date().toISOString().replace(/[:.]/g,"-"),e=`${te}.${n}.bak`;await ee.copyFile(te,e);try{let t=Se.dirname(te),o=Se.basename(te),s=(await ee.readdir(t)).filter(i=>i.startsWith(o)&&i.endsWith(".bak")).sort().reverse();if(s.length>3)for(let i=3;i<s.length;i++){let a=Se.join(t,s[i]);await ee.unlink(a)}}catch(t){console.warn("Failed to clean up old backups:",t)}return e}}catch(n){console.error("Failed to backup config file:",n)}return null},_e=async n=>{ca(),await ht(Dn),await fd();let e=`${JSON.stringify(n,null,2)}`;await ee.writeFile(te,e)},fd=async()=>{if(!await ee.access(te).then(()=>!0).catch(()=>!1))return;let e=Se.join(Dn,"config-history");await ht(e);let t=new Date().toISOString().replace(/[:.]/g,"-"),o=Se.join(e,`config-${t}.json`);await ee.copyFile(te,o);try{let s=(await ee.readdir(e)).filter(i=>i.startsWith("config-")&&i.endsWith(".json")).sort().reverse();if(s.length>50)for(let i of s.slice(50))await ee.unlink(Se.join(e,i))}catch(r){console.warn("Failed to prune config-history:",r)}},Cr=async()=>{let n=await ne();return Object.assign(process.env,n),n}});function md(n){return n?.cache_read_input_tokens??n?.input_tokens_details?.cached_tokens??n?.prompt_tokens_details?.cached_tokens??0}function gd(n){return n?.cache_creation_input_tokens??n?.input_tokens_details?.cache_creation_tokens??n?.input_tokens_details?.cache_write_tokens??n?.prompt_tokens_details?.cache_creation_tokens??n?.prompt_tokens_details?.cache_write_tokens??0}function Ve(n){if(!(!n||typeof n!="object"))return{...n,input_tokens:n.input_tokens??n.prompt_tokens??0,output_tokens:n.output_tokens??n.completion_tokens??0,cache_read_input_tokens:md(n),cache_creation_input_tokens:gd(n)}}function Hn(n,e,t){let o=t?{}:n||{},r=e||{};return{...o,input_tokens:r.input_tokens||o.input_tokens||0,output_tokens:r.output_tokens||o.output_tokens||0,cache_read_input_tokens:r.cache_read_input_tokens||o.cache_read_input_tokens||0,cache_creation_input_tokens:r.cache_creation_input_tokens||o.cache_creation_input_tokens||0}}var Sr=E(()=>{"use strict"});function zn(n,e,t){if(n){if(typeof n=="string"){let o=n.indexOf(",");if(o>0){let r=n.slice(0,o).trim(),s=n.slice(o+1).trim();r&&s&&e.has(r)&&t.add(Rr(r,s))}return}if(Array.isArray(n)){for(let o of n)zn(o,e,t);return}if(typeof n=="object")for(let o of Object.values(n))zn(o,e,t)}}function la(n){let e=n?.Providers||n?.providers||[],t=new Set,o=new Set;for(let r of e){let s=r?.name;if(!s)continue;t.add(s);let i=Array.isArray(r?.models)?r.models:[];for(let a of i)a&&o.add(Rr(s,a))}return zn(n?.Router,t,o),zn(n?.fallback,t,o),o}function yt(n,e){try{let t=U();if(!t?.getAllStates||!t?.recover)return 0;let o=la(n),r=0;for(let s of t.getAllStates()||[]){let i=s?.provider,a=s?.model;!i||!a||o.has(Rr(i,a))||(t.recover(i,a),r++)}return r>0&&e?.info?.(`[health-reconcile] Pruned ${r} orphaned provider-health entr${r===1?"y":"ies"}`),r}catch(t){return e?.warn?.(`[health-reconcile] Failed to reconcile health store: ${t?.message||t}`),0}}function Bn(n,e){try{if(!n)return 0;let t=U();if(!t?.getAllStates||!t?.recover)return 0;let o=0;for(let r of t.getAllStates()||[])r?.provider===n&&r?.model&&(t.recover(n,r.model),o++);return o>0&&e?.info?.(`[health-reconcile] Cleared ${o} health entr${o===1?"y":"ies"} for probed provider ${n}`),o}catch(t){return e?.warn?.(`[health-reconcile] Failed to clear provider health for ${n}: ${t?.message||t}`),0}}var hd,Rr,Jn=E(()=>{"use strict";re();hd="\0",Rr=(n,e)=>`${n}${hd}${e}`});function yd(n){return/\[1m\]/i.test(n)?1e6:2e5}function _d(n){let e=n.toLowerCase();return e.includes("haiku")||e.includes("mini")?8192:32e3}function kd(n,e=n){let t=yd(n),o=_d(n);return{type:"model",id:n,display_name:e,created_at:"2024-01-01T00:00:00Z",context_window:t,contextWindow:t,max_input_tokens:t,maxInputTokens:t,max_tokens:o,maxTokens:o,max_output_tokens:o,maxOutputTokens:o,capabilities:{context_window:t,contextWindow:t,max_input_tokens:t,maxInputTokens:t,max_tokens:o,maxTokens:o,max_output_tokens:o,maxOutputTokens:o}}}function Wn(n){let e=new Map,t=(o,r=o)=>{!o||e.has(o)||e.set(o,kd(o,r))};t("ccr-opus","CCR Opus"),t("ccr-sonnet","CCR Sonnet"),t("ccr-haiku","CCR Haiku"),t("ccr-opus[1m]","CCR Opus 1M"),t("ccr-sonnet[1m]","CCR Sonnet 1M"),t("ccr-haiku[1m]","CCR Haiku 1M");for(let o of n.Providers||n.providers||[])if(!(!o?.name||!Array.isArray(o.models)))for(let r of o.models)typeof r!="string"||!r||(t(r,r),t(`${o.name},${r}`,`${o.name}/${r}`));return Array.from(e.values())}var wr=E(()=>{"use strict"});function bd(n){let e=n.ip||n.connection?.remoteAddress||"";return e==="127.0.0.1"||e==="::1"||e==="::ffff:127.0.0.1"}var Kn,Er=E(()=>{"use strict";Kn=n=>async(e,t,o)=>{if(["/","/health"].includes(e.url)||e.url.startsWith("/ui")||bd(e))return o();let s=n.Providers||n.providers||[];if(!s||s.length===0)return o();let i=n.APIKEY;if(!i){let u=[`http://127.0.0.1:${n.PORT||3456}`,`http://localhost:${n.PORT||3456}`];if(e.headers.origin&&!u.includes(e.headers.origin)){t.status(403).send("CORS not allowed for this origin");return}else t.header("Access-Control-Allow-Origin",`http://127.0.0.1:${n.PORT||3456}`),t.header("Access-Control-Allow-Origin",`http://localhost:${n.PORT||3456}`);return o()}let a=e.headers.authorization||e.headers["x-api-key"],l=Array.isArray(a)?a[0]:a||"";if(!l){t.log.warn({url:e.url,headers:Object.keys(e.headers)},"[AUTH] No auth header"),t.status(401).send("APIKEY is missing");return}let c="";if(l.startsWith("Bearer")?c=l.split(" ")[1]:c=l,c!==i){t.log.warn({url:e.url,gotPrefix:c.slice(0,10),gotSuffix:c.slice(-6),gotLen:c.length,expectedPrefix:i.slice(0,6),expectedSuffix:i.slice(-6),expectedLen:i.length},"[AUTH] Key mismatch"),t.status(401).send("Invalid API key");return}o()}});var ka={};no(ka,{append:()=>vt,clear:()=>Ir,close:()=>zd,getOldestRecordTimestamp:()=>Bd,query:()=>Ar,querySummary:()=>xt,readTokenSpeedStats:()=>Mr});import{existsSync as pa,mkdirSync as Td,readFileSync as fa}from"fs";import{join as Qn}from"path";import{tmpdir as vd}from"os";import{openSqliteDatabase as xd}from"@wengine-ai/claude-code-router-shared";import{HOME_DIR as Cd,sanitizeTempFileKey as Sd,TOKEN_SPEED_TEMP_SUBDIRECTORY as Rd}from"@wengine-ai/claude-code-router-shared";function Ad(){pa(Vn)||Td(Vn,{recursive:!0})}function Tt(){if(be)return be;Ad();let n=xd(wd),e=n.db;n.driver==="node:sqlite"&&console.error(`[usage] better-sqlite3 unavailable, using built-in node:sqlite fallback. Reason: ${n.fallbackReason}`),e.pragma("journal_mode = WAL"),e.pragma("synchronous = NORMAL"),e.pragma("busy_timeout = 5000");let t=e.pragma("user_version",{simple:!0})||0;return t<1&&(Id(e),e.pragma("user_version = 1")),t<2&&(e.prepare("PRAGMA table_info(usage_records)").all().some(r=>r.name==="upstream_model")||e.exec("ALTER TABLE usage_records ADD COLUMN upstream_model TEXT"),e.pragma("user_version = 2")),Nd(e),ha(e,!0),Or=e.prepare(`
317
317
  INSERT INTO usage_records (
318
318
  id, timestamp, session_id, provider, original_model, model, upstream_model, model_family,
319
319
  scenario_type, client_type,