@wengine-ai/llms 2.3.234 → 2.3.236
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/ccr/config.d.ts +6 -0
- package/dist/cjs/server.cjs +52 -52
- package/dist/cjs/server.cjs.map +3 -3
- package/dist/clients/adapters.d.ts +0 -1
- package/dist/esm/server.mjs +44 -44
- package/dist/esm/server.mjs.map +3 -3
- package/dist/index.html +24 -24
- package/dist/services/quota-adapters.d.ts +19 -0
- package/dist/types/llm.d.ts +9 -0
- package/package.json +2 -2
- package/vitest.config.ts +16 -1
package/dist/esm/server.mjs
CHANGED
|
@@ -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
|
-
var Ln=Object.defineProperty;var
|
|
2
|
+
var Ln=Object.defineProperty;var ba=Object.getOwnPropertyDescriptor;var xa=Object.getOwnPropertyNames;var Ca=Object.prototype.hasOwnProperty;var Be=(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 S=(n,e)=>()=>(n&&(e=n(n=0)),e);var Fn=(n,e)=>{for(var t in e)Ln(n,t,{get:e[t],enumerable:!0})},Ta=(n,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of xa(e))!Ca.call(n,r)&&r!==t&&Ln(n,r,{get:()=>e[r],enumerable:!(o=ba(e,r))||o.enumerable});return n};var va=n=>Ta(Ln({},"__esModule",{value:!0}),n);import{ProxyAgent as Ra}from"undici";function Sa(n){if(n==null)return{ok:!0};let e=String(n).trim();if(!e)return{ok:!0};if(wa.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 yr(n){let e=[];for(let t of hr){let o=n[t];if(o==null)continue;let r=Sa(o);r.ok||e.push({key:t,error:r.error})}return e}function kt(n){for(let e of hr){let t=n.get(e);if(t==null)continue;let o=String(t).trim();if(o)return o}}function _r(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 ie(n,e){let t=kt(n);if(t)return _r(n.get("PROXY_GLOBAL_ENABLED"))||e?.proxyEnabled===!0||e?.proxy_enabled===!0?t:void 0}function G(n){let e=Pa(n),t=_t.get(e);if(t)return t;let o=new Ra(e);return _t.set(e,o),o}async function Un(){let n=Array.from(_t.values());_t.clear(),await Promise.allSettled(n.map(e=>e.close()))}function Pa(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 hr,wa,_t,te=S(()=>{"use strict";hr=["HTTPS_PROXY","https_proxy","httpsProxy","PROXY_URL"],wa=/\$\{[^}]+\}|\$[A-Z_][A-Z0-9_]*/;_t=new Map});import{readFileSync as Aa,existsSync as kr}from"fs";import{join as br}from"path";import{config as Oa}from"dotenv";import Ea from"json5";var xe,Dn=S(()=>{"use strict";te();xe=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:br(process.cwd(),this.options.jsonPath);if(kr(e))try{let t=Aa(e,"utf-8"),o=Ea.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:br(process.cwd(),this.options.envPath);if(kr(e))try{let t=Oa({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 kt(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 B(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 xr(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 bt=S(()=>{"use strict"});function zn(n){jn=n}function xt(){return jn}function Ct(n){return jn||n.get("DEBUG_LOG")===!0}function vr(n){let e=n.get("DEBUG_LOG_OPTIONS");return!e||typeof e!="object"?Ce:{maxBodyLength:e.maxBodyLength??Ce.maxBodyLength,maxStreamChunks:e.maxStreamChunks??Ce.maxStreamChunks}}function Tt(n){let e={};for(let[t,o]of Object.entries(n))Ia.has(t.toLowerCase())?e[t]="***MASKED***":e[t]=o;return e}function vt(n,e){return n.length<=e?n:n.slice(0,e)+`...[truncated, total ${n.length} bytes]`}function Rr(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:Tt(t.headers),body:vt(o,Ce.maxBodyLength)})}function wr(n,e,t){n.info({debug_log:!0,reqId:e,phase:"provider_response",status:t.status,headers:Tt(t.headers),...t.body!==void 0?{body:vt(t.body,Ce.maxBodyLength)}:{}})}function Cr(n,e,t,o){let r=Ma(o);n.info({debug_log:!0,reqId:e,phase:"provider_stream_chunk",chunkIndex:t,...r?{usage_monitor:r}:{},data:vt(o,Ce.maxBodyLength)})}function Ma(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:vt(o,512)})}}if(e.length)return e.length===1?e[0]:e}function Tr(n,e,t){n.info({debug_log:!0,reqId:e,phase:"provider_stream_end",totalChunks:t})}function Sr(n,e,t,o){(async()=>{let r=n.pipeThrough(new TextDecoderStream).getReader(),s=0;try{let a="";for(;;){let{done:l,value:c}=await r.read();if(l)break;a+=c;let i=a.split(`
|
|
3
3
|
|
|
4
|
-
`);a=i.pop()||"";for(let u of i)u.trim()&&(s<o.maxStreamChunks?Cr(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++)}a.trim()&&(s<o.maxStreamChunks&&Cr(e,t,s,a.trim()),s++),Tr(e,t,s)}catch(a){console.error(`[debug_log] Error reading debug stream for reqId=${t}:`,a),Tr(e,t,s)}finally{r.releaseLock()}})()}var Ma,xe,jn,We=S(()=>{"use strict";Ma=new Set(["authorization","x-api-key","x-goog-api-key","cookie","set-cookie"]),xe={maxBodyLength:4096,maxStreamChunks:100},jn=!1});function Pr(n,e,t,o,r){let s=new Headers({"Content-Type":"application/json"});t.headers&&Object.entries(t.headers).forEach(([i,u])=>{u&&s.set(i,u)});let a,l=AbortSignal.timeout(t.TIMEOUT??60*1e3*60);if(t.signal){let i=new AbortController,u=()=>i.abort();t.signal.addEventListener("abort",u),l.addEventListener("abort",u),a=i.signal}else a=l;let c={method:"POST",headers:s,body:JSON.stringify(e),signal:a};return t.httpsProxy&&(c.dispatcher=V(t.httpsProxy)),r?.debug({reqId:o.req.id,method:"POST",headers:Tt(Object.fromEntries(s.entries())),requestUrl:typeof n=="string"?n:n.toString(),useProxy:Na(t.httpsProxy)},"final request"),fetch(typeof n=="string"?n:n.toString(),c)}function Na(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 Ar=S(()=>{Z();We()});var Rt,Hn=S(()=>{Rt="2.3.234"});var Or={};Fn(Or,{getFallbackPromotionStore:()=>Ce,resetFallbackPromotionStore:()=>Ua});function Ce(n){return ge||(ge=new Jn,n&&ge.configure(n)),ge}function Ua(){ge&&(ge.clearAll(),ge=null)}var Fa,Jn,ge,wt=S(()=>{"use strict";ee();Fa=600*1e3,Jn=class{promotions=new Map;enabled=!0;ttlMs=Fa;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,a){if(!this.enabled)return;let l=this.getKey(e,t,o),c=`${r},${s}`;this.promotions.set(l,{promotedModel:c,timestamp:Date.now(),ttlMs:a??this.ttlMs})}getPromotion(e,t,o,r){if(!this.enabled)return null;let s=this.getKey(e,t,o),a=this.promotions.get(s);if(!a)return null;if(Date.now()-a.timestamp>=a.ttlMs)return this.promotions.delete(s),null;let[c,...i]=a.promotedModel.split(","),u=i.join(",");if(!U().isAvailable(c,u))return this.promotions.delete(s),null;let m=r.find(y=>y.name.toLowerCase()===c.toLowerCase()),g=m?.models?.find(y=>String(y).toLowerCase()===u.toLowerCase());return!m||!g||m.enabled===!1?(this.promotions.delete(s),null):`${m.name},${g}`}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}},ge=null});import{existsSync as Mr,mkdirSync as Da,readFileSync as ja,writeFileSync as za}from"fs";import{join as $r}from"path";import{HOME_DIR as Ha}from"@wengine-ai/claude-code-router-shared";function Ga(n){try{if(!Mr(Gn))return;let e=JSON.parse(ja(Gn,"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 Ir(n){try{let e=n.getAllStates();if(e.length===0)return;Mr(Wn)||Da(Wn,{recursive:!0});let t=e.map(o=>({...o,updatedAt:Date.now()}));za(Gn,JSON.stringify(t,null,2),"utf-8")}catch{}}function Vn(){if(Er)return;Er=!0;let n=U();Ga(n),Wa=setInterval(()=>Ir(n),6e4),process.on("exit",()=>Ir(n))}function U(n){return Bn||(Bn=new St(n)),Bn}var Ja,Ba,St,Wn,Gn,Er,Wa,Bn,ee=S(()=>{"use strict";Ja=120,Ba={enabled:!0,failureThreshold:3,probeIntervalMinutes:5,halfOpenSuccessThreshold:2},St=class{states=new Map;config;probeTimer;constructor(e){this.config={...Ba,...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}=(wt(),Ra(Or));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 a=this.states.get(s);a?(a.status="open",a.lastFailureTime=Date.now(),a.lastError=r||"rate-limited",a.lastProbeTime=0):(a={provider:e,model:t,status:"open",failureCount:0,successCount:0,lastFailureTime:Date.now(),lastProbeTime:0,lastError:r||"rate-limited"},this.states.set(s,a));let l=(o??Ja)*1e3;a.rateLimitUntil=Date.now()+l}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)}},Wn=$r(Ha,"runtime"),Gn=$r(Wn,"provider-health.json"),Er=!1,Wa=null;Bn=null});import{existsSync as Dr,mkdirSync as Va,readFileSync as Qa,writeFileSync as Ka}from"fs";import{join as jr}from"path";import{HOME_DIR as Xa}from"@wengine-ai/claude-code-router-shared";function Ge(n,e,t){let o=l=>{if(t instanceof Headers)return t.get(l);let c=Object.keys(t).find(i=>i.toLowerCase()===l);return c?t[c]:null},r=Qn(o,Ya),s=Qn(o,qa),a=Qn(o,Za);(r||s||a)&&Te.set(n,{provider:n,remaining:Fr(r),limit:Fr(s),reset:tc(a),capturedAt:Date.now()})}function ec(n){return Te.get(n)}function Yn(){return Array.from(Te.values())}function Qn(n,e){for(let t of e){let o=n(t);if(o)return o}return null}function Fr(n){if(!n)return null;let e=Number(n.trim().replace(/,/g,""));return Number.isFinite(e)?e:null}function tc(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=nc(e);return r===null?null:Math.floor((Date.now()+r)/1e3)}function nc(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]),a=r[2].toLowerCase();if(Number.isFinite(s))switch(a){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 oc(){try{if(!Dr(Xn))return;let n=JSON.parse(Qa(Xn,"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;Te.set(t.provider,t)}}catch{}}function Ur(){try{if(Te.size===0)return;Dr(Kn)||Va(Kn,{recursive:!0}),Ka(Xn,JSON.stringify(Array.from(Te.values()),null,2),"utf-8")}catch{}}function Ve(){Nr||(Nr=!0,oc(),Lr=setInterval(Ur,6e4),Lr.unref?.(),process.on("exit",Ur))}var Kn,Xn,Te,Nr,Lr,Ya,qa,Za,ve=S(()=>{"use strict";Kn=jr(Xa,"runtime"),Xn=jr(Kn,"rate-limit.json"),Te=new Map,Nr=!1,Lr=null,Ya=["x-ratelimit-remaining-tokens","x-ratelimit-remaining-requests","x-ratelimit-remaining"],qa=["x-ratelimit-limit-tokens","x-ratelimit-limit-requests","x-ratelimit-limit"],Za=["x-ratelimit-reset-tokens","x-ratelimit-reset-requests","x-ratelimit-reset"]});var Re,qn=S(()=>{"use strict";Re=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 a="";typeof s=="string"?a=s:s&&typeof s=="object"&&"text"in s&&(a=s.text),t.push({role:"system",content:a})}):e.instructions=r.content}if(e.messages.forEach(r=>{if(r.role!=="system"){if(Array.isArray(r.content)){let s=r.content.map(a=>this.normalizeRequestContent(a,r.role)).filter(a=>a!==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 e.json();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(),a="";try{let{value:f,done:_}=await s.read();!_&&f&&(a=new TextDecoder().decode(f))}finally{s.releaseLock()}if(o.cancel().catch(()=>{}),a.includes("message_start")||a.includes("content_block_start")){let f=this.prependToStream(a,r);return new Response(f,{status:e.status,statusText:e.statusText,headers:e.headers})}if(a.includes("response.created")||a.includes("response.output_text.delta")||a.includes("response.in_progress")||a.includes("response.output_item.added")){let f=this.prependToStream(a,r);return new Response(f,{status:e.status,statusText:e.statusText,headers:e.headers})}let i=this.prependToStream(a,r),u=new TextDecoder,d=new TextEncoder,m="",g=!1,y=this,p=new ReadableStream({async start(f){let _=i.getReader(),k=-1,h="",b=x=>(x!==h&&(k++,h=x),k);try{for(;;){let{done:x,value:v}=await _.read();if(x){g||f.enqueue(d.encode(`data: [DONE]
|
|
4
|
+
`);a=i.pop()||"";for(let u of i)u.trim()&&(s<o.maxStreamChunks?Cr(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++)}a.trim()&&(s<o.maxStreamChunks&&Cr(e,t,s,a.trim()),s++),Tr(e,t,s)}catch(a){console.error(`[debug_log] Error reading debug stream for reqId=${t}:`,a),Tr(e,t,s)}finally{r.releaseLock()}})()}var Ia,Ce,jn,We=S(()=>{"use strict";Ia=new Set(["authorization","x-api-key","x-goog-api-key","cookie","set-cookie"]),Ce={maxBodyLength:4096,maxStreamChunks:100},jn=!1});function Pr(n,e,t,o,r){let s=new Headers({"Content-Type":"application/json"});t.headers&&Object.entries(t.headers).forEach(([i,u])=>{u&&s.set(i,u)});let a,l=AbortSignal.timeout(t.TIMEOUT??60*1e3*60);if(t.signal){let i=new AbortController,u=()=>i.abort();t.signal.addEventListener("abort",u),l.addEventListener("abort",u),a=i.signal}else a=l;let c={method:"POST",headers:s,body:JSON.stringify(e),signal:a};return t.httpsProxy&&(c.dispatcher=G(t.httpsProxy)),r?.debug({reqId:o.req.id,method:"POST",headers:Tt(Object.fromEntries(s.entries())),requestUrl:typeof n=="string"?n:n.toString(),useProxy:$a(t.httpsProxy)},"final request"),fetch(typeof n=="string"?n:n.toString(),c)}function $a(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 Ar=S(()=>{te();We()});var Rt,Hn=S(()=>{Rt="2.3.236"});var Or={};Fn(Or,{getFallbackPromotionStore:()=>Te,resetFallbackPromotionStore:()=>Fa});function Te(n){return ge||(ge=new Jn,n&&ge.configure(n)),ge}function Fa(){ge&&(ge.clearAll(),ge=null)}var La,Jn,ge,wt=S(()=>{"use strict";ne();La=600*1e3,Jn=class{promotions=new Map;enabled=!0;ttlMs=La;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,a){if(!this.enabled)return;let l=this.getKey(e,t,o),c=`${r},${s}`;this.promotions.set(l,{promotedModel:c,timestamp:Date.now(),ttlMs:a??this.ttlMs})}getPromotion(e,t,o,r){if(!this.enabled)return null;let s=this.getKey(e,t,o),a=this.promotions.get(s);if(!a)return null;if(Date.now()-a.timestamp>=a.ttlMs)return this.promotions.delete(s),null;let[c,...i]=a.promotedModel.split(","),u=i.join(",");if(!U().isAvailable(c,u))return this.promotions.delete(s),null;let m=r.find(y=>y.name.toLowerCase()===c.toLowerCase()),g=m?.models?.find(y=>String(y).toLowerCase()===u.toLowerCase());return!m||!g||m.enabled===!1?(this.promotions.delete(s),null):`${m.name},${g}`}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}},ge=null});import{existsSync as Mr,mkdirSync as Ua,readFileSync as Da,writeFileSync as ja}from"fs";import{join as $r}from"path";import{HOME_DIR as za}from"@wengine-ai/claude-code-router-shared";function Wa(n){try{if(!Mr(Gn))return;let e=JSON.parse(Da(Gn,"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 Ir(n){try{let e=n.getAllStates();if(e.length===0)return;Mr(Wn)||Ua(Wn,{recursive:!0});let t=e.map(o=>({...o,updatedAt:Date.now()}));ja(Gn,JSON.stringify(t,null,2),"utf-8")}catch{}}function Vn(){if(Er)return;Er=!0;let n=U();Wa(n),Ba=setInterval(()=>Ir(n),6e4),process.on("exit",()=>Ir(n))}function U(n){return Bn||(Bn=new St(n)),Bn}var Ha,Ja,St,Wn,Gn,Er,Ba,Bn,ne=S(()=>{"use strict";Ha=120,Ja={enabled:!0,failureThreshold:3,probeIntervalMinutes:5,halfOpenSuccessThreshold:2},St=class{states=new Map;config;probeTimer;constructor(e){this.config={...Ja,...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}=(wt(),va(Or));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 a=this.states.get(s);a?(a.status="open",a.lastFailureTime=Date.now(),a.lastError=r||"rate-limited",a.lastProbeTime=0):(a={provider:e,model:t,status:"open",failureCount:0,successCount:0,lastFailureTime:Date.now(),lastProbeTime:0,lastError:r||"rate-limited"},this.states.set(s,a));let l=(o??Ha)*1e3;a.rateLimitUntil=Date.now()+l}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)}},Wn=$r(za,"runtime"),Gn=$r(Wn,"provider-health.json"),Er=!1,Ba=null;Bn=null});import{existsSync as Dr,mkdirSync as Ga,readFileSync as Va,writeFileSync as Qa}from"fs";import{join as jr}from"path";import{HOME_DIR as Ka}from"@wengine-ai/claude-code-router-shared";function Ge(n,e,t){let o=l=>{if(t instanceof Headers)return t.get(l);let c=Object.keys(t).find(i=>i.toLowerCase()===l);return c?t[c]:null},r=Qn(o,Xa),s=Qn(o,Ya),a=Qn(o,qa);(r||s||a)&&ve.set(n,{provider:n,remaining:Fr(r),limit:Fr(s),reset:ec(a),capturedAt:Date.now()})}function Za(n){return ve.get(n)}function Yn(){return Array.from(ve.values())}function Qn(n,e){for(let t of e){let o=n(t);if(o)return o}return null}function Fr(n){if(!n)return null;let e=Number(n.trim().replace(/,/g,""));return Number.isFinite(e)?e:null}function ec(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=tc(e);return r===null?null:Math.floor((Date.now()+r)/1e3)}function tc(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]),a=r[2].toLowerCase();if(Number.isFinite(s))switch(a){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 nc(){try{if(!Dr(Xn))return;let n=JSON.parse(Va(Xn,"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;ve.set(t.provider,t)}}catch{}}function Ur(){try{if(ve.size===0)return;Dr(Kn)||Ga(Kn,{recursive:!0}),Qa(Xn,JSON.stringify(Array.from(ve.values()),null,2),"utf-8")}catch{}}function Ve(){Nr||(Nr=!0,nc(),Lr=setInterval(Ur,6e4),Lr.unref?.(),process.on("exit",Ur))}var Kn,Xn,ve,Nr,Lr,Xa,Ya,qa,Re=S(()=>{"use strict";Kn=jr(Ka,"runtime"),Xn=jr(Kn,"rate-limit.json"),ve=new Map,Nr=!1,Lr=null,Xa=["x-ratelimit-remaining-tokens","x-ratelimit-remaining-requests","x-ratelimit-remaining"],Ya=["x-ratelimit-limit-tokens","x-ratelimit-limit-requests","x-ratelimit-limit"],qa=["x-ratelimit-reset-tokens","x-ratelimit-reset-requests","x-ratelimit-reset"]});var we,qn=S(()=>{"use strict";we=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 a="";typeof s=="string"?a=s:s&&typeof s=="object"&&"text"in s&&(a=s.text),t.push({role:"system",content:a})}):e.instructions=r.content}if(e.messages.forEach(r=>{if(r.role!=="system"){if(Array.isArray(r.content)){let s=r.content.map(a=>this.normalizeRequestContent(a,r.role)).filter(a=>a!==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 e.json();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(),a="";try{let{value:f,done:_}=await s.read();!_&&f&&(a=new TextDecoder().decode(f))}finally{s.releaseLock()}if(o.cancel().catch(()=>{}),a.includes("message_start")||a.includes("content_block_start")){let f=this.prependToStream(a,r);return new Response(f,{status:e.status,statusText:e.statusText,headers:e.headers})}if(a.includes("response.created")||a.includes("response.output_text.delta")||a.includes("response.in_progress")||a.includes("response.output_item.added")){let f=this.prependToStream(a,r);return new Response(f,{status:e.status,statusText:e.statusText,headers:e.headers})}let i=this.prependToStream(a,r),u=new TextDecoder,d=new TextEncoder,m="",g=!1,y=this,p=new ReadableStream({async start(f){let _=i.getReader(),k=-1,h="",b=x=>(x!==h&&(k++,h=x),k);try{for(;;){let{done:x,value:v}=await _.read();if(x){g||f.enqueue(d.encode(`data: [DONE]
|
|
5
5
|
|
|
6
6
|
`));break}let C=u.decode(v,{stream:!0});m+=C;let R=m.split(/\r?\n/);m=R.pop()||"";for(let T of R)if(T.trim())try{if(T.startsWith("event: "))continue;if(T.startsWith("data: ")){let A=T.slice(5).trim();if(A==="[DONE]"){g=!0,f.enqueue(d.encode(`data: [DONE]
|
|
7
7
|
|
|
@@ -39,13 +39,13 @@ data: ${JSON.stringify(N)}
|
|
|
39
39
|
`),T=(E,N=[])=>({id:a,object:"response",created_at:Math.floor(Date.now()/1e3),status:E,model:s,output:N,usage:this.buildResponsesUsage()}),A=()=>{k||(k=!0,P.enqueue(R("response.created",{type:"response.created",response:T("in_progress")})),P.enqueue(R("response.in_progress",{type:"response.in_progress",response:T("in_progress")})))},w=(E,N)=>{P.enqueue(R("response.output_item.done",{type:"response.output_item.done",output_index:E,item:{...N,status:"completed"}}))},O=E=>{if(!x){if(x=!0,h){let N=C.find(F=>F.type==="message");N&&(N.content=[{type:"output_text",text:l}],N.status="completed")}for(let N of C)N.type==="function_call"&&(N.status="completed");return R("response.completed",{type:"response.completed",response:{id:a,object:"response",created_at:Math.floor(Date.now()/1e3),status:"completed",model:s,output:C,usage:E?{...this.buildResponsesUsage(E)}:this.buildResponsesUsage()}})}},P;return new ReadableStream({async start(E){P=E;try{let N=e.getReader(),F="";for(;;){let{done:$,value:L}=await N.read();if($)break;F+=o.decode(L,{stream:!0});let W=F.split(`
|
|
40
40
|
`);F=W.pop()||"";for(let me of W){let D=me.trim();if(!D||D.startsWith("event:")||!D.startsWith("data:"))continue;let K=D.slice(5).trim();if(K==="[DONE]")continue;let H;try{H=JSON.parse(K)}catch{continue}if(H.type==="message_start"&&(a=H.message?.id||a,A()),H.type==="content_block_start"){let I=H.content_block;if(v=I?.type||null,I?.type==="tool_use"){u=I.id||"",d=I.name||"",m="",g=_++;let J={id:u,type:"function_call",status:"in_progress",call_id:u,name:d,arguments:""};C.push(J),P.enqueue(R("response.output_item.added",{type:"response.output_item.added",output_index:g,item:J}))}if(I?.type==="thinking"&&(y=I.thinking||"",!b)){b=!0,f=_++,p=`rs_${a}`;let J={id:p,type:"reasoning",status:"in_progress",summary:[]};C.push(J),P.enqueue(R("response.output_item.added",{type:"response.output_item.added",output_index:f,item:J}))}if(I?.type==="text"&&(l=I?.text||"",!h)){h=!0,i=_++,c=`${a}_msg`;let J={id:c,type:"message",status:"in_progress",role:"assistant",content:[]};C.push(J),P.enqueue(R("response.output_item.added",{type:"response.output_item.added",output_index:i,item:J}))}}if(H.type==="content_block_delta"){let I=H.delta;if(I?.type==="text_delta"){if(!h){h=!0,i=_++,c=`${a}_msg`;let J={id:c,type:"message",status:"in_progress",role:"assistant",content:[]};C.push(J),P.enqueue(R("response.output_item.added",{type:"response.output_item.added",output_index:i,item:J}))}l+=I.text||"",P.enqueue(R("response.output_text.delta",{type:"response.output_text.delta",item_id:c,output_index:i,content_index:0,delta:I.text||""}))}I?.type==="thinking_delta"&&(y+=I.thinking||"",P.enqueue(R("response.reasoning_summary_text.delta",{type:"response.reasoning_summary_text.delta",item_id:p||`rs_${a}`,output_index:f>=0?f:0,summary_index:0,delta:I.thinking||""}))),I?.type==="input_json_delta"&&(m+=I.partial_json||"",P.enqueue(R("response.function_call_arguments.delta",{type:"response.function_call_arguments.delta",item_id:u||"call_0",output_index:g>=0?g:0,delta:I.partial_json||""})))}if(H.type==="content_block_stop"){if(v==="tool_use"&&u){P.enqueue(R("response.function_call_arguments.done",{type:"response.function_call_arguments.done",item_id:u,output_index:g,arguments:m}));let I=C.find(J=>J.call_id===u);I&&(I.arguments=m,I.status="completed"),I&&w(g,I)}if(v==="text"&&h){P.enqueue(R("response.output_text.done",{type:"response.output_text.done",item_id:c,output_index:i,content_index:0,text:l}));let I=C.find(J=>J.type==="message");I&&(I.content=[{type:"output_text",text:l}],w(i,I))}if(v==="thinking"&&b){let I=C.find(J=>J.type==="reasoning");I&&(I.summary=[{type:"summary_text",text:y}],w(f,I))}v=null}if(H.type==="message_delta"){let I=O(H.usage);I&&P.enqueue(I)}if(H.type==="message_stop"){let I=O();I&&P.enqueue(I),P.enqueue(r.encode(`data: [DONE]
|
|
41
41
|
|
|
42
|
-
`))}}}A();let z=O();z&&P.enqueue(z),F="",P.close()}catch(N){P.error(N)}}})}wrapChatInResponses(e){let t=e?.choices?.[0],o=[],r=[];if(t?.message?.content&&r.push({type:"output_text",text:t.message.content}),o.push({type:"message",role:"assistant",content:r}),Array.isArray(t?.message?.tool_calls))for(let s of t.message.tool_calls)o.push({type:"function_call",id:s.id,call_id:s.id,name:s.function?.name||"",arguments:s.function?.arguments||"{}"});return{id:e.id||`resp_${Date.now()}`,object:"response",model:e.model,output:o,usage:e.usage?{...this.buildResponsesUsage(e.usage)}:void 0}}convertResponseToChat(e){let t=e.output?.find(i=>i.type==="message"),o=e.output?.find(i=>i.type==="function_call"),r;t?.content?.length&&t?.content[0].annotations&&(r=t.content[0].annotations.map(i=>({type:"url_citation",url_citation:{url:i.url||"",title:i.title||"",content:"",start_index:i.start_index||0,end_index:i.end_index||0}}))),this.logger.debug({data:r,type:"url_citation"});let s=null,a=null,l=null;if(t&&t.reasoning&&(l={content:t.reasoning}),t&&t.content){let i=[],u=[];if(t.content.forEach(d=>{if(d.type==="output_text")i.push(d.text||"");else if(d.type==="output_image"){let m=this.buildImageContent({url:d.image_url,mime_type:d.mime_type});m&&u.push(m)}else if(d.type==="output_image_base64"){let m=this.buildImageContent({b64_json:d.image_base64,mime_type:d.mime_type});m&&u.push(m)}}),u.length>0){let d=[];i.length>0&&d.push({type:"text",text:i.join("")}),d.push(...u),s=d}else s=i.join("")}return o&&(a=[{id:o.call_id||o.id,function:{name:o.name,arguments:o.arguments},type:"function"}]),{id:e.id||"chatcmpl-"+Date.now(),object:"chat.completion",created:e.created_at,model:e.model,choices:[{index:0,message:{role:"assistant",content:s||null,tool_calls:a,thinking:l,annotations:r},logprobs:null,finish_reason:a?"tool_calls":"stop"}],usage:e.usage?{prompt_tokens:e.usage.input_tokens||0,completion_tokens:e.usage.output_tokens||0,total_tokens:e.usage.total_tokens||0,prompt_tokens_details:{cached_tokens:this.getCacheReadInputTokens(e.usage),cache_creation_tokens:this.getCacheCreationInputTokens(e.usage)},cache_read_input_tokens:this.getCacheReadInputTokens(e.usage),cache_creation_input_tokens:this.getCacheCreationInputTokens(e.usage)}:null}}buildImageContent(e){return e&&(e.url||e.b64_json)?{type:"image_url",image_url:{url:e.url||"",b64_json:e.b64_json},media_type:e.mime_type}:null}}});var Zn,X,Pt=S(()=>{"use strict";Zn=class{capacity;cache;constructor(e){this.capacity=e,this.cache=new Map}get(e){if(!this.cache.has(e))return;let t=this.cache.get(e);return this.cache.delete(e),this.cache.set(e,t),t}put(e,t){if(this.cache.has(e))this.cache.delete(e);else if(this.cache.size>=this.capacity){let o=this.cache.keys().next().value;o!==void 0&&this.cache.delete(o)}this.cache.set(e,t)}values(){return Array.from(this.cache.values())}delete(e){return this.cache.delete(e)}},X=new Zn(100)});import{existsSync as Br,mkdirSync as rc,readFileSync as sc,writeFileSync as ic}from"fs";import{join as Wr}from"path";import{HOME_DIR as ac}from"@wengine-ai/claude-code-router-shared";function no(n,e){n&&we.set(n,{...e,provider:n,capturedAt:Date.now()})}function At(n){let e=we.get(n);return e?{...e}:void 0}function oo(){return Array.from(we.values()).map(n=>({...n}))}function cc(){try{if(!Br(to))return;let n=JSON.parse(sc(to,"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>1440*60*1e3)continue;we.set(t.provider,t)}}catch{}}function Jr(){try{if(we.size===0)return;Br(eo)||rc(eo,{recursive:!0}),ic(to,JSON.stringify(Array.from(we.values()),null,2),"utf-8")}catch{}}function Qe(){zr||(zr=!0,cc(),Hr=setInterval(Jr,6e4),Hr.unref?.(),process.on("exit",Jr))}var eo,to,we,zr,Hr,Se=S(()=>{"use strict";eo=Wr(ac,"runtime"),to=Wr(eo,"quota-store.json"),we=new Map,zr=!1,Hr=null});function Pe(n){if(typeof n!="string")return;let e=n.trim();if(!(!e||!lc.test(e)))return e}function Ke(n){if(!n)return;if(typeof n=="object")return Pe(n.session_id??n.sessionId);if(typeof n!="string")return;let e=n.trim();if(!e)return;try{let r=JSON.parse(e),s=Pe(r?.session_id??r?.sessionId);if(s)return s}catch{}let t="_session_",o=e.lastIndexOf(t);if(o!==-1)return Pe(e.slice(o+t.length))}var lc,Xe=S(()=>{"use strict";lc=/^[A-Za-z0-9_-]+$/});import{randomUUID as uc}from"node:crypto";import{readFileSync as dc,statSync as pc}from"node:fs";import{homedir as Gr}from"node:os";import{join as Qr}from"node:path";import{getContextWindow as fc}from"@wengine-ai/claude-code-router-shared";function Ae(n){return!!n&&typeof n=="object"&&!Array.isArray(n)}function hc(n){if(typeof n=="string")return n.slice(0,1e3);if(Array.isArray(n)){let e=n.find(t=>t&&typeof t.text=="string");return e?String(e.text).slice(0,1e3):""}return""}function yc(n){if(typeof n?.pathname=="string")return n.pathname;if(typeof n?.url!="string")return"";try{return new URL(n.url,"http://127.0.0.1").pathname}catch{return n.url}}function ro(n){return typeof n!="string"?"":(n.includes(",")&&n.split(",").pop()||n).trim().replace(/\[1m\]$/i,"").toLowerCase()}function _c(n){if(typeof n=="number"&&Number.isFinite(n)&&n>0)return Math.floor(n);if(typeof n=="string"&&/^\d+$/.test(n.trim())){let e=Number.parseInt(n.trim(),10);return e>0?e:void 0}}function kc(n){return n==="~"?Gr():n.startsWith("~/")?Qr(Gr(),n.slice(2)):n}function Kr(n,e){let t=Ae(n?.Clients)?n.Clients:{};return Ae(t[e])?t[e]:{}}function bc(n){let e;try{e=pc(n)}catch{Ye.delete(n);return}let t=Ye.get(n);if(t&&t.mtimeMs===e.mtimeMs&&t.size===e.size)return t;try{let o=JSON.parse(dc(n,"utf8")),r=Ae(o?.providers)&&Ae(o.providers.ccr)?o.providers.ccr:void 0,s=Array.isArray(r?.models)?r.models:[],a=new Map,l;for(let i of s){if(!Ae(i))continue;let u=_c(i.contextWindow);u&&(l||(l=u),typeof i.id=="string"&&i.id.trim()&&a.set(ro(i.id),u))}let c={mtimeMs:e.mtimeMs,size:e.size,contextWindows:a,firstContextWindow:l};return Ye.set(n,c),c}catch{Ye.delete(n);return}}function xc(n,e){let t=Kr(e,"pi"),o=kc(t.configPath||"~/.pi/agent"),r=bc(Qr(o,"models.json")),s=ro(n?.originalModel||n?.body?.model),a=ro(t.modelAlias||"ccr-opus");return(s?r?.contextWindows.get(s):void 0)||(a?r?.contextWindows.get(a):void 0)||r?.firstContextWindow||fc(e)}function Cc(n){let e=Kr(n,"pi").routing;if(e===void 0)return{extendedContextRatio:Vr};if(!Ae(e))throw new Error("Clients.pi.routing must be an object");for(let r of Object.keys(e))if(!gc.has(r))throw new Error(`Clients.pi.routing contains unsupported field: ${r}`);return{extendedContextRatio:((r,s)=>{let a=e[r];if(a===void 0)return s;if(typeof a!="number"||!Number.isFinite(a)||a<=0||a>1)throw new Error(`Clients.pi.routing.${r} must be a finite number greater than 0 and at most 1`);return a})("extendedContextRatio",Vr)}}function qe(n,e=!0){return{clientType:n,usageScope:"request",supportsExplicitExtendedContext:e}}function Xr(n,e,t=!0){let o=Ke(n?.body?.metadata?.user_id);return{clientType:e,usageScope:o?"session":"request",stableSessionId:o,supportsExplicitExtendedContext:t}}function qr(n){return typeof n=="string"&&mc.includes(n)}function he(n){if(qr(n?.clientType))return n.clientType;let e=yc(n),t=n?.headers||{},o=typeof t["user-agent"]=="string"?t["user-agent"]:"",r=n?.body||{},s=hc(r.system);if(/\bYou are Qwen Code\b/i.test(s)||/Qwen Code, an interactive CLI agent/i.test(s))return"qwen-code";if(/operating inside pi\b/i.test(s)||/a coding agent harness/i.test(s))return"pi";if(/\bYou are opencode\b/i.test(s))return"opencode";let a=t["x-anthropic-billing-header"];if(typeof a=="string"&&a.includes("cc_version="))return"claude-code";if(o.includes("codex")||o.includes("Codex")||e.endsWith("/v1/responses"))return"codex";if(r.metadata&&typeof r.metadata=="object"&&typeof r.metadata.user_id=="string")return"claude-code";if(o.includes("opencode"))return"opencode";if(o.includes("pi-coding-agent"))return"pi";if(o.includes("QwenCode"))return"qwen-code";let l=n?.originalModel||r.model||"";return/^ccr-(opus|sonnet|haiku)(\[1m\])?$/i.test(l)?o.includes("Anthropic/")?"pi":o.includes("claude-cli")||o.includes("Claude-CLI")?"qwen-code":typeof t["x-stainless-package-version"]=="string"?"pi":"claude-code":o.includes("claude-cli")||o.includes("Claude-CLI")?"claude-code":String(l).toLowerCase()==="ccr-codex"?"codex":e.endsWith("/v1/messages")?"api":"unknown"}function Zr(n){return Yr[n]}function Oc(n){if(typeof n?.__ccrRequestScopeId=="string"&&n.__ccrRequestScopeId)return n.__ccrRequestScopeId;let e=typeof n?.id=="string"&&n.id||uc();return n.__ccrRequestScopeId=e,e}function ye(n,e={}){let t=he(n),o=Zr(t).createContext(n,e),r=o.stableSessionId||Oc(n),s=o.usageScope==="session"?"session":"request";return n.clientType=t,n.clientContext=o,o.stableSessionId?n.sessionId=o.stableSessionId:delete n.sessionId,n.usageSessionId=r,n.usageCacheKey=`${t}:${s}:${r}`,o}function Ec(){Ye.clear()}var mc,Vr,gc,Ye,Tc,vc,Rc,wc,Sc,Pc,Ac,Yr,Oe=S(()=>{"use strict";Xe();mc=["claude-code","pi","qwen-code","opencode","codex","api","unknown"],Vr=.8,gc=new Set(["extendedContextRatio"]),Ye=new Map;Tc={type:"claude-code",createContext(n){return Xr(n,"claude-code")}},vc={type:"pi",createContext(n,e){let t=xc(n,e),o=Cc(e);return{...qe("pi",!1),contextWindow:t,extendedContextThreshold:Math.max(1,Math.floor(t*o.extendedContextRatio))}}},Rc={type:"qwen-code",createContext(n){return Xr(n,"qwen-code")}},wc={type:"opencode",createContext(){return qe("opencode")}},Sc={type:"codex",createContext(){return qe("codex")}},Pc={type:"api",createContext(){return qe("api")}},Ac={type:"unknown",createContext(){return qe("unknown")}},Yr={"claude-code":Tc,pi:vc,"qwen-code":Rc,opencode:wc,codex:Sc,api:Pc,unknown:Ac}});import{get_encoding as Ic}from"tiktoken";import{readFile as so}from"fs/promises";import{opendir as Mc,stat as $c}from"fs/promises";import{join as io}from"path";import{CLAUDE_PROJECTS_DIR as es,HOME_DIR as ts}from"@wengine-ai/claude-code-router-shared";function Y(n,e,t,o){let r=as(e,t),s=n.sessionId||n.clientContext?.stableSessionId,a=ss[r.code]||502;throw new ae(`Project routing error (${o}): ${r.reason}. Project-level Router target: "${e}". Session: "${s||"unknown"}".`,{sessionId:s,configuredTarget:e,code:r.code,statusCode:a})}function Et(n){let e=n||"";return e.includes(",")&&(e=e.split(",").pop()||e),e.includes("/")&&(e=e.split("/").pop()||e),e.includes(":")&&(e=e.split(":")[0]),e.trim().toLowerCase()}function is(n){let e=Et(n),t=e.includes("[1m]")||e.endsWith("[1m"),o=e.replace(/\[1m\]|\[1m$/g,""),r=o.match(/^ccr-(opus|sonnet|haiku)$/i);if(r)return{family:r[1].toLowerCase(),extended:t,isCcrAlias:!0};let s=o.match(/claude-(?:\d+-\d+-|\d+-)?(sonnet|opus|haiku)(?:-|$)/i)||o.match(/claude-(sonnet|opus|haiku)(?:-|$)/i);return s?{family:s[1].toLowerCase(),extended:t,isCcrAlias:!1}:{family:null,extended:t,isCcrAlias:!1}}function Lc(n,e){if(!e||!n)return null;let t=Et(n);if(e[n])return e[n];if(e[t])return e[t];let{family:o}=is(n);if(o&&e[o])return e[o];for(let[r,s]of Object.entries(e)){let a=Et(r);if(a&&t.includes(a))return s}return null}function Fc(n){return n?(n.input_tokens||0)+(n.cache_read_input_tokens||0)+(n.cache_creation_input_tokens||0):0}function Ot(n){if(!n?.includes(","))return null;let[e,...t]=n.split(","),o=e.trim(),r=t.join(",").trim();return!o||!r?null:{providerName:o,routeModel:r}}function Ze(n,e,t){let o=n.find(s=>s.name.toLowerCase()===e.toLowerCase());if(!o||o.enabled===!1)return null;let r=o.models?.find(s=>String(s).toLowerCase()===t.toLowerCase());return r?{provider:o,model:String(r)}:null}function as(n,e){let t=Ot(n);if(!t)return{reason:`invalid model format "${n}" (expected "provider,model")`,code:"invalid_model_format"};let{providerName:o,routeModel:r}=t,s=e.find(i=>i.name?.toLowerCase()===o.toLowerCase());if(!s)return{reason:`provider "${o}" not found`,code:"provider_not_found"};if(s.enabled===!1)return{reason:`provider "${o}" is disabled`,code:"provider_disabled"};let a=s.models?.find(i=>String(i).toLowerCase()===r.toLowerCase());if(!a)return{reason:`model "${r}" not found in provider "${o}"`,code:"model_not_found"};if(!U().isAvailable(s.name,String(a)))return{reason:`model "${r}" in provider "${o}" is temporarily unavailable (health fail-pool)`,code:"model_unhealthy"};let c=At(s.name);if(c){let i=c.limitDaily!==void 0&&c.usedDailyBalance!==void 0&&c.usedDailyBalance>=c.limitDaily,u=c.totalBalance!==void 0&&c.usedBalance!==void 0&&c.usedBalance>=c.totalBalance;if(i||u)return{reason:`provider "${o}" quota is exhausted`,code:"quota_exhausted"}}return{reason:`unable to resolve model "${n}"`,code:"resolution_failed"}}function G(n,e,t,o,r,s,a){let l=Ot(n);if(!l)return a?null:n;let{providerName:c,routeModel:i}=l,u=Ze(e,c,i);if(!u){if(r===!0&&o&&!t&&s!==!1){let m=Ce(),g=m.getPromotion(c,i,o,e);if(g){let y=Ot(g);if(y){let p=Ze(e,y.providerName,y.routeModel);if(p)return`${p.provider.name},${p.model}`}m.clear(c,i,o)}}return null}if(r===!0&&o&&!t&&s!==!1){let m=Ce(),g=m.getPromotion(c,i,o,e);if(g){let y=Ot(g);if(y){let p=Ze(e,y.providerName,y.routeModel);if(p)return`${p.provider.name},${p.model}`}m.clear(c,i,o)}}if(!t&&!U().isAvailable(u.provider.name,u.model))return null;let d=At(u.provider.name);if(d){let m=d.limitDaily!==void 0&&d.usedDailyBalance!==void 0&&d.usedDailyBalance>=d.limitDaily,g=d.totalBalance!==void 0&&d.usedBalance!==void 0&&d.usedBalance>=d.totalBalance;if(m||g)return null}return`${u.provider.name},${u.model}`}function Q(n,e,t,o,r,s){let a=U(),l=[t?.[n],o?.[n]];for(let c of l)if(!(!Array.isArray(c)||c.length===0))for(let i of c){let u=G(i,e,!1,n,void 0,void 0,s);if(u)return u}return null}function Uc(n){return n.body.messages?.some(e=>e.role==="user"&&Array.isArray(e.content)&&e.content.some(t=>t.type==="image"||t.type==="image_url"||Array.isArray(t?.content)&&t.content.some(o=>o.type==="image"||o.type==="image_url")))}function Dc(n){let e=Et(n);return[/claude/i,/gemini/i,/gpt-4o/i,/gpt-4\.1/i,/gpt-4-vision/i,/qwen.*vl/i,/glm-4v/i,/grok.*vision/i,/pixtral/i,/llava/i].some(o=>o.test(e))}function cs(n,e,t){return t?.usageScope!=="session"?n:Math.max(n,Fc(e))}function ls(n,e,t){return n?.extendedContextThreshold??e?.extendedContextThreshold??t??2e5}function jc(n,e,t,o,r,s,a,l,c,i,u,d){let m=n.clientContext,g=m?.longContextThreshold??t.longContextThreshold??c??6e4,y=cs(e,r,m),p=n.modelFamily,f=ls(m,t,i),_=m?.supportsExplicitExtendedContext!==!1&&s===!0;if((_||y>f)&&t.extendedContext){let b=G(t.extendedContext,o,!1,"extendedContext",l,d,u);if(b)return n.log.info(`Family: using extended context model (1M+), tokens: ${y}, estimated: ${e}, explicit: ${_}, threshold: ${f}`),{model:b,scenarioType:"extendedContext",isFallback:!1};let x=l?Q("extendedContext",o,t.fallback,a,p,u):null;if(x)return n.log.info(`Family: using extended context fallback model (1M+), tokens: ${y}, estimated: ${e}, explicit: ${_}, threshold: ${f}`),{model:x,scenarioType:"extendedContext",isFallback:!0};u&&Y(n,t.extendedContext,o,"extendedContext"),n.log.warn("Family: extendedContext model unavailable (fail pool), skipping")}if(y>g&&(t.longContext||t.fallback?.longContext?.length||a?.longContext?.length)){let b=t.longContext?G(t.longContext,o,!1,"longContext",l,d,u):null;if(b)return n.log.info(`Family: using long context model, tokens: ${y}, estimated: ${e}`),{model:b,scenarioType:"longContext",isFallback:!1};let x=l?Q("longContext",o,t.fallback,a,p,u):null;if(x)return n.log.info(`Family: using long context fallback model, tokens: ${y}, estimated: ${e}`),{model:x,scenarioType:"longContext",isFallback:!0};u&&t.longContext&&Y(n,t.longContext,o,"longContext"),n.log.warn("Family: no healthy longContext model available, falling through to other scenarios")}if(Array.isArray(n.body.tools)&&n.body.tools.some(b=>b.type?.startsWith("web_search"))&&t.webSearch){let b=G(t.webSearch,o,!1,"webSearch",l,d,u);if(b)return{model:b,scenarioType:"webSearch",isFallback:!1};let x=l?Q("webSearch",o,t.fallback,a,p,u):null;if(x)return n.log.info("Family: using webSearch fallback model"),{model:x,scenarioType:"webSearch",isFallback:!0};u&&Y(n,t.webSearch,o,"webSearch"),n.log.warn("Family: webSearch model unavailable (fail pool), skipping")}if(n.body.thinking?.type==="enabled"&&t.think){let b=G(t.think,o,!1,"think",l,d,u);if(b)return{model:b,scenarioType:"think",isFallback:!1};let x=l?Q("think",o,t.fallback,a,p,u):null;if(x)return n.log.info("Family: using think fallback model"),{model:x,scenarioType:"think",isFallback:!0};u&&Y(n,t.think,o,"think"),n.log.warn("Family: think model unavailable (fail pool), skipping")}if(t.default){let b=G(t.default,o,!1,"default",l,d,u);if(b)return{model:b,scenarioType:"default",isFallback:!1};let x=l?Q("default",o,t.fallback,a,p,u):null;if(x)return n.log.info("Family: using default fallback model"),{model:x,scenarioType:"default",isFallback:!0};u&&Y(n,t.default,o,"default"),n.log.warn("Family: default model unavailable (fail pool), skipping")}return null}function Wc(){if(_e.size<=ns)return;let n=[..._e.keys()].slice(0,_e.size-ns);for(let e of n)_e.delete(e)}function Gc(){if(Ee.size<=os)return;let n=[...Ee].slice(0,Ee.size-os);for(let e of n)Ee.delete(e)}var ss,ae,ie,It,Nc,zc,Mt,_e,ns,Ee,os,Hc,Jc,Bc,rs,us,et=S(()=>{"use strict";Pt();ee();Se();wt();Xe();Oe();ss={provider_not_found:404,model_not_found:404,invalid_model_format:400,provider_disabled:503,model_unhealthy:503,quota_exhausted:503,resolution_failed:502,project_config_error:500},ae=class extends Error{statusCode;code;type;sessionId;configuredTarget;constructor(e,t){super(e),this.name="ProjectRoutingError",this.statusCode=t?.statusCode||ss[t?.code||""]||502,this.code=t?.code||"project_routing_error",this.type="api_error",this.sessionId=t?.sessionId,this.configuredTarget=t?.configuredTarget}};ie=Ic("cl100k_base"),It=(n,e,t)=>{let o=0;return Array.isArray(n)&&n.forEach(r=>{typeof r.content=="string"?o+=ie.encode(r.content).length:Array.isArray(r.content)&&r.content.forEach(s=>{s.type==="text"?o+=ie.encode(s.text).length:s.type==="tool_use"?o+=ie.encode(JSON.stringify(s.input)).length:s.type==="tool_result"&&(o+=ie.encode(typeof s.content=="string"?s.content:JSON.stringify(s.content)).length)})}),typeof e=="string"?o+=ie.encode(e).length:Array.isArray(e)&&e.forEach(r=>{r.type==="text"&&(typeof r.text=="string"?o+=ie.encode(r.text).length:Array.isArray(r.text)&&r.text.forEach(s=>{o+=ie.encode(s||"").length}))}),t&&t.forEach(r=>{r.description&&(o+=ie.encode(r.name+r.description).length),r.input_schema&&(o+=ie.encode(JSON.stringify(r.input_schema)).length)}),o},Nc=async(n,e)=>{if(n.sessionId){let t=await us(n.sessionId);if(t){let o=io(ts,t,"config.json"),r=io(ts,t,`${n.sessionId}.json`);try{let s=JSON.parse(await so(r,"utf8"));if(s&&s.Router&&Object.keys(s.Router).length>0)return s.Router}catch{}try{let s=JSON.parse(await so(o,"utf8"));if(s&&s.Router&&Object.keys(s.Router).length>0)return s.Router}catch(s){if(s&&s.code!=="ENOENT"){let a=n.sessionId||n.clientContext?.stableSessionId;throw new ae(`Project routing error: project config.json is malformed or unreadable in project "${t}". ${s.message}. Session: "${a||"unknown"}".`,{sessionId:a,configuredTarget:o,code:"project_config_error",statusCode:500})}}}}};zc=async(n,e,t,o,r,s)=>{let a=t.get("providers")||[],l=r||t.get("Router"),c=l?.enableFallback===!0,i=c?l?.fallback:void 0,u=c&&!s?i||t.get("fallback"):i,d=!s,m=null;if(n.body?.system?.length>1&&n.body?.system[1]?.text?.includes("<CCR-SUBAGENT-MODEL>")){let C=n.body?.system[1].text.match(/<CCR-SUBAGENT-MODEL>(.*?)<\/CCR-SUBAGENT-MODEL>/s);C&&(n.body.system[1].text=n.body.system[1].text.replace(`<CCR-SUBAGENT-MODEL>${C[1]}</CCR-SUBAGENT-MODEL>`,""),m=C[1])}if(n.body.model.includes(",")&&!s){let C=G(n.body.model,a,!1,"default",c,d,s);if(C)return{model:C,scenarioType:"default"};n.log.warn(`Explicit model ${n.body.model} unavailable (fail pool), trying fallback`);let R=c?Q("default",a,void 0,u,void 0,s):null;if(R)return n.log.info(`Using fallback for explicit model: ${R}`),{model:R,scenarioType:"default"};n.log.warn(`No fallback available for explicit model ${n.body.model}, continuing through routing logic`)}let{family:g,extended:y,isCcrAlias:p}=is(n.body.model),f=l?.families?.[g||""];if(f&&l?.enableFamilyRouting){n.log.info(`Using model family routing for: ${g}${y?" (1M)":""}`),n.modelFamily=g,n.familyFallback=f.fallback;let C=jc(n,e,f,a,o,y,u,c,l?.longContextThreshold,l?.extendedContextThreshold,s,d);if(C)return{model:C.model,scenarioType:C.scenarioType}}let _=p&&!l?.enableFamilyRouting?null:Lc(n.body.model,l?.models);if(_){let C=G(_,a,!1,"modelMapping",c,d,s);if(C)return n.log.info(`Using mapped model for ${n.body.model}: ${_}`),{model:C,scenarioType:"modelMapping"};let R=c?Q("modelMapping",a,void 0,u,void 0,s):null;if(R)return{model:R,scenarioType:"modelMapping"};s&&Y(n,_,a,"modelMapping"),n.log.warn(`Mapped model ${_} unavailable (fail pool), skipping`)}let k=n.clientContext,h=cs(e,o,k),b=ls(k,void 0,l?.extendedContextThreshold);if(h>b&&l?.extendedContext){n.log.info(`Using extended context (1M) model due to token count: ${h}, estimated: ${e}, threshold: ${b}`);let C=G(l.extendedContext,a,!1,"extendedContext",c,d,s);if(C)return{model:C,scenarioType:"extendedContext"};n.log.warn(`Extended context model ${l.extendedContext} unavailable (fail pool), trying fallback`);let R=c?Q("extendedContext",a,void 0,u,void 0,s):null;if(R)return{model:R,scenarioType:"extendedContext"};s&&Y(n,l.extendedContext,a,"extendedContext")}let x=k?.longContextThreshold??l?.longContextThreshold??6e4;if(h>x&&l?.longContext){n.log.info(`Using long context model due to token count: ${h}, estimated: ${e}, threshold: ${x}`);let C=G(l.longContext,a,!1,"longContext",c,d,s);if(C)return{model:C,scenarioType:"longContext"};n.log.warn(`Long context model ${l.longContext} unavailable (fail pool), trying fallback`);let R=c?Q("longContext",a,void 0,u,void 0,s):null;if(R)return{model:R,scenarioType:"longContext"};s&&Y(n,l.longContext,a,"longContext")}if(!s&&m)return{model:m,scenarioType:"default"};if(n.body.model?.includes("claude")&&n.body.model?.includes("haiku")&&l?.background){n.log.info(`Using background model for ${n.body.model}`);let C=G(l.background,a,!1,"background",c,d,s);if(C)return{model:C,scenarioType:"background"};let R=c?Q("background",a,void 0,u,void 0,s):null;if(R)return{model:R,scenarioType:"background"};s&&Y(n,l.background,a,"background"),n.log.warn(`Background model ${l.background} unavailable (fail pool), falling through`)}if(Array.isArray(n.body.tools)&&n.body.tools.some(C=>C.type?.startsWith("web_search"))&&l?.webSearch){let C=G(l.webSearch,a,!1,"webSearch",c,d,s);if(C)return{model:C,scenarioType:"webSearch"};n.log.warn(`WebSearch model ${l.webSearch} unavailable (fail pool), trying fallback`);let R=c?Q("webSearch",a,void 0,u,void 0,s):null;if(R)return{model:R,scenarioType:"webSearch"};s&&Y(n,l.webSearch,a,"webSearch")}if(n.body.thinking?.type==="enabled"&&l?.think){n.log.info(`Using think model for ${n.body.thinking}`);let C=G(l.think,a,!1,"think",c,d,s);if(C)return{model:C,scenarioType:"think"};n.log.warn(`Think model ${l.think} unavailable (fail pool), trying fallback`);let R=c?Q("think",a,void 0,u,void 0,s):null;if(R)return{model:R,scenarioType:"think"};s&&Y(n,l.think,a,"think")}if(l?.default){let C=G(l.default,a,!1,"default",c,d,s);if(C)return{model:C,scenarioType:"default"};n.log.warn(`Default model ${l.default} unavailable (fail pool), trying fallback`);let R=c?Q("default",a,void 0,u,void 0,s):null;if(R)return{model:R,scenarioType:"default"};if(!s){let T=G(l.default,a,!0,"default",c,d,s);if(T)return n.log.warn(`No fallback available; retrying default model ${l.default} despite fail-pool state`),{model:T,scenarioType:"default"}}}return s&&Y(n,l?.default||n.body.model,a,"default"),{model:void 0,scenarioType:"default"}},Mt=async(n,e,t)=>{let{configService:o,event:r}=t;n.originalModel=n.body.model,ye(n,o.getAll());let s=await Nc(n,o),a=s||o.get("Router"),l=a?.enableFallback===!0,c=o.get("providers")||[],i=!!s;n.enableFallback=l,n.strictProjectRouting=i,n.fallbackConfig=i?a?.fallback:a?.fallback||o.get("fallback");let u=n.clientContext?.usageScope==="session"?n.previousUsage??X.get(n.usageCacheKey):void 0,{messages:d,system:m=[],tools:g}=n.body,y=o.get("REWRITE_SYSTEM_PROMPT");if(y&&m.length>1&&m[1]?.text?.includes("<env>")){let p=await so(y,"utf-8");m[1].text=`${p}<env>${m[1].text.split("<env>").pop()}`}try{let[p,f]=n.body.model.split(","),_=t.tokenizerService?.getTokenizerConfigForModel(p,f),k;t.tokenizerService?k=(await t.tokenizerService.countTokens({messages:d,system:m,tools:g},_,p)).tokenCount:k=It(d,m,g),n.tokenCount=k;let h,b=i?void 0:o.get("CUSTOM_ROUTER_PATH");if(b)try{h=await Be(b)(n,o.getAll(),{event:r})}catch(x){n.log.error(`failed to load custom router: ${x.message}`)}if(h)n.scenarioType="default";else{let x=await zc(n,k,o,u,s,!!s);h=x.model,n.scenarioType=x.scenarioType}if(a?.image&&h!==a.image&&Uc(n)&&!Dc(h)){let x=G(a.image,c,!1,"image",l,!i,i);if(x)n.log.info(`Using image model fallback for ${h}`),h=x,n.scenarioType="image";else{let v=l?Q("image",c,void 0,n.fallbackConfig,void 0,i):null;v?(n.log.info(`Using image fallback model: ${v}`),h=v,n.scenarioType="image"):i?Y(n,a.image,c,"image"):(n.log.warn(`Image model ${a.image} unavailable (fail pool), keeping ${h}`),n.scenarioType="image")}}typeof h=="string"&&h.trim()?n.body.model=h:(n.log.warn(`Router could not resolve a valid model for ${n.originalModel||n.body.model}; keeping original request model`),n.scenarioType=n.scenarioType||"default")}catch(p){if(p instanceof ae)throw p;if(n.log.error(`Error in router middleware: ${p.message}`),i){let f=n.sessionId||n.clientContext?.stableSessionId;throw new ae(`Project routing error: router failure in project mode. ${p.message}. Session: "${f||"unknown"}".`,{sessionId:f,configuredTarget:a?.default,code:"project_router_failure",statusCode:502})}n.body.model=a?.default,n.scenarioType="default"}},_e=new Map,ns=1e3,Ee=new Set,os=1e3,Hc=3,Jc=50,Bc=n=>new Promise(e=>setTimeout(e,n));rs=async n=>{let e=await Mc(es),t=[];for await(let s of e)s.isDirectory()&&t.push(s.name);let o=t.map(async s=>{let a=io(es,s,`${n}.jsonl`);try{return(await $c(a)).isFile()?s:null}catch{return null}}),r=await Promise.all(o);for(let s of r)if(s)return s;return null},us=async n=>{let e=Pe(n);if(!e)return null;if(_e.has(e))return _e.get(e)||null;try{let t=await rs(e);if(!t&&!Ee.has(e)){Ee.add(e),Gc();for(let o=0;o<Hc&&!t;o++)await Bc(Jc),t=await rs(e)}return t?(_e.set(e,t),Wc(),t):null}catch(t){return console.error("Error searching for project by session:",t),null}}});function tt(n){let e=[],t=Array.isArray(n.input)?n.input:[n.input];for(let o of t)if(o.type==="function_call")e.push({role:"assistant",tool_calls:[{id:o.call_id,type:"function",function:{name:o.name,arguments:o.arguments||"{}"}}]});else if(o.type==="function_call_output")e.push({role:"tool",tool_call_id:o.call_id,content:typeof o.output=="string"?o.output:JSON.stringify(o.output)});else if(o.type==="reasoning"){let r=Array.isArray(o.summary)?o.summary.filter(s=>s.type==="summary_text"&&s.text).map(s=>s.text).join(`
|
|
42
|
+
`))}}}A();let z=O();z&&P.enqueue(z),F="",P.close()}catch(N){P.error(N)}}})}wrapChatInResponses(e){let t=e?.choices?.[0],o=[],r=[];if(t?.message?.content&&r.push({type:"output_text",text:t.message.content}),o.push({type:"message",role:"assistant",content:r}),Array.isArray(t?.message?.tool_calls))for(let s of t.message.tool_calls)o.push({type:"function_call",id:s.id,call_id:s.id,name:s.function?.name||"",arguments:s.function?.arguments||"{}"});return{id:e.id||`resp_${Date.now()}`,object:"response",model:e.model,output:o,usage:e.usage?{...this.buildResponsesUsage(e.usage)}:void 0}}convertResponseToChat(e){let t=e.output?.find(i=>i.type==="message"),o=e.output?.find(i=>i.type==="function_call"),r;t?.content?.length&&t?.content[0].annotations&&(r=t.content[0].annotations.map(i=>({type:"url_citation",url_citation:{url:i.url||"",title:i.title||"",content:"",start_index:i.start_index||0,end_index:i.end_index||0}}))),this.logger.debug({data:r,type:"url_citation"});let s=null,a=null,l=null;if(t&&t.reasoning&&(l={content:t.reasoning}),t&&t.content){let i=[],u=[];if(t.content.forEach(d=>{if(d.type==="output_text")i.push(d.text||"");else if(d.type==="output_image"){let m=this.buildImageContent({url:d.image_url,mime_type:d.mime_type});m&&u.push(m)}else if(d.type==="output_image_base64"){let m=this.buildImageContent({b64_json:d.image_base64,mime_type:d.mime_type});m&&u.push(m)}}),u.length>0){let d=[];i.length>0&&d.push({type:"text",text:i.join("")}),d.push(...u),s=d}else s=i.join("")}return o&&(a=[{id:o.call_id||o.id,function:{name:o.name,arguments:o.arguments},type:"function"}]),{id:e.id||"chatcmpl-"+Date.now(),object:"chat.completion",created:e.created_at,model:e.model,choices:[{index:0,message:{role:"assistant",content:s||null,tool_calls:a,thinking:l,annotations:r},logprobs:null,finish_reason:a?"tool_calls":"stop"}],usage:e.usage?{prompt_tokens:e.usage.input_tokens||0,completion_tokens:e.usage.output_tokens||0,total_tokens:e.usage.total_tokens||0,prompt_tokens_details:{cached_tokens:this.getCacheReadInputTokens(e.usage),cache_creation_tokens:this.getCacheCreationInputTokens(e.usage)},cache_read_input_tokens:this.getCacheReadInputTokens(e.usage),cache_creation_input_tokens:this.getCacheCreationInputTokens(e.usage)}:null}}buildImageContent(e){return e&&(e.url||e.b64_json)?{type:"image_url",image_url:{url:e.url||"",b64_json:e.b64_json},media_type:e.mime_type}:null}}});var Zn,X,Pt=S(()=>{"use strict";Zn=class{capacity;cache;constructor(e){this.capacity=e,this.cache=new Map}get(e){if(!this.cache.has(e))return;let t=this.cache.get(e);return this.cache.delete(e),this.cache.set(e,t),t}put(e,t){if(this.cache.has(e))this.cache.delete(e);else if(this.cache.size>=this.capacity){let o=this.cache.keys().next().value;o!==void 0&&this.cache.delete(o)}this.cache.set(e,t)}values(){return Array.from(this.cache.values())}delete(e){return this.cache.delete(e)}},X=new Zn(100)});import{existsSync as Br,mkdirSync as oc,readFileSync as rc,writeFileSync as sc}from"fs";import{join as Wr}from"path";import{HOME_DIR as ic}from"@wengine-ai/claude-code-router-shared";function no(n,e){n&&Se.set(n,{...e,provider:n,capturedAt:Date.now()})}function At(n){let e=Se.get(n);return e?{...e}:void 0}function oo(){return Array.from(Se.values()).map(n=>({...n}))}function ac(){try{if(!Br(to))return;let n=JSON.parse(rc(to,"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>1440*60*1e3)continue;Se.set(t.provider,t)}}catch{}}function Jr(){try{if(Se.size===0)return;Br(eo)||oc(eo,{recursive:!0}),sc(to,JSON.stringify(Array.from(Se.values()),null,2),"utf-8")}catch{}}function Qe(){zr||(zr=!0,ac(),Hr=setInterval(Jr,6e4),Hr.unref?.(),process.on("exit",Jr))}var eo,to,Se,zr,Hr,Pe=S(()=>{"use strict";eo=Wr(ic,"runtime"),to=Wr(eo,"quota-store.json"),Se=new Map,zr=!1,Hr=null});function Ae(n){if(typeof n!="string")return;let e=n.trim();if(!(!e||!cc.test(e)))return e}function Ke(n){if(!n)return;if(typeof n=="object")return Ae(n.session_id??n.sessionId);if(typeof n!="string")return;let e=n.trim();if(!e)return;try{let r=JSON.parse(e),s=Ae(r?.session_id??r?.sessionId);if(s)return s}catch{}let t="_session_",o=e.lastIndexOf(t);if(o!==-1)return Ae(e.slice(o+t.length))}var cc,Xe=S(()=>{"use strict";cc=/^[A-Za-z0-9_-]+$/});import{randomUUID as lc}from"node:crypto";function dc(n){if(typeof n=="string")return n.slice(0,1e3);if(Array.isArray(n)){let e=n.find(t=>t&&typeof t.text=="string");return e?String(e.text).slice(0,1e3):""}return""}function pc(n){if(typeof n?.pathname=="string")return n.pathname;if(typeof n?.url!="string")return"";try{return new URL(n.url,"http://127.0.0.1").pathname}catch{return n.url}}function Ye(n,e=!0){return{clientType:n,usageScope:"request",supportsExplicitExtendedContext:e}}function Gr(n,e,t=!0){let o=Ke(n?.body?.metadata?.user_id);return{clientType:e,usageScope:o?"session":"request",stableSessionId:o,supportsExplicitExtendedContext:t}}function Qr(n){return typeof n=="string"&&uc.includes(n)}function he(n){if(Qr(n?.clientType))return n.clientType;let e=pc(n),t=n?.headers||{},o=typeof t["user-agent"]=="string"?t["user-agent"]:"",r=n?.body||{},s=dc(r.system);if(/\bYou are Qwen Code\b/i.test(s)||/Qwen Code, an interactive CLI agent/i.test(s))return"qwen-code";if(/operating inside pi\b/i.test(s)||/a coding agent harness/i.test(s))return"pi";if(/\bYou are opencode\b/i.test(s))return"opencode";let a=t["x-anthropic-billing-header"];if(typeof a=="string"&&a.includes("cc_version="))return"claude-code";if(o.includes("codex")||o.includes("Codex")||e.endsWith("/v1/responses"))return"codex";if(r.metadata&&typeof r.metadata=="object"&&typeof r.metadata.user_id=="string")return"claude-code";if(o.includes("opencode"))return"opencode";if(o.includes("pi-coding-agent"))return"pi";if(o.includes("QwenCode"))return"qwen-code";let l=n?.originalModel||r.model||"";return/^ccr-(opus|sonnet|haiku)(\[1m\])?$/i.test(l)?o.includes("Anthropic/")?"pi":o.includes("claude-cli")||o.includes("Claude-CLI")?"qwen-code":typeof t["x-stainless-package-version"]=="string"?"pi":"claude-code":o.includes("claude-cli")||o.includes("Claude-CLI")?"claude-code":String(l).toLowerCase()==="ccr-codex"?"codex":e.endsWith("/v1/messages")?"api":"unknown"}function Kr(n){return Vr[n]}function bc(n){if(typeof n?.__ccrRequestScopeId=="string"&&n.__ccrRequestScopeId)return n.__ccrRequestScopeId;let e=typeof n?.id=="string"&&n.id||lc();return n.__ccrRequestScopeId=e,e}function ye(n,e={}){let t=he(n),o=Kr(t).createContext(n,e),r=o.stableSessionId||bc(n),s=o.usageScope==="session"?"session":"request";return n.clientType=t,n.clientContext=o,o.stableSessionId?n.sessionId=o.stableSessionId:delete n.sessionId,n.usageSessionId=r,n.usageCacheKey=`${t}:${s}:${r}`,o}function xc(){}var uc,fc,mc,gc,hc,yc,_c,kc,Vr,Oe=S(()=>{"use strict";Xe();uc=["claude-code","pi","qwen-code","opencode","codex","api","unknown"];fc={type:"claude-code",createContext(n){return Gr(n,"claude-code")}},mc={type:"pi",createContext(){return Ye("pi",!1)}},gc={type:"qwen-code",createContext(n){return Gr(n,"qwen-code")}},hc={type:"opencode",createContext(){return Ye("opencode")}},yc={type:"codex",createContext(){return Ye("codex")}},_c={type:"api",createContext(){return Ye("api")}},kc={type:"unknown",createContext(){return Ye("unknown")}},Vr={"claude-code":fc,pi:mc,"qwen-code":gc,opencode:hc,codex:yc,api:_c,unknown:kc}});import{get_encoding as Cc}from"tiktoken";import{readFile as ro}from"fs/promises";import{opendir as Tc,stat as vc}from"fs/promises";import{join as so}from"path";import{CLAUDE_PROJECTS_DIR as Xr,HOME_DIR as Yr}from"@wengine-ai/claude-code-router-shared";function Y(n,e,t,o){let r=os(e,t),s=n.sessionId||n.clientContext?.stableSessionId,a=ts[r.code]||502;throw new ce(`Project routing error (${o}): ${r.reason}. Project-level Router target: "${e}". Session: "${s||"unknown"}".`,{sessionId:s,configuredTarget:e,code:r.code,statusCode:a})}function Et(n){let e=n||"";return e.includes(",")&&(e=e.split(",").pop()||e),e.includes("/")&&(e=e.split("/").pop()||e),e.includes(":")&&(e=e.split(":")[0]),e.trim().toLowerCase()}function ns(n){let e=Et(n),t=e.includes("[1m]")||e.endsWith("[1m"),o=e.replace(/\[1m\]|\[1m$/g,""),r=o.match(/^ccr-(opus|sonnet|haiku)$/i);if(r)return{family:r[1].toLowerCase(),extended:t,isCcrAlias:!0};let s=o.match(/claude-(?:\d+-\d+-|\d+-)?(sonnet|opus|haiku)(?:-|$)/i)||o.match(/claude-(sonnet|opus|haiku)(?:-|$)/i);return s?{family:s[1].toLowerCase(),extended:t,isCcrAlias:!1}:{family:null,extended:t,isCcrAlias:!1}}function wc(n,e){if(!e||!n)return null;let t=Et(n);if(e[n])return e[n];if(e[t])return e[t];let{family:o}=ns(n);if(o&&e[o])return e[o];for(let[r,s]of Object.entries(e)){let a=Et(r);if(a&&t.includes(a))return s}return null}function Sc(n){return n?(n.input_tokens||0)+(n.cache_read_input_tokens||0)+(n.cache_creation_input_tokens||0):0}function Ot(n){if(!n?.includes(","))return null;let[e,...t]=n.split(","),o=e.trim(),r=t.join(",").trim();return!o||!r?null:{providerName:o,routeModel:r}}function qe(n,e,t){let o=n.find(s=>s.name.toLowerCase()===e.toLowerCase());if(!o||o.enabled===!1)return null;let r=o.models?.find(s=>String(s).toLowerCase()===t.toLowerCase());return r?{provider:o,model:String(r)}:null}function os(n,e){let t=Ot(n);if(!t)return{reason:`invalid model format "${n}" (expected "provider,model")`,code:"invalid_model_format"};let{providerName:o,routeModel:r}=t,s=e.find(i=>i.name?.toLowerCase()===o.toLowerCase());if(!s)return{reason:`provider "${o}" not found`,code:"provider_not_found"};if(s.enabled===!1)return{reason:`provider "${o}" is disabled`,code:"provider_disabled"};let a=s.models?.find(i=>String(i).toLowerCase()===r.toLowerCase());if(!a)return{reason:`model "${r}" not found in provider "${o}"`,code:"model_not_found"};if(!U().isAvailable(s.name,String(a)))return{reason:`model "${r}" in provider "${o}" is temporarily unavailable (health fail-pool)`,code:"model_unhealthy"};let c=At(s.name);if(c){let i=c.limitDaily!==void 0&&c.usedDailyBalance!==void 0&&c.usedDailyBalance>=c.limitDaily,u=c.totalBalance!==void 0&&c.usedBalance!==void 0&&c.usedBalance>=c.totalBalance;if(i||u)return{reason:`provider "${o}" quota is exhausted`,code:"quota_exhausted"}}return{reason:`unable to resolve model "${n}"`,code:"resolution_failed"}}function V(n,e,t,o,r,s,a){let l=Ot(n);if(!l)return a?null:n;let{providerName:c,routeModel:i}=l,u=qe(e,c,i);if(!u){if(r===!0&&o&&!t&&s!==!1){let m=Te(),g=m.getPromotion(c,i,o,e);if(g){let y=Ot(g);if(y){let p=qe(e,y.providerName,y.routeModel);if(p)return`${p.provider.name},${p.model}`}m.clear(c,i,o)}}return null}if(r===!0&&o&&!t&&s!==!1){let m=Te(),g=m.getPromotion(c,i,o,e);if(g){let y=Ot(g);if(y){let p=qe(e,y.providerName,y.routeModel);if(p)return`${p.provider.name},${p.model}`}m.clear(c,i,o)}}if(!t&&!U().isAvailable(u.provider.name,u.model))return null;let d=At(u.provider.name);if(d){let m=d.limitDaily!==void 0&&d.usedDailyBalance!==void 0&&d.usedDailyBalance>=d.limitDaily,g=d.totalBalance!==void 0&&d.usedBalance!==void 0&&d.usedBalance>=d.totalBalance;if(m||g)return null}return`${u.provider.name},${u.model}`}function Q(n,e,t,o,r,s){let a=U(),l=[t?.[n],o?.[n]];for(let c of l)if(!(!Array.isArray(c)||c.length===0))for(let i of c){let u=V(i,e,!1,n,void 0,void 0,s);if(u)return u}return null}function Pc(n){return n.body.messages?.some(e=>e.role==="user"&&Array.isArray(e.content)&&e.content.some(t=>t.type==="image"||t.type==="image_url"||Array.isArray(t?.content)&&t.content.some(o=>o.type==="image"||o.type==="image_url")))}function Ac(n){let e=Et(n);return[/claude/i,/gemini/i,/gpt-4o/i,/gpt-4\.1/i,/gpt-4-vision/i,/qwen.*vl/i,/glm-4v/i,/grok.*vision/i,/pixtral/i,/llava/i].some(o=>o.test(e))}function rs(n,e,t){return t?.usageScope!=="session"?n:Math.max(n,Sc(e))}function ss(n,e,t){return n?.extendedContextThreshold??e?.extendedContextThreshold??t??2e5}function Oc(n,e,t,o,r,s,a,l,c,i,u,d){let m=n.clientContext,g=m?.longContextThreshold??t.longContextThreshold??c??6e4,y=rs(e,r,m),p=n.modelFamily,f=ss(m,t,i),_=m?.supportsExplicitExtendedContext!==!1&&s===!0;if((_||y>f)&&t.extendedContext){let b=V(t.extendedContext,o,!1,"extendedContext",l,d,u);if(b)return n.log.info(`Family: using extended context model (1M+), tokens: ${y}, estimated: ${e}, explicit: ${_}, threshold: ${f}`),{model:b,scenarioType:"extendedContext",isFallback:!1};let x=l?Q("extendedContext",o,t.fallback,a,p,u):null;if(x)return n.log.info(`Family: using extended context fallback model (1M+), tokens: ${y}, estimated: ${e}, explicit: ${_}, threshold: ${f}`),{model:x,scenarioType:"extendedContext",isFallback:!0};u&&Y(n,t.extendedContext,o,"extendedContext"),n.log.warn("Family: extendedContext model unavailable (fail pool), skipping")}if(y>g&&(t.longContext||t.fallback?.longContext?.length||a?.longContext?.length)){let b=t.longContext?V(t.longContext,o,!1,"longContext",l,d,u):null;if(b)return n.log.info(`Family: using long context model, tokens: ${y}, estimated: ${e}`),{model:b,scenarioType:"longContext",isFallback:!1};let x=l?Q("longContext",o,t.fallback,a,p,u):null;if(x)return n.log.info(`Family: using long context fallback model, tokens: ${y}, estimated: ${e}`),{model:x,scenarioType:"longContext",isFallback:!0};u&&t.longContext&&Y(n,t.longContext,o,"longContext"),n.log.warn("Family: no healthy longContext model available, falling through to other scenarios")}if(Array.isArray(n.body.tools)&&n.body.tools.some(b=>b.type?.startsWith("web_search"))&&t.webSearch){let b=V(t.webSearch,o,!1,"webSearch",l,d,u);if(b)return{model:b,scenarioType:"webSearch",isFallback:!1};let x=l?Q("webSearch",o,t.fallback,a,p,u):null;if(x)return n.log.info("Family: using webSearch fallback model"),{model:x,scenarioType:"webSearch",isFallback:!0};u&&Y(n,t.webSearch,o,"webSearch"),n.log.warn("Family: webSearch model unavailable (fail pool), skipping")}if(n.body.thinking?.type==="enabled"&&t.think){let b=V(t.think,o,!1,"think",l,d,u);if(b)return{model:b,scenarioType:"think",isFallback:!1};let x=l?Q("think",o,t.fallback,a,p,u):null;if(x)return n.log.info("Family: using think fallback model"),{model:x,scenarioType:"think",isFallback:!0};u&&Y(n,t.think,o,"think"),n.log.warn("Family: think model unavailable (fail pool), skipping")}if(t.default){let b=V(t.default,o,!1,"default",l,d,u);if(b)return{model:b,scenarioType:"default",isFallback:!1};let x=l?Q("default",o,t.fallback,a,p,u):null;if(x)return n.log.info("Family: using default fallback model"),{model:x,scenarioType:"default",isFallback:!0};u&&Y(n,t.default,o,"default"),n.log.warn("Family: default model unavailable (fail pool), skipping")}return null}function Nc(){if(_e.size<=qr)return;let n=[..._e.keys()].slice(0,_e.size-qr);for(let e of n)_e.delete(e)}function Lc(){if(Ee.size<=Zr)return;let n=[...Ee].slice(0,Ee.size-Zr);for(let e of n)Ee.delete(e)}var ts,ce,ae,It,Rc,Ec,Mt,_e,qr,Ee,Zr,Ic,Mc,$c,es,is,Ze=S(()=>{"use strict";Pt();ne();Pe();wt();Xe();Oe();ts={provider_not_found:404,model_not_found:404,invalid_model_format:400,provider_disabled:503,model_unhealthy:503,quota_exhausted:503,resolution_failed:502,project_config_error:500},ce=class extends Error{statusCode;code;type;sessionId;configuredTarget;constructor(e,t){super(e),this.name="ProjectRoutingError",this.statusCode=t?.statusCode||ts[t?.code||""]||502,this.code=t?.code||"project_routing_error",this.type="api_error",this.sessionId=t?.sessionId,this.configuredTarget=t?.configuredTarget}};ae=Cc("cl100k_base"),It=(n,e,t)=>{let o=0;return Array.isArray(n)&&n.forEach(r=>{typeof r.content=="string"?o+=ae.encode(r.content).length:Array.isArray(r.content)&&r.content.forEach(s=>{s.type==="text"?o+=ae.encode(s.text).length:s.type==="tool_use"?o+=ae.encode(JSON.stringify(s.input)).length:s.type==="tool_result"&&(o+=ae.encode(typeof s.content=="string"?s.content:JSON.stringify(s.content)).length)})}),typeof e=="string"?o+=ae.encode(e).length:Array.isArray(e)&&e.forEach(r=>{r.type==="text"&&(typeof r.text=="string"?o+=ae.encode(r.text).length:Array.isArray(r.text)&&r.text.forEach(s=>{o+=ae.encode(s||"").length}))}),t&&t.forEach(r=>{r.description&&(o+=ae.encode(r.name+r.description).length),r.input_schema&&(o+=ae.encode(JSON.stringify(r.input_schema)).length)}),o},Rc=async(n,e)=>{if(n.sessionId){let t=await is(n.sessionId);if(t){let o=so(Yr,t,"config.json"),r=so(Yr,t,`${n.sessionId}.json`);try{let s=JSON.parse(await ro(r,"utf8"));if(s&&s.Router&&Object.keys(s.Router).length>0)return s.Router}catch{}try{let s=JSON.parse(await ro(o,"utf8"));if(s&&s.Router&&Object.keys(s.Router).length>0)return s.Router}catch(s){if(s&&s.code!=="ENOENT"){let a=n.sessionId||n.clientContext?.stableSessionId;throw new ce(`Project routing error: project config.json is malformed or unreadable in project "${t}". ${s.message}. Session: "${a||"unknown"}".`,{sessionId:a,configuredTarget:o,code:"project_config_error",statusCode:500})}}}}};Ec=async(n,e,t,o,r,s)=>{let a=t.get("providers")||[],l=r||t.get("Router"),c=l?.enableFallback===!0,i=c?l?.fallback:void 0,u=c&&!s?i||t.get("fallback"):i,d=!s,m=null;if(n.body?.system?.length>1&&n.body?.system[1]?.text?.includes("<CCR-SUBAGENT-MODEL>")){let C=n.body?.system[1].text.match(/<CCR-SUBAGENT-MODEL>(.*?)<\/CCR-SUBAGENT-MODEL>/s);C&&(n.body.system[1].text=n.body.system[1].text.replace(`<CCR-SUBAGENT-MODEL>${C[1]}</CCR-SUBAGENT-MODEL>`,""),m=C[1])}if(n.body.model.includes(",")&&!s){let C=V(n.body.model,a,!1,"default",c,d,s);if(C)return{model:C,scenarioType:"default"};n.log.warn(`Explicit model ${n.body.model} unavailable (fail pool), trying fallback`);let R=c?Q("default",a,void 0,u,void 0,s):null;if(R)return n.log.info(`Using fallback for explicit model: ${R}`),{model:R,scenarioType:"default"};n.log.warn(`No fallback available for explicit model ${n.body.model}, continuing through routing logic`)}let{family:g,extended:y,isCcrAlias:p}=ns(n.body.model),f=l?.families?.[g||""];if(f&&l?.enableFamilyRouting){n.log.info(`Using model family routing for: ${g}${y?" (1M)":""}`),n.modelFamily=g,n.familyFallback=f.fallback;let C=Oc(n,e,f,a,o,y,u,c,l?.longContextThreshold,l?.extendedContextThreshold,s,d);if(C)return{model:C.model,scenarioType:C.scenarioType}}let _=p&&!l?.enableFamilyRouting?null:wc(n.body.model,l?.models);if(_){let C=V(_,a,!1,"modelMapping",c,d,s);if(C)return n.log.info(`Using mapped model for ${n.body.model}: ${_}`),{model:C,scenarioType:"modelMapping"};let R=c?Q("modelMapping",a,void 0,u,void 0,s):null;if(R)return{model:R,scenarioType:"modelMapping"};s&&Y(n,_,a,"modelMapping"),n.log.warn(`Mapped model ${_} unavailable (fail pool), skipping`)}let k=n.clientContext,h=rs(e,o,k),b=ss(k,void 0,l?.extendedContextThreshold);if(h>b&&l?.extendedContext){n.log.info(`Using extended context (1M) model due to token count: ${h}, estimated: ${e}, threshold: ${b}`);let C=V(l.extendedContext,a,!1,"extendedContext",c,d,s);if(C)return{model:C,scenarioType:"extendedContext"};n.log.warn(`Extended context model ${l.extendedContext} unavailable (fail pool), trying fallback`);let R=c?Q("extendedContext",a,void 0,u,void 0,s):null;if(R)return{model:R,scenarioType:"extendedContext"};s&&Y(n,l.extendedContext,a,"extendedContext")}let x=k?.longContextThreshold??l?.longContextThreshold??6e4;if(h>x&&l?.longContext){n.log.info(`Using long context model due to token count: ${h}, estimated: ${e}, threshold: ${x}`);let C=V(l.longContext,a,!1,"longContext",c,d,s);if(C)return{model:C,scenarioType:"longContext"};n.log.warn(`Long context model ${l.longContext} unavailable (fail pool), trying fallback`);let R=c?Q("longContext",a,void 0,u,void 0,s):null;if(R)return{model:R,scenarioType:"longContext"};s&&Y(n,l.longContext,a,"longContext")}if(!s&&m)return{model:m,scenarioType:"default"};if(n.body.model?.includes("claude")&&n.body.model?.includes("haiku")&&l?.background){n.log.info(`Using background model for ${n.body.model}`);let C=V(l.background,a,!1,"background",c,d,s);if(C)return{model:C,scenarioType:"background"};let R=c?Q("background",a,void 0,u,void 0,s):null;if(R)return{model:R,scenarioType:"background"};s&&Y(n,l.background,a,"background"),n.log.warn(`Background model ${l.background} unavailable (fail pool), falling through`)}if(Array.isArray(n.body.tools)&&n.body.tools.some(C=>C.type?.startsWith("web_search"))&&l?.webSearch){let C=V(l.webSearch,a,!1,"webSearch",c,d,s);if(C)return{model:C,scenarioType:"webSearch"};n.log.warn(`WebSearch model ${l.webSearch} unavailable (fail pool), trying fallback`);let R=c?Q("webSearch",a,void 0,u,void 0,s):null;if(R)return{model:R,scenarioType:"webSearch"};s&&Y(n,l.webSearch,a,"webSearch")}if(n.body.thinking?.type==="enabled"&&l?.think){n.log.info(`Using think model for ${n.body.thinking}`);let C=V(l.think,a,!1,"think",c,d,s);if(C)return{model:C,scenarioType:"think"};n.log.warn(`Think model ${l.think} unavailable (fail pool), trying fallback`);let R=c?Q("think",a,void 0,u,void 0,s):null;if(R)return{model:R,scenarioType:"think"};s&&Y(n,l.think,a,"think")}if(l?.default){let C=V(l.default,a,!1,"default",c,d,s);if(C)return{model:C,scenarioType:"default"};n.log.warn(`Default model ${l.default} unavailable (fail pool), trying fallback`);let R=c?Q("default",a,void 0,u,void 0,s):null;if(R)return{model:R,scenarioType:"default"};if(!s){let T=V(l.default,a,!0,"default",c,d,s);if(T)return n.log.warn(`No fallback available; retrying default model ${l.default} despite fail-pool state`),{model:T,scenarioType:"default"}}}return s&&Y(n,l?.default||n.body.model,a,"default"),{model:void 0,scenarioType:"default"}},Mt=async(n,e,t)=>{let{configService:o,event:r}=t;n.originalModel=n.body.model,ye(n,o.getAll());let s=await Rc(n,o),a=s||o.get("Router"),l=a?.enableFallback===!0,c=o.get("providers")||[],i=!!s;n.enableFallback=l,n.strictProjectRouting=i,n.fallbackConfig=i?a?.fallback:a?.fallback||o.get("fallback");let u=n.clientContext?.usageScope==="session"?n.previousUsage??X.get(n.usageCacheKey):void 0,{messages:d,system:m=[],tools:g}=n.body,y=o.get("REWRITE_SYSTEM_PROMPT");if(y&&m.length>1&&m[1]?.text?.includes("<env>")){let p=await ro(y,"utf-8");m[1].text=`${p}<env>${m[1].text.split("<env>").pop()}`}try{let[p,f]=n.body.model.split(","),_=t.tokenizerService?.getTokenizerConfigForModel(p,f),k;t.tokenizerService?k=(await t.tokenizerService.countTokens({messages:d,system:m,tools:g},_,p)).tokenCount:k=It(d,m,g),n.tokenCount=k;let h,b=i?void 0:o.get("CUSTOM_ROUTER_PATH");if(b)try{h=await Be(b)(n,o.getAll(),{event:r})}catch(x){n.log.error(`failed to load custom router: ${x.message}`)}if(h)n.scenarioType="default";else{let x=await Ec(n,k,o,u,s,!!s);h=x.model,n.scenarioType=x.scenarioType}if(a?.image&&h!==a.image&&Pc(n)&&!Ac(h)){let x=V(a.image,c,!1,"image",l,!i,i);if(x)n.log.info(`Using image model fallback for ${h}`),h=x,n.scenarioType="image";else{let v=l?Q("image",c,void 0,n.fallbackConfig,void 0,i):null;v?(n.log.info(`Using image fallback model: ${v}`),h=v,n.scenarioType="image"):i?Y(n,a.image,c,"image"):(n.log.warn(`Image model ${a.image} unavailable (fail pool), keeping ${h}`),n.scenarioType="image")}}typeof h=="string"&&h.trim()?n.body.model=h:(n.log.warn(`Router could not resolve a valid model for ${n.originalModel||n.body.model}; keeping original request model`),n.scenarioType=n.scenarioType||"default")}catch(p){if(p instanceof ce)throw p;if(n.log.error(`Error in router middleware: ${p.message}`),i){let f=n.sessionId||n.clientContext?.stableSessionId;throw new ce(`Project routing error: router failure in project mode. ${p.message}. Session: "${f||"unknown"}".`,{sessionId:f,configuredTarget:a?.default,code:"project_router_failure",statusCode:502})}n.body.model=a?.default,n.scenarioType="default"}},_e=new Map,qr=1e3,Ee=new Set,Zr=1e3,Ic=3,Mc=50,$c=n=>new Promise(e=>setTimeout(e,n));es=async n=>{let e=await Tc(Xr),t=[];for await(let s of e)s.isDirectory()&&t.push(s.name);let o=t.map(async s=>{let a=so(Xr,s,`${n}.jsonl`);try{return(await vc(a)).isFile()?s:null}catch{return null}}),r=await Promise.all(o);for(let s of r)if(s)return s;return null},is=async n=>{let e=Ae(n);if(!e)return null;if(_e.has(e))return _e.get(e)||null;try{let t=await es(e);if(!t&&!Ee.has(e)){Ee.add(e),Lc();for(let o=0;o<Ic&&!t;o++)await $c(Mc),t=await es(e)}return t?(_e.set(e,t),Nc(),t):null}catch(t){return console.error("Error searching for project by session:",t),null}}});function et(n){let e=[],t=Array.isArray(n.input)?n.input:[n.input];for(let o of t)if(o.type==="function_call")e.push({role:"assistant",tool_calls:[{id:o.call_id,type:"function",function:{name:o.name,arguments:o.arguments||"{}"}}]});else if(o.type==="function_call_output")e.push({role:"tool",tool_call_id:o.call_id,content:typeof o.output=="string"?o.output:JSON.stringify(o.output)});else if(o.type==="reasoning"){let r=Array.isArray(o.summary)?o.summary.filter(s=>s.type==="summary_text"&&s.text).map(s=>s.text).join(`
|
|
43
43
|
`):"";r&&e.push({role:"assistant",content:[{type:"text",text:`[reasoning]
|
|
44
|
-
${r}`}],_reasoningItem:!0})}else if(o.role){let r=o.content;Array.isArray(r)&&(r=r.map(s=>s.type==="input_text"?{type:"text",text:s.text}:s.type==="output_text"?{type:"text",text:s.text}:s.type==="input_image"?{type:"image_url",image_url:{url:s.image_url},media_type:s.mime_type}:s)),e.push({role:o.role,content:r})}n.messages=e,delete n.input,n.instructions&&typeof n.instructions=="string"&&(n.system=n.instructions,delete n.instructions),Array.isArray(n.tools)&&(n.tools=n.tools.filter(o=>o&&typeof o=="object").map(o=>o.type==="function"&&o.name&&!o.function?{type:"function",function:{name:o.name,description:o.description||"",parameters:o.parameters||{type:"object",properties:{}}}}:o.function?.name?o:o.type==="web_search"?{type:"function",function:{name:"web_search",description:"Search the web",parameters:{type:"object",properties:{query:{type:"string"}}}}}:null).filter(Boolean)),n.reasoning&&typeof n.reasoning=="object"&&(n.reasoning={enabled:!0,effort:n.reasoning.effort}),delete n.store,delete n.previous_response_id,delete n.include}async function
|
|
45
|
-
`).filter(c=>c.startsWith("data:")&&c.trim().length>5).length===0){o.releaseLock();let c=s.length<500?s:s.slice(0,500);throw B(`Provider ${t} returned streaming response with no SSE data lines: ${c}`,400,"provider_response_error")}let l=new ReadableStream({start:c=>{c.enqueue(r.value);let i=()=>{o.read().then(({done:u,value:d})=>{u?c.close():(c.enqueue(d),i())}).catch(u=>c.error(u))};i()},cancel:()=>{o.cancel()}});return new Response(l,{headers:e.headers,status:e.status,statusText:e.statusText})}async function Qc(n,e,t,o,r){let s=n.scenarioType||"default",a=n.familyFallback,l=n.modelFamily,c=n.strictProjectRouting?n.fallbackConfig:n.fallbackConfig??t.configService.get("fallback"),i=U(),u=n.provider||"",d=n.body.model||"",m=new Set,g=r?.statusCode===429||r?.isRateLimit===!0||r?.rawBody&&$t(r.rawBody)||r?.message&&$t(r.message);if(u&&d&&(g?(i.markRateLimited(u,d,120,r?.message),n.log.warn(`Primary model ${u},${d} rate-limited, will try fallbacks`)):i.recordFailure(u,d,r?.message),m.add(`${u},${d}`),t.recordUsage?.({provider:u,model:d,originalModel:n.originalModel||d,scenarioType:s,modelFamily:n.modelFamily,errorMessage:r?.message||String(r),sessionId:n.usageSessionId||n.id,stream:n.body.stream,inputTokens:n.tokenCount||0,req:n})),!(n.enableFallback??t.configService.get("Router")?.enableFallback===!0))return n.log.info("Fallback disabled by configuration, skipping fallback attempts"),null;let p=k=>{let[h,...b]=k.split(","),x=h?.trim(),v=b.join(",").trim();return!x||!v?null:{provider:x,model:v,key:`${x},${v}`}},f=[];if(l){let k=a?.[s];if(Array.isArray(k)&&k.length>0)f.push({name:`${l}/${s}`,models:k});else{let h=n.strictProjectRouting;n.log.warn(`No ${l} fallback configured for ${s}; ${h?"no project fallback available":"will try global fallback"}`)}}if(Array.isArray(c?.[s])&&c[s].length>0&&f.push({name:`global/${s}`,models:c[s]}),f.length===0&&s!=="image"&&n.body?.messages?.some(b=>b.role==="user"&&Array.isArray(b.content)&&b.content.some(x=>x.type==="image"||x.type==="image_url"||Array.isArray(x?.content)&&x.content.some(v=>v.type==="image"||v.type==="image_url")))&&Array.isArray(c?.image)&&c.image.length>0&&(n.log.info(`No fallback for scenario '${s}', but request has images \u2014 trying fallback.image`),f.push({name:"global/image (auto-detected)",models:c.image})),f.length===0)return null;let _=f.reduce((k,h)=>k+h.models.length,0);n.log.warn(`Request failed for ${s}, trying ${_} fallback models across ${f.length} fallback stage(s)`);for(let k of f){n.log.info(`Trying ${k.name} fallback stage with ${k.models.length} models`);for(let h of k.models){let b=p(h);if(!b){n.log.warn(`Fallback model '${h}' is invalid, skipping`);continue}if(m.has(b.key))continue;m.add(b.key);let x=t.providerService.getProviders(),v=Ze(x,b.provider,b.model);if(!v){n.log.warn(`Fallback model ${h} is not configured or provider is disabled, skipping`);continue}let C=v.provider.name,R=v.model;if(!i.isAvailable(C,R)){n.log.warn(`Fallback model ${h} unavailable (fail pool), skipping`);continue}let T;for(let A=1;A<=2;A++)try{n.log.info(`Trying fallback model: ${C},${R}${A>1?" (retry)":""}`);let w={...n.body};w.model=R;let O={...n,provider:C,body:w},P=v.provider,{requestBody:E,config:N,bypass:F}=await fs(w,P,o,n.headers,{req:O}),z=await ms(E,N,P,t,F,o,{req:O});try{P?.baseUrl&&z?.headers&&Ge(C,P.baseUrl,z.headers)}catch{}let $=await gs(E,z,P,o,F,{req:O,isCodexOnMessagesEndpoint:n.isCodexOnMessagesEndpoint||!1});return $=await ps(w,$,C),n.log.info(`Fallback model ${C},${R} succeeded`),i.recordSuccess(C,R),u&&d&&!n.strictProjectRouting&&(Ce().promote(u,d,s,C,R),n.log.info(`Promoted fallback model ${C},${R} for ${u},${d}:${s}`),g?n.log.info(`Rate-limited original model ${u},${d} already marked unavailable with cooldown`):(i.forceOpen(u,d,r?.message),n.log.info(`Marked original model ${u},${d} as unavailable`))),n.provider=C,n.body=w,hs($,e,w,t)}catch(w){if(T=w,A===1){n.log.warn(`Fallback model ${C},${R} failed, retrying once: ${w.message}`);continue}}i.recordFailure(C,R,T?.message),n.log.warn(`Fallback model ${C},${R} failed after retry: ${T?.message}`),t.recordUsage?.({provider:C,model:R,originalModel:n.originalModel||d||n.body.model,scenarioType:s,modelFamily:n.modelFamily,errorMessage:T?.message||String(T),sessionId:n.usageSessionId||n.id,stream:n.body.stream,inputTokens:n.tokenCount||0,req:n})}}return n.log.error(`All fallback models failed for ${s}`),null}async function fs(n,e,t,o,r){let s=JSON.parse(JSON.stringify(n)),a=s?.system;if(typeof a=="string"&&a.includes("cch="))s.system=a.replace(/cch=[^;]+;?/g,"cch=ccr-stable;");else if(Array.isArray(a))for(let i=0;i<a.length;i++){let u=a[i],d=typeof u=="string"?u:u?.text??"";if(d.includes("cch=")){let m=d.replace(/cch=[^;]+;?/g,"cch=ccr-stable;");typeof u=="string"?a[i]=m:typeof u?.text=="string"&&(u.text=m)}}let l={},c=!1;if(c=Kc(e,t,n),c&&(o instanceof Headers?o.delete("content-length"):delete o["content-length"],l.headers=o),!c&&typeof t.transformRequestOut=="function"){let i=await t.transformRequestOut(s);i.body?(s=i.body,l=i.config||{}):s=i}if(!c&&e.transformer?.use?.length)for(let i of e.transformer.use){if(!i||typeof i.transformRequestIn!="function")continue;let u=await i.transformRequestIn(s,e,r);u.body?(s=u.body,l={...l,...u.config}):s=u}if(!c&&e.transformer?.[n.model]?.use?.length)for(let i of e.transformer[n.model].use)!i||typeof i.transformRequestIn!="function"||(s=await i.transformRequestIn(s,e,r));return{requestBody:s,config:l,bypass:c}}function Kc(n,e,t){return e.endPoint==="/v1/chat/completions"&&Array.isArray(t?.system)?!1:n.transformer?.use?.length===1&&n.transformer.use[0].name===e.name&&(!n.transformer?.[t.model]?.use.length||n.transformer?.[t.model]?.use.length===1&&n.transformer?.[t.model]?.use[0].name===e.name)}function Xc(n){if(n.clientType)return n.clientType==="codex";let e=n.headers||{},t=e["x-anthropic-billing-header"]||"";if(typeof t=="string"&&t.includes("cc_version="))return!1;let o=e["user-agent"]||"";if(typeof o=="string"&&/codex/i.test(o))return!0;let r=n.pathname||n.url||"";if(typeof r=="string"&&r.split("?",1)[0].endsWith("/v1/responses"))return!0;let s=n.originalModel||n.body?.model||"";return typeof s=="string"&&s.toLowerCase()==="ccr-codex"}async function ms(n,e,t,o,r,s,a){let l=e.url||new URL(t.baseUrl);if(!e.TIMEOUT){let u=o.configService.get("API_TIMEOUT_MS");u&&(e.TIMEOUT=typeof u=="string"?parseInt(u,10):u)}if(r&&typeof s.auth=="function"){let u=await s.auth(n,t);if(u.body){n=u.body;let d=e.headers||{};u.config?.headers&&(d={...d,...u.config.headers},delete d.host,delete u.config.headers),e={...e,...u.config,headers:d}}else n=u}let c={Authorization:`Bearer ${t.apiKey}`,...e?.headers||{}};for(let u in c)(c[u]==="undefined"||["authorization","Authorization"].includes(u)&&c[u]?.includes("undefined"))&&delete c[u];Ct(o.configService)&&Rr(o.log,a.req.id,{url:String(l),headers:c,body:n});let i=await Pr(l,n,{...e,headers:JSON.parse(JSON.stringify(c)),httpsProxy:se(o.configService,t)},a,o.log);if(!i.ok){let u=await i.text();o.log.error(`[provider_response_error] Error from provider(${t.name},${n.model}: ${i.status}): ${u}`);let d=B(`Error from provider(${t.name},${n.model}: ${i.status}): ${u}`,i.status,"provider_response_error");throw d.isRateLimit=i.status===429||$t(u),d.rawBody=u,d}if(i.ok){let u=i.headers.get("content-type")||"",d=n.stream===!0;if(o.log.info(`[hidden-error-check] provider=${t.name} model=${n.model} stream=${n.stream} isStreamRequest=${d} contentType=${u} ok=${i.ok} status=${i.status} hasBody=${!!i.body}`),!d||u.includes("application/json")){let m=i.clone(),g="";try{if(g=await m.text(),!g||g.trim()==="")throw new SyntaxError("Empty JSON body");let y=JSON.parse(g);if(y&&typeof y=="object"&&y.error&&(typeof y.error=="string"||typeof y.error=="object"&&Object.keys(y.error).length>0)){o.log.error(`[provider_response_error] Hidden error from provider(${t.name},${n.model}: ${i.status}): ${g}`);let f=$t(g),_=B(`Error from provider(${t.name},${n.model}: ${i.status}): ${g}`,400,"provider_response_error");throw _.isRateLimit=f,_.rawBody=g,_}}catch(y){if(y instanceof SyntaxError){o.log.warn(`[provider_response_error] Empty or malformed JSON response from provider(${t.name},${n.model}: 200): "${g}"`);let p=B(`API returned an empty or malformed response (HTTP 200) from ${t.name} \u2014 check for a proxy or gateway intercepting the request`,400,"provider_response_error");throw p.rawBody=g,p}throw y}}}if(!n.stream&&Ct(o.configService)){let d=await i.clone().text();wr(o.log,a.req.id,{status:i.status,headers:Object.fromEntries(i.headers.entries()),body:d})}return i}async function gs(n,e,t,o,r,s){let a=e;if(!r&&t.transformer?.use?.length)for(let l of Array.from(t.transformer.use).reverse())!l||typeof l.transformResponseOut!="function"||(a=await l.transformResponseOut(a,s));if(!r&&t.transformer?.[n.model]?.use?.length)for(let l of Array.from(t.transformer[n.model].use).reverse())!l||typeof l.transformResponseOut!="function"||(a=await l.transformResponseOut(a,s));if(!r&&o.transformResponseIn&&(s.provider||(s.provider=t),a=await o.transformResponseIn(a,s)),s?.isCodexOnMessagesEndpoint)try{a=await new Re().transformResponseIn(a,{...s,provider:t})}catch(l){console.error("Failed to apply Responses API conversion for codex client:",l)}return a}function hs(n,e,t,o){if(n.ok||e.code(n.status),t.stream===!0){if(e.header("Content-Type","text/event-stream"),e.header("Cache-Control","no-cache"),e.header("Connection","keep-alive"),o&&Ct(o.configService)){let[s,a]=n.body.tee(),l=vr(o.configService);return Sr(s,o.log,e.request.id,l),e.send(a)}return e.send(n.body)}else return n.json()}function $t(n){let e=n.toLowerCase();return e.includes("rate limit")||e.includes("rate_limit")||e.includes("rate_limit_error")||e.includes("too many requests")||e.includes("too many")||e.includes("quota exhausted")||e.includes("qps_limit")||e.includes("token_limit")||e.includes("\u9650\u6D41")||e.includes("\u9891\u7387\u9650\u5236")}function Yc(n){try{return new URL(n),!0}catch{return!1}}var Vc,ys,Nt=S(()=>{"use strict";Ar();bt();We();Hn();ee();ve();wt();qn();et();Z();Vc=/^ccr-(opus|sonnet|haiku)(\[1m\])?$/i;ys=async n=>{n.get("/",async()=>({message:"LLMs API",version:Rt})),n.get("/health",async()=>({status:"ok",timestamp:new Date().toISOString()})),n.get("/providers/health",async()=>({states:U().getAllStates().map(r=>({provider:r.provider,model:r.model,status:r.status,failureCount:r.failureCount,successCount:r.successCount,lastFailureTime:r.lastFailureTime,lastError:r.lastError,rateLimitUntil:r.rateLimitUntil??null})),timestamp:new Date().toISOString()}));let e=n.transformerService.getTransformersWithEndpoint();for(let{transformer:t}of e)t.endPoint&&n.post(t.endPoint,async(o,r)=>ds(o,r,n,t));n.post("/providers",{schema:{body:{type:"object",properties:{id:{type:"string"},name:{type:"string"},type:{type:"string",enum:["openai","anthropic"]},baseUrl:{type:"string"},apiKey:{type:"string"},models:{type:"array",items:{type:"string"}},proxyEnabled:{type:"boolean"}},required:["id","name","type","baseUrl","apiKey","models"]}}},async(t,o)=>{let{name:r,baseUrl:s,apiKey:a,models:l}=t.body;if(!r?.trim())throw B("Provider name is required",400,"invalid_request");if(!s||!Yc(s))throw B("Valid base URL is required",400,"invalid_request");if(!a?.trim())throw B("API key is required",400,"invalid_request");if(!l||!Array.isArray(l)||l.length===0)throw B("At least one model is required",400,"invalid_request");if(n.providerService.getProvider(t.body.name))throw B(`Provider with name '${t.body.name}' already exists`,400,"provider_exists");return n.providerService.registerProvider(t.body)}),n.get("/providers",async()=>n.providerService.getProviders()),n.get("/providers/:id",{schema:{params:{type:"object",properties:{id:{type:"string"}},required:["id"]}}},async t=>{let o=n.providerService.getProvider(t.params.id);if(!o)throw B("Provider not found",404,"provider_not_found");return o}),n.put("/providers/:id",{schema:{params:{type:"object",properties:{id:{type:"string"}},required:["id"]},body:{type:"object",properties:{name:{type:"string"},type:{type:"string",enum:["openai","anthropic"]},baseUrl:{type:"string"},apiKey:{type:"string"},models:{type:"array",items:{type:"string"}},proxyEnabled:{type:"boolean"},enabled:{type:"boolean"}}}}},async(t,o)=>{let r=n.providerService.updateProvider(t.params.id,t.body);if(!r)throw B("Provider not found",404,"provider_not_found");return r}),n.delete("/providers/:id",{schema:{params:{type:"object",properties:{id:{type:"string"}},required:["id"]}}},async t=>{if(!n.providerService.deleteProvider(t.params.id))throw B("Provider not found",404,"provider_not_found");return{message:"Provider deleted successfully"}}),n.patch("/providers/:id/toggle",{schema:{params:{type:"object",properties:{id:{type:"string"}},required:["id"]},body:{type:"object",properties:{enabled:{type:"boolean"}},required:["enabled"]}}},async(t,o)=>{if(!n.providerService.toggleProvider(t.params.id,t.body.enabled))throw B("Provider not found",404,"provider_not_found");return{message:`Provider ${t.body.enabled?"enabled":"disabled"} successfully`}})}});var ce,Lt=S(()=>{"use strict";ce=class{constructor(e,t,o){this.configService=e;this.transformerService=t;this.logger=o;this.initializeCustomProviders()}providers=new Map;modelRoutes=new Map;initializeCustomProviders(){let e=this.configService.get("providers");if(e&&Array.isArray(e)){this.initializeFromProvidersArray(e);return}}initializeFromProvidersArray(e){e.forEach(t=>{try{if(!t.name||!t.api_base_url||!t.api_key)return;let o={};t.transformer&&Object.keys(t.transformer).forEach(r=>{r==="use"?Array.isArray(t.transformer.use)&&(o.use=t.transformer.use.map(s=>{if(Array.isArray(s)&&typeof s[0]=="string"){let a=this.transformerService.getTransformer(s[0]);if(a)return new a(s[1])}if(typeof s=="string"){let a=this.transformerService.getTransformer(s);return typeof a=="function"?new a:a}}).filter(s=>typeof s<"u")):Array.isArray(t.transformer[r]?.use)&&(o[r]={use:t.transformer[r].use.map(s=>{if(Array.isArray(s)&&typeof s[0]=="string"){let a=this.transformerService.getTransformer(s[0]);if(a)return new a(s[1])}if(typeof s=="string"){let a=this.transformerService.getTransformer(s);return typeof a=="function"?new a:a}}).filter(s=>typeof s<"u")})}),this.registerProvider({name:t.name,baseUrl:t.api_base_url,apiKey:t.api_key,models:t.models||[],quotaToken:t.quota_token,transformer:t.transformer?o:void 0,cacheMode:t.cache_mode||"exclusive",enabled:t.enabled!==!1,proxyEnabled:t.proxy_enabled===!0,wakeupEnabled:t.wakeup_enabled===!0,wakeupTime:t.wakeup_time||"06:00",wakeupModel:t.wakeup_model||""}),this.logger.info(`${t.name} provider registered`)}catch(o){this.logger.error(`${t.name} provider registered error: ${o}`)}})}registerProvider(e){let t={...e,enabled:e.enabled!==!1,proxyEnabled:e.proxyEnabled===!0,wakeupEnabled:e.wakeupEnabled===!0,wakeupTime:e.wakeupTime||"06:00",wakeupModel:e.wakeupModel||""};return this.providers.set(t.name,t),e.models.forEach(o=>{let r=`${t.name},${o}`,s={provider:t.name,model:o,fullModel:r};this.modelRoutes.set(r,s),this.modelRoutes.has(o)||this.modelRoutes.set(o,s)}),t}getProviders(){return Array.from(this.providers.values())}getProvider(e){return this.providers.get(e)}updateProvider(e,t){let o=this.providers.get(e);if(!o)return null;let r={...o,...t,updatedAt:new Date};return this.providers.set(e,r),t.models&&(o.models.forEach(s=>{let a=`${o.name},${s}`;this.modelRoutes.delete(a),this.modelRoutes.delete(s)}),t.models.forEach(s=>{let a=`${o.name},${s}`,l={provider:o.name,model:s,fullModel:a};this.modelRoutes.set(a,l),this.modelRoutes.has(s)||this.modelRoutes.set(s,l)})),r}deleteProvider(e){let t=this.providers.get(e);return t?(t.models.forEach(o=>{let r=`${t.name},${o}`;this.modelRoutes.delete(r),this.modelRoutes.delete(o)}),this.providers.delete(e),!0):!1}toggleProvider(e,t){let o=this.providers.get(e);if(!o)return!1;o.enabled=t;let r=this.configService.get("providers");if(r&&Array.isArray(r)){let s=r.find(a=>a.name===e);s&&(s.enabled=t)}return!0}resolveModelRoute(e){let t=this.modelRoutes.get(e);if(!t)return null;let o=this.providers.get(t.provider);return o?{provider:o,originalModel:e,targetModel:t.model}:null}getAvailableModelNames(){let e=[];return this.providers.forEach(t=>{t.enabled!==!1&&t.models.forEach(o=>{e.push(o),e.push(`${t.name},${o}`)})}),e}getModelRoutes(){return Array.from(this.modelRoutes.values())}parseTransformerConfig(e){return e?Array.isArray(e)?e.reduce((t,o)=>{if(Array.isArray(o)){let[r,s={}]=o;t[r]=s}else t[o]={};return t},{}):e:{}}async getAvailableModels(){let e=[];return this.providers.forEach(t=>{t.enabled!==!1&&t.models.forEach(o=>{e.push({id:o,object:"model",owned_by:t.name,provider:t.name}),e.push({id:`${t.name},${o}`,object:"model",owned_by:t.name,provider:t.name})})}),{object:"list",data:e}}}});var _s,ks=S(()=>{_s=n=>n<=0?"none":n<=1024?"low":n<=8192?"medium":"high"});var bs,xs=S(()=>{bs=(n,e)=>(n.includes("base64")&&(n=n.split("base64").pop(),n.startsWith(",")&&(n=n.slice(1))),`data:${e};base64,${n}`)});function qc(n){return n.filter(e=>!!e?.function?.name).map(e=>({name:e.function.name,description:e.function.description,input_schema:e.function.parameters}))}function Cs(n){let e=[],t=[],o=m=>{if(typeof m=="string"){t.push({type:"text",text:m});return}Array.isArray(m)&&m.forEach(g=>{if(typeof g=="string"){t.push({type:"text",text:g});return}g&&typeof g=="object"&&g.type==="text"&&g.text&&t.push({...g})})},r=()=>{let m=new Map;for(let g=0;g<t.length;g++){let y=t[g],p=y?.text??JSON.stringify(y),f=m.get(p);if(f===void 0){m.set(p,g);continue}!t[f]?.cache_control&&y?.cache_control&&(t[f]=y),t.splice(g,1),g--}};n.messages.forEach(m=>{m.role==="system"?o(m.content):e.push(m)}),r();let s=[];for(let m=0;m<e.length;m++){let g=e[m];if(g.role==="tool"){let y=g.content;try{typeof g.content=="string"&&(y=JSON.parse(g.content))}catch{}y!=null&&typeof y!="object"&&typeof y!="string"&&(y=String(y));let p={type:"tool_result",tool_use_id:g.tool_call_id,content:y};g.cache_control&&(p.cache_control=g.cache_control);let f=s[s.length-1];f&&f.role==="user"&&Array.isArray(f.content)?f.content.push(p):s.push({role:"user",content:[p]})}else if(g.role==="user"){let y=[];typeof g.content=="string"?y.push({type:"text",text:g.content}):Array.isArray(g.content)&&g.content.forEach(f=>{f&&typeof f=="object"&&f.type==="image_url"&&f.image_url?.url?y.push({type:"image",source:{type:"base64",media_type:f.media_type||"image/jpeg",data:f.image_url.url.split(",")[1]||f.image_url.url}}):y.push(f)});let p=s[s.length-1];p&&p.role==="user"&&Array.isArray(p.content)?p.content.push(...y):s.push({role:"user",content:y.length>0?y:[{type:"text",text:" "}]})}else if(g.role==="assistant"){let y=[];g.content&&(typeof g.content=="string"?y.push({type:"text",text:g.content}):Array.isArray(g.content)&&y.push(...g.content)),g.tool_calls&&g.tool_calls.length>0&&g.tool_calls.forEach(f=>{let _={};try{_=JSON.parse(f.function.arguments)}catch{_=f.function.arguments}y.push({type:"tool_use",id:f.id,name:f.function.name,input:_})}),g.thinking&&y.unshift({type:"thinking",thinking:g.thinking.content,signature:g.thinking.signature});let p=s[s.length-1];p&&p.role==="assistant"&&Array.isArray(p.content)?p.content.push(...y):s.push({role:"assistant",content:y.length>0?y:[{type:"text",text:" "}]})}}let a=()=>{let m=t.filter(g=>g?.cache_control).length;for(let g of s)Array.isArray(g.content)&&(m+=g.content.filter(y=>y?.cache_control).length);return m},l=m=>m&&typeof m=="object"?{...m}:{type:"ephemeral"},c=()=>{for(let m=s.length-1;m>=0;m--){let g=s[m]?.content;if(!Array.isArray(g))continue;let y=g.find(p=>p?.cache_control);if(y?.cache_control)return y.cache_control}for(let m=t.length-1;m>=0;m--)if(t[m]?.cache_control)return t[m].cache_control;return{type:"ephemeral"}},i=(m,g)=>{if(!Array.isArray(m?.content)||m.content.some(p=>p?.cache_control))return!1;let y=m.content.find(p=>p&&typeof p=="object"&&!p.cache_control);return y?(y.cache_control=l(g),!0):!1};(()=>{let m=4-a();if(m<=0||s.length===0)return;let g=s,y=c(),p=[];for(let f=g.length-1;f>=0;f--)g[f]?.role!=="user"||!Array.isArray(g[f].content)||p.push(f);for(let f of p){if(m<=0)break;i(g[f],y)&&m--}})();let d={messages:s,model:n.model,max_tokens:n.max_tokens||4096,temperature:n.temperature,stream:n.stream};if(t.length>0){let m=t.some(g=>g?.cache_control);d.system=m?t:t.map(g=>g.text||"").join(`
|
|
44
|
+
${r}`}],_reasoningItem:!0})}else if(o.role){let r=o.content;Array.isArray(r)&&(r=r.map(s=>s.type==="input_text"?{type:"text",text:s.text}:s.type==="output_text"?{type:"text",text:s.text}:s.type==="input_image"?{type:"image_url",image_url:{url:s.image_url},media_type:s.mime_type}:s)),e.push({role:o.role,content:r})}n.messages=e,delete n.input,n.instructions&&typeof n.instructions=="string"&&(n.system=n.instructions,delete n.instructions),Array.isArray(n.tools)&&(n.tools=n.tools.filter(o=>o&&typeof o=="object").map(o=>o.type==="function"&&o.name&&!o.function?{type:"function",function:{name:o.name,description:o.description||"",parameters:o.parameters||{type:"object",properties:{}}}}:o.function?.name?o:o.type==="web_search"?{type:"function",function:{name:"web_search",description:"Search the web",parameters:{type:"object",properties:{query:{type:"string"}}}}}:null).filter(Boolean)),n.reasoning&&typeof n.reasoning=="object"&&(n.reasoning={enabled:!0,effort:n.reasoning.effort}),delete n.store,delete n.previous_response_id,delete n.include}async function as(n,e,t,o){let r=n.body;(n.ccrHookOrder||=[]).push("handler"),o.endPoint==="/v1/responses"&&r?.input&&!r?.messages&&et(r),o.endPoint==="/v1/responses"&&!n.provider&&typeof r?.model=="string"&&Fc.test(r.model)&&await Mt(n,e,{configService:t.configService,tokenizerService:t.tokenizerService});let s=n.provider;if(!s&&r?.model){let i=r.model.split(",");i.length>1&&(s=i[0],r.model=i.slice(1).join(","))}let a=s?t.providerService.getProvider(s):void 0;if(!a&&r?.model){let i=t.providerService.resolveModelRoute(r.model);i&&(a=i.provider,r.model=i.targetModel)}if(!a&&r?.model){let u=t.configService.get("Router")?.default;if(u&&u.includes(",")){let[d,...m]=u.split(","),g=t.providerService.getProvider(d);g&&(a=g,r.model=m.join(","))}}if(n.originalModel||(n.originalModel=r?.model),!a)throw B(`Provider '${s}' not found`,404,"provider_not_found");n.provider=a.name||s;let l=jc(n),c=o.endPoint==="/v1/messages"&&l;l&&e.header("X-Codex-Detected","true"),c&&e.header("X-Codex-On-Messages","true"),n.isCodexOnMessagesEndpoint=c,n.codexDetected=l;try{o.endPoint==="/v1/responses"&&r.input&&!r.messages&&et(r);let{requestBody:i,config:u,bypass:d}=await ls(r,a,o,n.headers,{req:n});if(i?.messages&&!d&&!n.isTargetAnthropic){let p=i.messages,f=new Set,_=[],k=[];for(let h of p){if(h?.role!=="system"){k.push(h);continue}let b=JSON.stringify(h.content??"");f.has(b)||(f.add(b),_.push(h))}_.length>0&&k.length>0&&(i.messages=[..._,...k])}let m=await us(i,u,a,t,d,o,{req:n});try{a?.baseUrl&&m?.headers&&Ge(s,a.baseUrl,m.headers)}catch{}let g=await ds(i,m,a,o,d,{req:n,isCodexOnMessagesEndpoint:c});g=await cs(r,g,a.name||s);let y=ps(g,e,r,t);try{let p=r.model||n.originalModel;s&&p&&U().recordSuccess(s,p)}catch{}return y}catch(i){if(i instanceof ce)throw i;if(!n.__retryAttempted){n.__retryAttempted=!0;try{return await as(n,e,t,o)}catch(d){if(n.__fallbackExhausted)throw d;i=d}}let u=await Uc(n,e,t,o,i);if(u)return u;throw n.__fallbackExhausted=!0,i}}async function cs(n,e,t){if(!n?.stream||!e?.body)return e;let o=e.body.getReader(),r=await o.read();if(r.done)throw o.releaseLock(),B(`Provider returned empty streaming response from ${t}`,400,"provider_response_error");let s=new TextDecoder().decode(r.value);if(s.includes("event: error")){o.releaseLock();let c=s.length<500?s:s.slice(0,500);throw B(`Provider ${t} returned error in SSE stream: ${c}`,400,"provider_response_error")}if(s.split(`
|
|
45
|
+
`).filter(c=>c.startsWith("data:")&&c.trim().length>5).length===0){o.releaseLock();let c=s.length<500?s:s.slice(0,500);throw B(`Provider ${t} returned streaming response with no SSE data lines: ${c}`,400,"provider_response_error")}let l=new ReadableStream({start:c=>{c.enqueue(r.value);let i=()=>{o.read().then(({done:u,value:d})=>{u?c.close():(c.enqueue(d),i())}).catch(u=>c.error(u))};i()},cancel:()=>{o.cancel()}});return new Response(l,{headers:e.headers,status:e.status,statusText:e.statusText})}async function Uc(n,e,t,o,r){let s=n.scenarioType||"default",a=n.familyFallback,l=n.modelFamily,c=n.strictProjectRouting?n.fallbackConfig:n.fallbackConfig??t.configService.get("fallback"),i=U(),u=n.provider||"",d=n.body.model||"",m=new Set,g=r?.statusCode===429||r?.isRateLimit===!0||r?.rawBody&&$t(r.rawBody)||r?.message&&$t(r.message);if(u&&d&&(g?(i.markRateLimited(u,d,120,r?.message),n.log.warn(`Primary model ${u},${d} rate-limited, will try fallbacks`)):i.recordFailure(u,d,r?.message),m.add(`${u},${d}`),t.recordUsage?.({provider:u,model:d,originalModel:n.originalModel||d,scenarioType:s,modelFamily:n.modelFamily,errorMessage:r?.message||String(r),sessionId:n.usageSessionId||n.id,stream:n.body.stream,inputTokens:n.tokenCount||0,req:n})),!(n.enableFallback??t.configService.get("Router")?.enableFallback===!0))return n.log.info("Fallback disabled by configuration, skipping fallback attempts"),null;let p=k=>{let[h,...b]=k.split(","),x=h?.trim(),v=b.join(",").trim();return!x||!v?null:{provider:x,model:v,key:`${x},${v}`}},f=[];if(l){let k=a?.[s];if(Array.isArray(k)&&k.length>0)f.push({name:`${l}/${s}`,models:k});else{let h=n.strictProjectRouting;n.log.warn(`No ${l} fallback configured for ${s}; ${h?"no project fallback available":"will try global fallback"}`)}}if(Array.isArray(c?.[s])&&c[s].length>0&&f.push({name:`global/${s}`,models:c[s]}),f.length===0&&s!=="image"&&n.body?.messages?.some(b=>b.role==="user"&&Array.isArray(b.content)&&b.content.some(x=>x.type==="image"||x.type==="image_url"||Array.isArray(x?.content)&&x.content.some(v=>v.type==="image"||v.type==="image_url")))&&Array.isArray(c?.image)&&c.image.length>0&&(n.log.info(`No fallback for scenario '${s}', but request has images \u2014 trying fallback.image`),f.push({name:"global/image (auto-detected)",models:c.image})),f.length===0)return null;let _=f.reduce((k,h)=>k+h.models.length,0);n.log.warn(`Request failed for ${s}, trying ${_} fallback models across ${f.length} fallback stage(s)`);for(let k of f){n.log.info(`Trying ${k.name} fallback stage with ${k.models.length} models`);for(let h of k.models){let b=p(h);if(!b){n.log.warn(`Fallback model '${h}' is invalid, skipping`);continue}if(m.has(b.key))continue;m.add(b.key);let x=t.providerService.getProviders(),v=qe(x,b.provider,b.model);if(!v){n.log.warn(`Fallback model ${h} is not configured or provider is disabled, skipping`);continue}let C=v.provider.name,R=v.model;if(!i.isAvailable(C,R)){n.log.warn(`Fallback model ${h} unavailable (fail pool), skipping`);continue}let T;for(let A=1;A<=2;A++)try{n.log.info(`Trying fallback model: ${C},${R}${A>1?" (retry)":""}`);let w={...n.body};w.model=R;let O={...n,provider:C,body:w},P=v.provider,{requestBody:E,config:N,bypass:F}=await ls(w,P,o,n.headers,{req:O}),z=await us(E,N,P,t,F,o,{req:O});try{P?.baseUrl&&z?.headers&&Ge(C,P.baseUrl,z.headers)}catch{}let $=await ds(E,z,P,o,F,{req:O,isCodexOnMessagesEndpoint:n.isCodexOnMessagesEndpoint||!1});return $=await cs(w,$,C),n.log.info(`Fallback model ${C},${R} succeeded`),i.recordSuccess(C,R),u&&d&&!n.strictProjectRouting&&(Te().promote(u,d,s,C,R),n.log.info(`Promoted fallback model ${C},${R} for ${u},${d}:${s}`),g?n.log.info(`Rate-limited original model ${u},${d} already marked unavailable with cooldown`):(i.forceOpen(u,d,r?.message),n.log.info(`Marked original model ${u},${d} as unavailable`))),n.provider=C,n.body=w,ps($,e,w,t)}catch(w){if(T=w,A===1){n.log.warn(`Fallback model ${C},${R} failed, retrying once: ${w.message}`);continue}}i.recordFailure(C,R,T?.message),n.log.warn(`Fallback model ${C},${R} failed after retry: ${T?.message}`),t.recordUsage?.({provider:C,model:R,originalModel:n.originalModel||d||n.body.model,scenarioType:s,modelFamily:n.modelFamily,errorMessage:T?.message||String(T),sessionId:n.usageSessionId||n.id,stream:n.body.stream,inputTokens:n.tokenCount||0,req:n})}}return n.log.error(`All fallback models failed for ${s}`),null}async function ls(n,e,t,o,r){let s=JSON.parse(JSON.stringify(n)),a=s?.system;if(typeof a=="string"&&a.includes("cch="))s.system=a.replace(/cch=[^;]+;?/g,"cch=ccr-stable;");else if(Array.isArray(a))for(let i=0;i<a.length;i++){let u=a[i],d=typeof u=="string"?u:u?.text??"";if(d.includes("cch=")){let m=d.replace(/cch=[^;]+;?/g,"cch=ccr-stable;");typeof u=="string"?a[i]=m:typeof u?.text=="string"&&(u.text=m)}}let l={},c=!1;if(c=Dc(e,t,n),c&&(o instanceof Headers?o.delete("content-length"):delete o["content-length"],l.headers=o),!c&&typeof t.transformRequestOut=="function"){let i=await t.transformRequestOut(s);i.body?(s=i.body,l=i.config||{}):s=i}if(!c&&e.transformer?.use?.length)for(let i of e.transformer.use){if(!i||typeof i.transformRequestIn!="function")continue;let u=await i.transformRequestIn(s,e,r);u.body?(s=u.body,l={...l,...u.config}):s=u}if(!c&&e.transformer?.[n.model]?.use?.length)for(let i of e.transformer[n.model].use)!i||typeof i.transformRequestIn!="function"||(s=await i.transformRequestIn(s,e,r));return{requestBody:s,config:l,bypass:c}}function Dc(n,e,t){return e.endPoint==="/v1/chat/completions"&&Array.isArray(t?.system)?!1:n.transformer?.use?.length===1&&n.transformer.use[0].name===e.name&&(!n.transformer?.[t.model]?.use.length||n.transformer?.[t.model]?.use.length===1&&n.transformer?.[t.model]?.use[0].name===e.name)}function jc(n){if(n.clientType)return n.clientType==="codex";let e=n.headers||{},t=e["x-anthropic-billing-header"]||"";if(typeof t=="string"&&t.includes("cc_version="))return!1;let o=e["user-agent"]||"";if(typeof o=="string"&&/codex/i.test(o))return!0;let r=n.pathname||n.url||"";if(typeof r=="string"&&r.split("?",1)[0].endsWith("/v1/responses"))return!0;let s=n.originalModel||n.body?.model||"";return typeof s=="string"&&s.toLowerCase()==="ccr-codex"}async function us(n,e,t,o,r,s,a){let l=e.url||new URL(t.baseUrl);if(!e.TIMEOUT){let u=o.configService.get("API_TIMEOUT_MS");u&&(e.TIMEOUT=typeof u=="string"?parseInt(u,10):u)}if(r&&typeof s.auth=="function"){let u=await s.auth(n,t);if(u.body){n=u.body;let d=e.headers||{};u.config?.headers&&(d={...d,...u.config.headers},delete d.host,delete u.config.headers),e={...e,...u.config,headers:d}}else n=u}let c={Authorization:`Bearer ${t.apiKey}`,...e?.headers||{}};for(let u in c)(c[u]==="undefined"||["authorization","Authorization"].includes(u)&&c[u]?.includes("undefined"))&&delete c[u];Ct(o.configService)&&Rr(o.log,a.req.id,{url:String(l),headers:c,body:n});let i=await Pr(l,n,{...e,headers:JSON.parse(JSON.stringify(c)),httpsProxy:ie(o.configService,t)},a,o.log);if(!i.ok){let u=await i.text();o.log.error(`[provider_response_error] Error from provider(${t.name},${n.model}: ${i.status}): ${u}`);let d=B(`Error from provider(${t.name},${n.model}: ${i.status}): ${u}`,i.status,"provider_response_error");throw d.isRateLimit=i.status===429||$t(u),d.rawBody=u,d}if(i.ok){let u=i.headers.get("content-type")||"",d=n.stream===!0;if(o.log.info(`[hidden-error-check] provider=${t.name} model=${n.model} stream=${n.stream} isStreamRequest=${d} contentType=${u} ok=${i.ok} status=${i.status} hasBody=${!!i.body}`),!d||u.includes("application/json")){let m=i.clone(),g="";try{if(g=await m.text(),!g||g.trim()==="")throw new SyntaxError("Empty JSON body");let y=JSON.parse(g);if(y&&typeof y=="object"&&y.error&&(typeof y.error=="string"||typeof y.error=="object"&&Object.keys(y.error).length>0)){o.log.error(`[provider_response_error] Hidden error from provider(${t.name},${n.model}: ${i.status}): ${g}`);let f=$t(g),_=B(`Error from provider(${t.name},${n.model}: ${i.status}): ${g}`,400,"provider_response_error");throw _.isRateLimit=f,_.rawBody=g,_}}catch(y){if(y instanceof SyntaxError){o.log.warn(`[provider_response_error] Empty or malformed JSON response from provider(${t.name},${n.model}: 200): "${g}"`);let p=B(`API returned an empty or malformed response (HTTP 200) from ${t.name} \u2014 check for a proxy or gateway intercepting the request`,400,"provider_response_error");throw p.rawBody=g,p}throw y}}}if(!n.stream&&Ct(o.configService)){let d=await i.clone().text();wr(o.log,a.req.id,{status:i.status,headers:Object.fromEntries(i.headers.entries()),body:d})}return i}async function ds(n,e,t,o,r,s){let a=e;if(!r&&t.transformer?.use?.length)for(let l of Array.from(t.transformer.use).reverse())!l||typeof l.transformResponseOut!="function"||(a=await l.transformResponseOut(a,s));if(!r&&t.transformer?.[n.model]?.use?.length)for(let l of Array.from(t.transformer[n.model].use).reverse())!l||typeof l.transformResponseOut!="function"||(a=await l.transformResponseOut(a,s));if(!r&&o.transformResponseIn&&(s.provider||(s.provider=t),a=await o.transformResponseIn(a,s)),s?.isCodexOnMessagesEndpoint)try{a=await new we().transformResponseIn(a,{...s,provider:t})}catch(l){console.error("Failed to apply Responses API conversion for codex client:",l)}return a}function ps(n,e,t,o){if(n.ok||e.code(n.status),t.stream===!0){if(e.header("Content-Type","text/event-stream"),e.header("Cache-Control","no-cache"),e.header("Connection","keep-alive"),o&&Ct(o.configService)){let[s,a]=n.body.tee(),l=vr(o.configService);return Sr(s,o.log,e.request.id,l),e.send(a)}return e.send(n.body)}else return n.json()}function $t(n){let e=n.toLowerCase();return e.includes("rate limit")||e.includes("rate_limit")||e.includes("rate_limit_error")||e.includes("too many requests")||e.includes("too many")||e.includes("quota exhausted")||e.includes("qps_limit")||e.includes("token_limit")||e.includes("\u9650\u6D41")||e.includes("\u9891\u7387\u9650\u5236")}function zc(n){try{return new URL(n),!0}catch{return!1}}var Fc,fs,Nt=S(()=>{"use strict";Ar();bt();We();Hn();ne();Re();wt();qn();Ze();te();Fc=/^ccr-(opus|sonnet|haiku)(\[1m\])?$/i;fs=async n=>{n.get("/",async()=>({message:"LLMs API",version:Rt})),n.get("/health",async()=>({status:"ok",timestamp:new Date().toISOString()})),n.get("/providers/health",async()=>({states:U().getAllStates().map(r=>({provider:r.provider,model:r.model,status:r.status,failureCount:r.failureCount,successCount:r.successCount,lastFailureTime:r.lastFailureTime,lastError:r.lastError,rateLimitUntil:r.rateLimitUntil??null})),timestamp:new Date().toISOString()}));let e=n.transformerService.getTransformersWithEndpoint();for(let{transformer:t}of e)t.endPoint&&n.post(t.endPoint,async(o,r)=>as(o,r,n,t));n.post("/providers",{schema:{body:{type:"object",properties:{id:{type:"string"},name:{type:"string"},type:{type:"string",enum:["openai","anthropic"]},baseUrl:{type:"string"},apiKey:{type:"string"},models:{type:"array",items:{type:"string"}},proxyEnabled:{type:"boolean"}},required:["id","name","type","baseUrl","apiKey","models"]}}},async(t,o)=>{let{name:r,baseUrl:s,apiKey:a,models:l}=t.body;if(!r?.trim())throw B("Provider name is required",400,"invalid_request");if(!s||!zc(s))throw B("Valid base URL is required",400,"invalid_request");if(!a?.trim())throw B("API key is required",400,"invalid_request");if(!l||!Array.isArray(l)||l.length===0)throw B("At least one model is required",400,"invalid_request");if(n.providerService.getProvider(t.body.name))throw B(`Provider with name '${t.body.name}' already exists`,400,"provider_exists");return n.providerService.registerProvider(t.body)}),n.get("/providers",async()=>n.providerService.getProviders()),n.get("/providers/:id",{schema:{params:{type:"object",properties:{id:{type:"string"}},required:["id"]}}},async t=>{let o=n.providerService.getProvider(t.params.id);if(!o)throw B("Provider not found",404,"provider_not_found");return o}),n.put("/providers/:id",{schema:{params:{type:"object",properties:{id:{type:"string"}},required:["id"]},body:{type:"object",properties:{name:{type:"string"},type:{type:"string",enum:["openai","anthropic"]},baseUrl:{type:"string"},apiKey:{type:"string"},models:{type:"array",items:{type:"string"}},proxyEnabled:{type:"boolean"},enabled:{type:"boolean"}}}}},async(t,o)=>{let r=n.providerService.updateProvider(t.params.id,t.body);if(!r)throw B("Provider not found",404,"provider_not_found");return r}),n.delete("/providers/:id",{schema:{params:{type:"object",properties:{id:{type:"string"}},required:["id"]}}},async t=>{if(!n.providerService.deleteProvider(t.params.id))throw B("Provider not found",404,"provider_not_found");return{message:"Provider deleted successfully"}}),n.patch("/providers/:id/toggle",{schema:{params:{type:"object",properties:{id:{type:"string"}},required:["id"]},body:{type:"object",properties:{enabled:{type:"boolean"}},required:["enabled"]}}},async(t,o)=>{if(!n.providerService.toggleProvider(t.params.id,t.body.enabled))throw B("Provider not found",404,"provider_not_found");return{message:`Provider ${t.body.enabled?"enabled":"disabled"} successfully`}})}});var le,Lt=S(()=>{"use strict";le=class{constructor(e,t,o){this.configService=e;this.transformerService=t;this.logger=o;this.initializeCustomProviders()}providers=new Map;modelRoutes=new Map;initializeCustomProviders(){let e=this.configService.get("providers");if(e&&Array.isArray(e)){this.initializeFromProvidersArray(e);return}}initializeFromProvidersArray(e){e.forEach(t=>{try{if(!t.name||!t.api_base_url||!t.api_key)return;let o={};t.transformer&&Object.keys(t.transformer).forEach(r=>{r==="use"?Array.isArray(t.transformer.use)&&(o.use=t.transformer.use.map(s=>{if(Array.isArray(s)&&typeof s[0]=="string"){let a=this.transformerService.getTransformer(s[0]);if(a)return new a(s[1])}if(typeof s=="string"){let a=this.transformerService.getTransformer(s);return typeof a=="function"?new a:a}}).filter(s=>typeof s<"u")):Array.isArray(t.transformer[r]?.use)&&(o[r]={use:t.transformer[r].use.map(s=>{if(Array.isArray(s)&&typeof s[0]=="string"){let a=this.transformerService.getTransformer(s[0]);if(a)return new a(s[1])}if(typeof s=="string"){let a=this.transformerService.getTransformer(s);return typeof a=="function"?new a:a}}).filter(s=>typeof s<"u")})}),this.registerProvider({name:t.name,baseUrl:t.api_base_url,apiKey:t.api_key,models:t.models||[],quotaToken:t.quota_token,quotaSecToken:t.quota_sec_token,transformer:t.transformer?o:void 0,cacheMode:t.cache_mode||"exclusive",enabled:t.enabled!==!1,proxyEnabled:t.proxy_enabled===!0,wakeupEnabled:t.wakeup_enabled===!0,wakeupTime:t.wakeup_time||"06:00",wakeupModel:t.wakeup_model||""}),this.logger.info(`${t.name} provider registered`)}catch(o){this.logger.error(`${t.name} provider registered error: ${o}`)}})}registerProvider(e){let t={...e,enabled:e.enabled!==!1,proxyEnabled:e.proxyEnabled===!0,wakeupEnabled:e.wakeupEnabled===!0,wakeupTime:e.wakeupTime||"06:00",wakeupModel:e.wakeupModel||""};return this.providers.set(t.name,t),e.models.forEach(o=>{let r=`${t.name},${o}`,s={provider:t.name,model:o,fullModel:r};this.modelRoutes.set(r,s),this.modelRoutes.has(o)||this.modelRoutes.set(o,s)}),t}getProviders(){return Array.from(this.providers.values())}getProvider(e){return this.providers.get(e)}updateProvider(e,t){let o=this.providers.get(e);if(!o)return null;let r={...o,...t,updatedAt:new Date};return this.providers.set(e,r),t.models&&(o.models.forEach(s=>{let a=`${o.name},${s}`;this.modelRoutes.delete(a),this.modelRoutes.delete(s)}),t.models.forEach(s=>{let a=`${o.name},${s}`,l={provider:o.name,model:s,fullModel:a};this.modelRoutes.set(a,l),this.modelRoutes.has(s)||this.modelRoutes.set(s,l)})),r}deleteProvider(e){let t=this.providers.get(e);return t?(t.models.forEach(o=>{let r=`${t.name},${o}`;this.modelRoutes.delete(r),this.modelRoutes.delete(o)}),this.providers.delete(e),!0):!1}toggleProvider(e,t){let o=this.providers.get(e);if(!o)return!1;o.enabled=t;let r=this.configService.get("providers");if(r&&Array.isArray(r)){let s=r.find(a=>a.name===e);s&&(s.enabled=t)}return!0}resolveModelRoute(e){let t=this.modelRoutes.get(e);if(!t)return null;let o=this.providers.get(t.provider);return o?{provider:o,originalModel:e,targetModel:t.model}:null}getAvailableModelNames(){let e=[];return this.providers.forEach(t=>{t.enabled!==!1&&t.models.forEach(o=>{e.push(o),e.push(`${t.name},${o}`)})}),e}getModelRoutes(){return Array.from(this.modelRoutes.values())}parseTransformerConfig(e){return e?Array.isArray(e)?e.reduce((t,o)=>{if(Array.isArray(o)){let[r,s={}]=o;t[r]=s}else t[o]={};return t},{}):e:{}}async getAvailableModels(){let e=[];return this.providers.forEach(t=>{t.enabled!==!1&&t.models.forEach(o=>{e.push({id:o,object:"model",owned_by:t.name,provider:t.name}),e.push({id:`${t.name},${o}`,object:"model",owned_by:t.name,provider:t.name})})}),{object:"list",data:e}}}});var ms,gs=S(()=>{ms=n=>n<=0?"none":n<=1024?"low":n<=8192?"medium":"high"});var hs,ys=S(()=>{hs=(n,e)=>(n.includes("base64")&&(n=n.split("base64").pop(),n.startsWith(",")&&(n=n.slice(1))),`data:${e};base64,${n}`)});function Hc(n){return n.filter(e=>!!e?.function?.name).map(e=>({name:e.function.name,description:e.function.description,input_schema:e.function.parameters}))}function _s(n){let e=[],t=[],o=m=>{if(typeof m=="string"){t.push({type:"text",text:m});return}Array.isArray(m)&&m.forEach(g=>{if(typeof g=="string"){t.push({type:"text",text:g});return}g&&typeof g=="object"&&g.type==="text"&&g.text&&t.push({...g})})},r=()=>{let m=new Map;for(let g=0;g<t.length;g++){let y=t[g],p=y?.text??JSON.stringify(y),f=m.get(p);if(f===void 0){m.set(p,g);continue}!t[f]?.cache_control&&y?.cache_control&&(t[f]=y),t.splice(g,1),g--}};n.messages.forEach(m=>{m.role==="system"?o(m.content):e.push(m)}),r();let s=[];for(let m=0;m<e.length;m++){let g=e[m];if(g.role==="tool"){let y=g.content;try{typeof g.content=="string"&&(y=JSON.parse(g.content))}catch{}y!=null&&typeof y!="object"&&typeof y!="string"&&(y=String(y));let p={type:"tool_result",tool_use_id:g.tool_call_id,content:y};g.cache_control&&(p.cache_control=g.cache_control);let f=s[s.length-1];f&&f.role==="user"&&Array.isArray(f.content)?f.content.push(p):s.push({role:"user",content:[p]})}else if(g.role==="user"){let y=[];typeof g.content=="string"?y.push({type:"text",text:g.content}):Array.isArray(g.content)&&g.content.forEach(f=>{f&&typeof f=="object"&&f.type==="image_url"&&f.image_url?.url?y.push({type:"image",source:{type:"base64",media_type:f.media_type||"image/jpeg",data:f.image_url.url.split(",")[1]||f.image_url.url}}):y.push(f)});let p=s[s.length-1];p&&p.role==="user"&&Array.isArray(p.content)?p.content.push(...y):s.push({role:"user",content:y.length>0?y:[{type:"text",text:" "}]})}else if(g.role==="assistant"){let y=[];g.content&&(typeof g.content=="string"?y.push({type:"text",text:g.content}):Array.isArray(g.content)&&y.push(...g.content)),g.tool_calls&&g.tool_calls.length>0&&g.tool_calls.forEach(f=>{let _={};try{_=JSON.parse(f.function.arguments)}catch{_=f.function.arguments}y.push({type:"tool_use",id:f.id,name:f.function.name,input:_})}),g.thinking&&y.unshift({type:"thinking",thinking:g.thinking.content,signature:g.thinking.signature});let p=s[s.length-1];p&&p.role==="assistant"&&Array.isArray(p.content)?p.content.push(...y):s.push({role:"assistant",content:y.length>0?y:[{type:"text",text:" "}]})}}let a=()=>{let m=t.filter(g=>g?.cache_control).length;for(let g of s)Array.isArray(g.content)&&(m+=g.content.filter(y=>y?.cache_control).length);return m},l=m=>m&&typeof m=="object"?{...m}:{type:"ephemeral"},c=()=>{for(let m=s.length-1;m>=0;m--){let g=s[m]?.content;if(!Array.isArray(g))continue;let y=g.find(p=>p?.cache_control);if(y?.cache_control)return y.cache_control}for(let m=t.length-1;m>=0;m--)if(t[m]?.cache_control)return t[m].cache_control;return{type:"ephemeral"}},i=(m,g)=>{if(!Array.isArray(m?.content)||m.content.some(p=>p?.cache_control))return!1;let y=m.content.find(p=>p&&typeof p=="object"&&!p.cache_control);return y?(y.cache_control=l(g),!0):!1};(()=>{let m=4-a();if(m<=0||s.length===0)return;let g=s,y=c(),p=[];for(let f=g.length-1;f>=0;f--)g[f]?.role!=="user"||!Array.isArray(g[f].content)||p.push(f);for(let f of p){if(m<=0)break;i(g[f],y)&&m--}})();let d={messages:s,model:n.model,max_tokens:n.max_tokens||4096,temperature:n.temperature,stream:n.stream};if(t.length>0){let m=t.some(g=>g?.cache_control);d.system=m?t:t.map(g=>g.text||"").join(`
|
|
46
46
|
|
|
47
|
-
`)}return n.tools&&n.tools.length>0&&(d.tools=
|
|
48
|
-
`));let c=s.content.filter(u=>u.type==="tool_use"&&u.id);c.length&&(a.tool_calls=c.map(u=>({id:u.id,type:"function",function:{name:u.name,arguments:JSON.stringify(u.input||{})}})));let i=s.content.find(u=>u.type==="thinking");i&&(a.thinking={content:i.thinking,signature:i.signature}),t.push(a)}return}}});let r={messages:t,model:e.model,max_tokens:e.max_tokens,temperature:e.temperature,stream:e.stream,tools:e.tools?.length?this.convertAnthropicToolsToUnified(e.tools):void 0,tool_choice:e.tool_choice};return e.thinking&&(r.reasoning={effort:
|
|
47
|
+
`)}return n.tools&&n.tools.length>0&&(d.tools=Hc(n.tools),n.tool_choice&&(n.tool_choice==="auto"?d.tool_choice={type:"auto"}:n.tool_choice==="any"||n.tool_choice==="required"?d.tool_choice={type:"any"}:typeof n.tool_choice=="string"?d.tool_choice={type:"tool",name:n.tool_choice}:typeof n.tool_choice=="object"&&n.tool_choice.type==="function"&&(d.tool_choice={type:"tool",name:n.tool_choice.function.name}))),d}var ks=S(()=>{});import{v4 as io}from"uuid";var Ft,bs=S(()=>{"use strict";gs();bt();ys();ks();Ft=class{constructor(e){this.options=e;this.useBearer=this.options?.UseBearer??!1}name="Anthropic";endPoint="/v1/messages";useBearer;logger;async auth(e,t){let o={};return this.useBearer?(o.authorization=`Bearer ${t.apiKey}`,o["x-api-key"]=void 0):(o["x-api-key"]=t.apiKey,o.authorization=void 0),{body:e,config:{headers:o}}}async transformRequestOut(e){let t=[];if(e.system){if(typeof e.system=="string")t.push({role:"system",content:e.system});else if(Array.isArray(e.system)&&e.system.length){let s=e.system.filter(a=>a.type==="text"&&a.text).map(a=>({type:"text",text:a.text,cache_control:a.cache_control}));t.push({role:"system",content:s})}}let o=JSON.parse(JSON.stringify(e.messages||[]));o?.forEach(s=>{s.role==="system"&&t.push({role:"system",content:s.content})}),o?.forEach(s=>{if(s.role!=="system"&&(s.role==="user"||s.role==="assistant")){if(typeof s.content=="string"){t.push({role:s.role,content:s.content});return}if(Array.isArray(s.content)){if(s.role==="user"){let a=s.content.filter(c=>c.type==="tool_result"&&c.tool_use_id);a.length&&a.forEach(c=>{let i={role:"tool",content:typeof c.content=="string"?c.content:JSON.stringify(c.content),tool_call_id:c.tool_use_id,cache_control:c.cache_control};t.push(i)});let l=s.content.filter(c=>c.type==="text"&&c.text||c.type==="image"&&c.source);l.length&&t.push({role:"user",content:l.map(c=>c?.type==="image"?{type:"image_url",image_url:{url:c.source?.type==="base64"?hs(c.source.data,c.source.media_type):c.source.url},media_type:c.source.media_type}:c)})}else if(s.role==="assistant"){let a={role:"assistant",content:""},l=s.content.filter(u=>u.type==="text"&&u.text);l.length&&(a.content=l.map(u=>u.text).join(`
|
|
48
|
+
`));let c=s.content.filter(u=>u.type==="tool_use"&&u.id);c.length&&(a.tool_calls=c.map(u=>({id:u.id,type:"function",function:{name:u.name,arguments:JSON.stringify(u.input||{})}})));let i=s.content.find(u=>u.type==="thinking");i&&(a.thinking={content:i.thinking,signature:i.signature}),t.push(a)}return}}});let r={messages:t,model:e.model,max_tokens:e.max_tokens,temperature:e.temperature,stream:e.stream,tools:e.tools?.length?this.convertAnthropicToolsToUnified(e.tools):void 0,tool_choice:e.tool_choice};return e.thinking&&(r.reasoning={effort:ms(e.thinking.budget_tokens),enabled:e.thinking.type==="enabled"}),e.tool_choice&&(e.tool_choice.type==="tool"?r.tool_choice={type:"function",function:{name:e.tool_choice.name}}:r.tool_choice=e.tool_choice.type),r}async transformRequestIn(e,t,o){if(!this.isAnthropicMessagesEndpoint(t.baseUrl))return e;o&&o.req&&(o.req.isTargetAnthropic=!0);let r=_s(e),s={};return this.useBearer?(s.authorization=`Bearer ${t.apiKey}`,s["x-api-key"]=void 0):(s["x-api-key"]=t.apiKey,s.authorization=void 0),s["anthropic-version"]="2023-06-01",s["content-type"]="application/json",{body:r,config:{headers:s}}}isAnthropicMessagesEndpoint(e){try{return new URL(e.trim()).pathname.replace(/\/+$/,"").endsWith("/messages")}catch{return!1}}async transformResponseIn(e,t){if(t?.req?.isTargetAnthropic)return e;if(e.headers.get("Content-Type")?.includes("text/event-stream")){if(!e.body)throw new Error("Stream response body is null");let r=await this.convertOpenAIStreamToAnthropic(e.body,t);return new Response(r,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}else{let r=await e.json(),s=this.convertOpenAIResponseToAnthropic(r,t);return new Response(JSON.stringify(s),{headers:{"Content-Type":"application/json"}})}}convertAnthropicToolsToUnified(e){return e.map(t=>({type:"function",function:{name:t.name,description:t.description||"",parameters:t.input_schema}}))}async convertOpenAIStreamToAnthropic(e,t){return new ReadableStream({start:async r=>{let s=new TextEncoder,a=`msg_${Date.now()}`,l=null,c="unknown",i=!1,u=!1,d=!1,m=new Map,g=new Map,y=0,p=0,f=0,_=!1,k=!1,h=0,b=-1,x=()=>{let T=h;return h++,T},v=T=>{if(!_)try{r.enqueue(T);let A=new TextDecoder().decode(T);this.logger.debug({reqId:t.req.id,data:A,type:"send data"})}catch(A){if(A instanceof TypeError&&A.message.includes("Controller is already closed"))_=!0;else throw this.logger.debug({reqId:t.req.id,error:A instanceof Error?A.message:String(A),type:"send data error"}),A}},C=()=>{if(!_)try{if(!i){this.logger?.warn("[empty_stream] Upstream produced no data, closing silently"),r.close(),_=!0;return}if(b>=0){let A={type:"content_block_stop",index:b};v(s.encode(`event: content_block_stop
|
|
49
49
|
data: ${JSON.stringify(A)}
|
|
50
50
|
|
|
51
51
|
`)),b=-1}if(l)v(s.encode(`event: message_delta
|
|
@@ -88,14 +88,14 @@ data: ${JSON.stringify($)}
|
|
|
88
88
|
`))}}if(z?.delta?.annotations?.length&&!_&&!d){if(b>=0&&u){let $={type:"content_block_stop",index:b};v(s.encode(`event: content_block_stop
|
|
89
89
|
data: ${JSON.stringify($)}
|
|
90
90
|
|
|
91
|
-
`)),b=-1,u=!1}z?.delta?.annotations.forEach($=>{let L=x(),W={type:"content_block_start",index:L,content_block:{type:"web_search_tool_result",tool_use_id:`srvtoolu_${
|
|
91
|
+
`)),b=-1,u=!1}z?.delta?.annotations.forEach($=>{let L=x(),W={type:"content_block_start",index:L,content_block:{type:"web_search_tool_result",tool_use_id:`srvtoolu_${io()}`,content:[{type:"web_search_result",title:$.url_citation.title,url:$.url_citation.url}]}};v(s.encode(`event: content_block_start
|
|
92
92
|
data: ${JSON.stringify(W)}
|
|
93
93
|
|
|
94
94
|
`));let me={type:"content_block_stop",index:L};v(s.encode(`event: content_block_stop
|
|
95
95
|
data: ${JSON.stringify(me)}
|
|
96
96
|
|
|
97
|
-
`)),b=-1})}if(z?.delta?.tool_calls&&!_&&!d){f++;let $=new Set;for(let L of z.delta.tool_calls){if(_)break;let W=L.index??0;if($.has(W))continue;if($.add(W),!g.has(W)){if(b>=0){let
|
|
98
|
-
data: ${JSON.stringify(
|
|
97
|
+
`)),b=-1})}if(z?.delta?.tool_calls&&!_&&!d){f++;let $=new Set;for(let L of z.delta.tool_calls){if(_)break;let W=L.index??0;if($.has(W))continue;if($.add(W),!g.has(W)){if(b>=0){let ka={type:"content_block_stop",index:b};v(s.encode(`event: content_block_stop
|
|
98
|
+
data: ${JSON.stringify(ka)}
|
|
99
99
|
|
|
100
100
|
`)),b=-1}let D=x();g.set(W,D);let K=L.id||`call_ccr_${W}`,H=L.function?.name||`tool_${W}`,I={type:"content_block_start",index:D,content_block:{type:"tool_use",id:K,name:H,input:{}}};v(s.encode(`event: content_block_start
|
|
101
101
|
data: ${JSON.stringify(I)}
|
|
@@ -109,7 +109,7 @@ data: ${JSON.stringify(I)}
|
|
|
109
109
|
`))}catch(H){console.error(H)}}}}}if(z?.finish_reason&&!_&&!d){if(p===0&&f===0&&console.error("Warning: No content in the stream response!"),b>=0){let $={type:"content_block_stop",index:b};v(s.encode(`event: content_block_stop
|
|
110
110
|
data: ${JSON.stringify($)}
|
|
111
111
|
|
|
112
|
-
`)),b=-1}if(!_){let L={stop:"end_turn",length:"max_tokens",tool_calls:"tool_use",content_filter:"stop_sequence"}[z.finish_reason]||"end_turn";l?l.delta={...l.delta,stop_reason:L,stop_sequence:null}:l={type:"message_delta",delta:{stop_reason:L,stop_sequence:null},usage:{input_tokens:0,output_tokens:0,cache_read_input_tokens:0}}}d=!0}}catch(F){this.logger?.error(`parseError: ${F.name} message: ${F.message} stack: ${F.stack} data: ${N}`)}}}C()}catch(T){if(!_)try{r.error(T)}catch(A){console.error(A)}}finally{if(R)try{R.releaseLock()}catch(T){console.error(T)}}},cancel:r=>{this.logger.debug({reqId:t.req.id},`cancle stream: ${r}`)}})}convertOpenAIResponseToAnthropic(e,t){this.logger.debug({reqId:t.req.id,response:e},"Original OpenAI response");try{let o=e.choices[0];if(!o)throw new Error("No choices found in OpenAI response");let r=[];if(o.message.annotations){let c=`srvtoolu_${
|
|
112
|
+
`)),b=-1}if(!_){let L={stop:"end_turn",length:"max_tokens",tool_calls:"tool_use",content_filter:"stop_sequence"}[z.finish_reason]||"end_turn";l?l.delta={...l.delta,stop_reason:L,stop_sequence:null}:l={type:"message_delta",delta:{stop_reason:L,stop_sequence:null},usage:{input_tokens:0,output_tokens:0,cache_read_input_tokens:0}}}d=!0}}catch(F){this.logger?.error(`parseError: ${F.name} message: ${F.message} stack: ${F.stack} data: ${N}`)}}}C()}catch(T){if(!_)try{r.error(T)}catch(A){console.error(A)}}finally{if(R)try{R.releaseLock()}catch(T){console.error(T)}}},cancel:r=>{this.logger.debug({reqId:t.req.id},`cancle stream: ${r}`)}})}convertOpenAIResponseToAnthropic(e,t){this.logger.debug({reqId:t.req.id,response:e},"Original OpenAI response");try{let o=e.choices[0];if(!o)throw new Error("No choices found in OpenAI response");let r=[];if(o.message.annotations){let c=`srvtoolu_${io()}`;r.push({type:"server_tool_use",id:c,name:"web_search",input:{query:""}}),r.push({type:"web_search_tool_result",tool_use_id:c,content:o.message.annotations.map(i=>({type:"web_search_result",url:i.url_citation.url,title:i.url_citation.title}))})}o.message.content&&r.push({type:"text",text:o.message.content}),o.message.tool_calls&&o.message.tool_calls.length>0&&o.message.tool_calls.forEach(c=>{let i={};try{let u=c.function.arguments||"{}";typeof u=="object"?i=u:typeof u=="string"&&(i=JSON.parse(u))}catch{i={text:c.function.arguments||""}}r.push({type:"tool_use",id:c.id,name:c.function.name,input:i})}),o.message?.thinking?.content&&r.push({type:"thinking",thinking:o.message.thinking.content,signature:o.message.thinking.signature});let s=e.usage?.prompt_tokens_details?.cached_tokens||0,a=(e.usage?.prompt_tokens||0)-s,l={id:e.id?.startsWith("msg_")?e.id:`msg_${io().replace(/-/g,"")}`,type:"message",role:"assistant",model:e.model,content:r,stop_reason:o.finish_reason==="stop"?"end_turn":o.finish_reason==="length"?"max_tokens":o.finish_reason==="tool_calls"?"tool_use":o.finish_reason==="content_filter"?"stop_sequence":"end_turn",stop_sequence:null,usage:{input_tokens:a,cache_creation_input_tokens:0,cache_read_input_tokens:s,output_tokens:e.usage?.completion_tokens||0,server_tool_use:{web_search_requests:0,web_fetch_requests:0},service_tier:"standard",cache_creation:{ephemeral_1h_input_tokens:0,ephemeral_5m_input_tokens:0},inference_geo:"",iterations:[],speed:"standard"},stop_details:null,context_management:null};return this.logger.debug({reqId:t.req.id,result:l},"Conversion complete, final Anthropic response"),l}catch{throw B(`Provider error: ${JSON.stringify(e)}`,500,"provider_error")}}}});function Jc(n,e){n.includes("null")&&(e.nullable=!0);let t=n.filter(o=>o!=="null");if(t.length===1){let o=t[0].toUpperCase();e.type=Object.values(Ie).includes(o)?o:Ie.TYPE_UNSPECIFIED}else{e.anyOf=[];for(let o of t){let r=o.toUpperCase();e.anyOf.push({type:Object.values(Ie).includes(r)?r:Ie.TYPE_UNSPECIFIED})}}}function tt(n){let e={},t=["items"],o=["anyOf"],r=["properties"];if(n.type&&n.anyOf)throw new Error("type and anyOf cannot be both populated.");let s=n.anyOf;s!=null&&Array.isArray(s)&&s.length==2&&(s[0]&&s[0].type==="null"?(e.nullable=!0,n=s[1]):s[1]&&s[1].type==="null"&&(e.nullable=!0,n=s[0])),n.type&&Array.isArray(n.type)&&Jc(n.type,e);for(let[a,l]of Object.entries(n))if(l!=null)if(a=="type"){if(l==="null")throw new Error("type: null can not be the only possible type for the field.");if(Array.isArray(l))continue;let c=l.toUpperCase();e.type=Object.values(Ie).includes(c)?c:Ie.TYPE_UNSPECIFIED}else if(t.includes(a))e[a]=tt(l);else if(o.includes(a)){let c=[];for(let i of l){if(i.type=="null"){e.nullable=!0;continue}c.push(tt(i))}e[a]=c}else if(r.includes(a)){let c={};for(let[i,u]of Object.entries(l))c[i]=tt(u);e[a]=c}else{if(a==="additionalProperties")continue;e[a]=l}return e}function Bc(n){if(n.functionDeclarations)for(let e of n.functionDeclarations)e.parameters&&(Object.keys(e.parameters).includes("$schema")?e.parametersJsonSchema||(e.parametersJsonSchema=e.parameters,delete e.parameters):e.parameters=tt(e.parameters)),e.response&&(Object.keys(e.response).includes("$schema")?e.responseJsonSchema||(e.responseJsonSchema=e.response,delete e.response):e.response=tt(e.response));return n}function Ut(n){let e=[],t=n.tools?.filter(c=>c.function.name!=="web_search")?.map(c=>({name:c.function.name,description:c.function.description,parametersJsonSchema:c.function.parameters}));t?.length&&e.push(Bc({functionDeclarations:t})),n.tools?.find(c=>c.function.name==="web_search")&&e.push({googleSearch:{}});let r=[],s=n.messages.filter(c=>c.role==="tool");n.messages.filter(c=>c.role!=="tool").forEach(c=>{let i;c.role==="assistant"?i="model":(["user","system"].includes(c.role),i="user");let u=[];if(typeof c.content=="string"){let d={text:c.content};c.thinking?.signature&&(d.thoughtSignature=c.thinking.signature),u.push(d)}else Array.isArray(c.content)?u.push(...c.content.map(d=>{if(d.type==="text")return{text:d.text||""};if(d.type==="image_url")return d.image_url.url.startsWith("http")?{file_data:{mime_type:d.media_type,file_uri:d.image_url.url}}:{inlineData:{mime_type:d.media_type,data:d.image_url.url?.split(",")?.pop()||d.image_url.url}}})):c.content&&typeof c.content=="object"&&(c.content.text?u.push({text:c.content.text}):u.push({text:JSON.stringify(c.content)}));if(Array.isArray(c.tool_calls)&&u.push(...c.tool_calls.map(d=>{let m={functionCall:{id:d.id||`tool_${Math.random().toString(36).substring(2,15)}`,name:d.function.name,args:JSON.parse(d.function.arguments||"{}")}};return c.thinking?.signature&&(m.thoughtSignature=c.thinking.signature),m})),u.length===0&&u.push({text:""}),r.push({role:i,parts:u}),i==="model"&&c.tool_calls){let d=c.tool_calls.map(m=>{let g=s.find(y=>y.tool_call_id===m.id);return{functionResponse:{name:m?.function?.name,response:{result:g?.content}}}});r.push({role:"user",parts:d})}});let a={};if(n.reasoning&&n.reasoning.effort&&n.reasoning.effort!=="none")if(a.thinkingConfig={includeThoughts:!0},n.model.includes("gemini-3"))a.thinkingConfig.thinkingLevel=n.reasoning.effort;else{let c=n.model.includes("pro")?[128,32768]:[0,24576],i,u=n.reasoning.max_tokens;typeof u<"u"&&(u>=c[0]&&u<=c[1]?i=u:u<c[0]?i=c[0]:u>c[1]&&(i=c[1]),a.thinkingConfig.thinkingBudget=i)}let l={contents:r,tools:e.length?e:void 0,generationConfig:a};if(n.tool_choice){let c={functionCallingConfig:{}};n.tool_choice==="auto"?c.functionCallingConfig.mode="auto":n.tool_choice==="none"?c.functionCallingConfig.mode="none":n.tool_choice==="required"?c.functionCallingConfig.mode="any":n.tool_choice?.function?.name&&(c.functionCallingConfig.mode="any",c.functionCallingConfig.allowedFunctionNames=[n.tool_choice?.function?.name]),l.toolConfig=c}return l}function Dt(n){let e=n.contents,t=n.tools,o=n.model,r=n.max_tokens,s=n.temperature,a=n.stream,l=n.tool_choice,c={messages:[],model:o,max_tokens:r,temperature:s,stream:a,tool_choice:l};return Array.isArray(e)&&e.forEach(i=>{typeof i=="string"?c.messages.push({role:"user",content:i}):typeof i.text=="string"?c.messages.push({role:"user",content:i.text||null}):i.role==="user"?c.messages.push({role:"user",content:i?.parts?.map(u=>({type:"text",text:u.text||""}))||[]}):i.role==="model"&&c.messages.push({role:"assistant",content:i?.parts?.map(u=>({type:"text",text:u.text||""}))||[]})}),Array.isArray(t)&&(c.tools=[],t.forEach(i=>{Array.isArray(i.functionDeclarations)&&i.functionDeclarations.forEach(u=>{c.tools.push({type:"function",function:{name:u.name,description:u.description,parameters:u.parameters}})})})),c}async function jt(n,e,t){if(n.headers.get("Content-Type")?.includes("application/json")){let o=await n.json();t?.debug({response:o},`${e} response:`);let r="",s="",a=o.candidates[0]?.content?.parts||[],l=[];for(let d of a)d.text&&d.thought===!0?r+=d.text:l.push(d);s=a.find(d=>d.thoughtSignature)?.thoughtSignature;let c=l?.filter(d=>d.functionCall)?.map(d=>({id:d.functionCall?.id||`tool_${Math.random().toString(36).substring(2,15)}`,type:"function",function:{name:d.functionCall?.name,arguments:JSON.stringify(d.functionCall?.args||{})}}))||[],i=l?.filter(d=>d.text)?.map(d=>d.text)?.join(`
|
|
113
113
|
`)||"",u={id:o.responseId,choices:[{finish_reason:o.candidates[0].finishReason?.toLowerCase()||null,index:0,message:{content:i,role:"assistant",tool_calls:c.length>0?c:void 0,...s&&{thinking:{content:r||"(no content)",signature:s}}}}],created:parseInt(new Date().getTime()/1e3+"",10),model:o.modelVersion,object:"chat.completion",usage:{completion_tokens:o.usageMetadata?.candidatesTokenCount||0,prompt_tokens:o.usageMetadata?.promptTokenCount||0,prompt_tokens_details:{cached_tokens:o.usageMetadata?.cachedContentTokenCount||0},total_tokens:o.usageMetadata?.totalTokenCount||0,output_tokens_details:{reasoning_tokens:o.usageMetadata?.thoughtsTokenCount||0}}};return new Response(JSON.stringify(u),{status:n.status,statusText:n.statusText,headers:n.headers})}else if(n.headers.get("Content-Type")?.includes("stream")){if(!n.body)return n;let o=new TextDecoder,r=new TextEncoder,s=!1,a=!1,l=!1,c="",i=0,u=-1,d=new ReadableStream({async start(m){let g=async(f,_)=>{if(f.startsWith("data: ")){let k=f.slice(6).trim();if(k){t?.debug({chunkStr:k},`${e} chunk:`);try{let h=JSON.parse(k);if(!h.candidates||!h.candidates[0]){t?.debug({chunkStr:k},"Invalid chunk structure");return}let b=h.candidates[0],x=b.content?.parts||[];x.filter(T=>T.text&&T.thought===!0).forEach(T=>{l||(l=!0);let A={choices:[{delta:{role:"assistant",content:null,thinking:{content:T.text}},finish_reason:null,index:i,logprobs:null}],created:parseInt(new Date().getTime()/1e3+"",10),id:h.responseId||"",model:h.modelVersion||"",object:"chat.completion.chunk",system_fingerprint:"fp_a49d71b8a1"};_.enqueue(r.encode(`data: ${JSON.stringify(A)}
|
|
114
114
|
|
|
115
115
|
`))});let v=x.find(T=>T.thoughtSignature)?.thoughtSignature;if(v&&!s){if(!l){let A={choices:[{delta:{role:"assistant",content:null,thinking:{content:"(no content)"}},finish_reason:null,index:i,logprobs:null}],created:parseInt(new Date().getTime()/1e3+"",10),id:h.responseId||"",model:h.modelVersion||"",object:"chat.completion.chunk",system_fingerprint:"fp_a49d71b8a1"};_.enqueue(r.encode(`data: ${JSON.stringify(A)}
|
|
@@ -128,10 +128,10 @@ data: ${JSON.stringify($)}
|
|
|
128
128
|
`)),!a&&R&&(a=!0)}C.length>0&&(C.forEach(T=>{i++,u++;let A={choices:[{delta:{role:"assistant",tool_calls:[{...T,index:u}]},finish_reason:b.finishReason?.toLowerCase()||null,index:i,logprobs:null}],created:parseInt(new Date().getTime()/1e3+"",10),id:h.responseId||"",model:h.modelVersion||"",object:"chat.completion.chunk",system_fingerprint:"fp_a49d71b8a1",usage:{completion_tokens:h.usageMetadata?.candidatesTokenCount||0,prompt_tokens:h.usageMetadata?.promptTokenCount||0,prompt_tokens_details:{cached_tokens:h.usageMetadata?.cachedContentTokenCount||0},total_tokens:h.usageMetadata?.totalTokenCount||0,output_tokens_details:{reasoning_tokens:h.usageMetadata?.thoughtsTokenCount||0}}};b?.groundingMetadata?.groundingChunks?.length&&(A.choices[0].delta.annotations=b.groundingMetadata.groundingChunks.map((w,O)=>{let P=b?.groundingMetadata?.groundingSupports?.filter(E=>E.groundingChunkIndices?.includes(O));return{type:"url_citation",url_citation:{url:w?.web?.uri||"",title:w?.web?.title||"",content:P?.[0]?.segment?.text||"",start_index:P?.[0]?.segment?.startIndex||0,end_index:P?.[0]?.segment?.endIndex||0}}})),_.enqueue(r.encode(`data: ${JSON.stringify(A)}
|
|
129
129
|
|
|
130
130
|
`))}),!a&&R&&(a=!0))}catch(h){t?.error(`Error parsing ${e} stream chunk`,k,h.message)}}}},y=n.body.getReader(),p="";try{for(;;){let{done:f,value:_}=await y.read();if(f){p&&await g(p,m);break}p+=o.decode(_,{stream:!0});let k=p.split(`
|
|
131
|
-
`);p=k.pop()||"";for(let h of k)await g(h,m)}}catch(f){m.error(f)}finally{m.close()}}});return new Response(d,{status:n.status,statusText:n.statusText,headers:n.headers})}}var Ie,
|
|
131
|
+
`);p=k.pop()||"";for(let h of k)await g(h,m)}}catch(f){m.error(f)}finally{m.close()}}});return new Response(d,{status:n.status,statusText:n.statusText,headers:n.headers})}}var Ie,ao=S(()=>{"use strict";Ie={TYPE_UNSPECIFIED:"TYPE_UNSPECIFIED",STRING:"STRING",NUMBER:"NUMBER",INTEGER:"INTEGER",BOOLEAN:"BOOLEAN",ARRAY:"ARRAY",OBJECT:"OBJECT",NULL:"NULL"}});var zt,xs=S(()=>{"use strict";ao();zt=class{name="gemini";endPoint="/v1beta/models/:modelAndAction";async transformRequestIn(e,t){return{body:Ut(e),config:{url:new URL(`./${e.model}:${e.stream?"streamGenerateContent?alt=sse":"generateContent"}`,t.baseUrl),headers:{"x-goog-api-key":t.apiKey,Authorization:void 0}}}}transformRequestOut=Dt;async transformResponseOut(e){return jt(e,this.name,this.logger)}}});async function Wc(){try{let{GoogleAuth:n}=await import("google-auth-library");return(await(await new n({scopes:["https://www.googleapis.com/auth/cloud-platform"]}).getClient()).getAccessToken()).token||""}catch(n){throw console.error("Error getting access token:",n),new Error(`Failed to get access token for Vertex AI. Please ensure you have set up authentication using one of these methods:
|
|
132
132
|
1. Set GOOGLE_APPLICATION_CREDENTIALS to point to service account key file
|
|
133
133
|
2. Run "gcloud auth application-default login"
|
|
134
|
-
3. Use Google Cloud environment with default service account`)}}var Ht,
|
|
134
|
+
3. Use Google Cloud environment with default service account`)}}var Ht,Cs=S(()=>{"use strict";ao();Ht=class{name="vertex-gemini";async transformRequestIn(e,t){let o=process.env.GOOGLE_CLOUD_PROJECT,r=process.env.GOOGLE_CLOUD_LOCATION||"us-central1";if(!o&&process.env.GOOGLE_APPLICATION_CREDENTIALS)try{let l=(await import("fs")).readFileSync(process.env.GOOGLE_APPLICATION_CREDENTIALS,"utf8"),c=JSON.parse(l);c&&c.project_id&&(o=c.project_id)}catch(a){console.error("Error extracting project_id from GOOGLE_APPLICATION_CREDENTIALS:",a)}if(!o)throw new Error("Project ID is required for Vertex AI. Set GOOGLE_CLOUD_PROJECT environment variable or ensure project_id is in GOOGLE_APPLICATION_CREDENTIALS file.");let s=await Wc();return{body:Ut(e),config:{url:new URL(`./v1beta1/projects/${o}/locations/${r}/publishers/google/models/${e.model}:${e.stream?"streamGenerateContent":"generateContent"}`,t.baseUrl.endsWith("/")?t.baseUrl:t.baseUrl+"/"||`https://${r}-aiplatform.googleapis.com`),headers:{Authorization:`Bearer ${s}`,"x-goog-api-key":void 0}}}}async transformRequestOut(e){return Dt(e)}async transformResponseOut(e){return jt(e,this.name)}}});var Jt,Ts=S(()=>{"use strict";Jt=class{name="deepseek";async transformRequestIn(e){e.max_tokens&&e.max_tokens>8192&&(e.max_tokens=8192);let t=e.model?.includes("reasoner")||e.model?.includes("v4")||e.model?.includes("pro")||e.model?.includes("think"),o=e.thinking||e.reasoning?.enabled||e.messages.some(r=>r.thinking?.content)||t;return o&&e.tool_choice&&delete e.tool_choice,e.messages.forEach(r=>{if(r.role==="assistant"){let s=r.thinking?.content,a=r.thinking?.signature,l="";if(typeof r.content=="string"){let i=/<thinking>([\s\S]*?)<\/thinking>/g.exec(r.content);i&&(l=i[1].trim(),r.content=r.content.replace(i[0],"").trim())}s&&typeof s=="string"&&s.trim()?(r.reasoning_content=s,a&&(r.reasoning_content_signature=a)):l&&(r.reasoning_content=l),o&&!r.reasoning_content&&(r.reasoning_content=" "),r.thinking&&delete r.thinking}}),e}async transformResponseOut(e){if(e.headers.get("Content-Type")?.includes("application/json")){let t=await e.json();return new Response(JSON.stringify(t),{status:e.status,statusText:e.statusText,headers:e.headers})}else if(e.headers.get("Content-Type")?.includes("stream")){if(!e.body)return e;let t=new TextDecoder,o=new TextEncoder,r="",s=!1,a="",l=new ReadableStream({async start(c){let i=e.body.getReader(),u=(m,g,y)=>{let p=m.split(`
|
|
135
135
|
`);for(let f of p)f.trim()&&g.enqueue(y.encode(f+`
|
|
136
136
|
`))},d=(m,g)=>{let{controller:y,encoder:p}=g;if(m.startsWith("data: ")&&m.trim()!=="data: [DONE]")try{let f=JSON.parse(m.slice(6));if(f.choices?.[0]?.delta?.reasoning_content){g.appendReasoningContent(f.choices[0].delta.reasoning_content);let _={...f,choices:[{...f.choices[0],delta:{...f.choices[0].delta,thinking:{content:f.choices[0].delta.reasoning_content}}}]};delete _.choices[0].delta.reasoning_content;let k=`data: ${JSON.stringify(_)}
|
|
137
137
|
|
|
@@ -145,7 +145,7 @@ data: ${JSON.stringify($)}
|
|
|
145
145
|
`))}else y.enqueue(p.encode(m+`
|
|
146
146
|
`))};try{for(;;){let{done:m,value:g}=await i.read();if(m){a.trim()&&u(a,c,o);break}let y=t.decode(g,{stream:!0});a+=y;let p=a.split(`
|
|
147
147
|
`);a=p.pop()||"";for(let f of p)if(f.trim())try{d(f,{controller:c,encoder:o,reasoningContent:()=>r,appendReasoningContent:_=>r+=_,isReasoningComplete:()=>s,setReasoningComplete:_=>s=_})}catch(_){console.error("Error processing line:",f,_),c.enqueue(o.encode(f+`
|
|
148
|
-
`))}}}catch(m){console.error("Stream error:",m),c.error(m)}finally{try{i.releaseLock()}catch(m){console.error("Error releasing reader lock:",m)}c.close()}}});return new Response(l,{status:e.status,statusText:e.statusText,headers:{"Content-Type":e.headers.get("Content-Type")||"text/plain","Cache-Control":"no-cache",Connection:"keep-alive"}})}return e}}});var Bt,
|
|
148
|
+
`))}}}catch(m){console.error("Stream error:",m),c.error(m)}finally{try{i.releaseLock()}catch(m){console.error("Error releasing reader lock:",m)}c.close()}}});return new Response(l,{status:e.status,statusText:e.statusText,headers:{"Content-Type":e.headers.get("Content-Type")||"text/plain","Cache-Control":"no-cache",Connection:"keep-alive"}})}return e}}});var Bt,vs=S(()=>{"use strict";Bt=class{name="tooluse";transformRequestIn(e){return e.messages.push({role:"system",content:"<system-reminder>Tool mode is active. The user expects you to proactively execute the most suitable tool to help complete the task. \nBefore invoking a tool, you must carefully evaluate whether it matches the current task. If no available tool is appropriate for the task, you MUST call the `ExitTool` to exit tool mode \u2014 this is the only valid way to terminate tool mode.\nAlways prioritize completing the user's task effectively and efficiently by using tools whenever appropriate.</system-reminder>"}),e.tools?.length&&(e.tool_choice="required",e.tools.push({type:"function",function:{name:"ExitTool",description:`Use this tool when you are in tool mode and have completed the task. This is the only valid way to exit tool mode.
|
|
149
149
|
IMPORTANT: Before using this tool, ensure that none of the available tools are applicable to the current task. You must evaluate all available options \u2014 only if no suitable tool can help you complete the task should you use ExitTool to terminate tool mode.
|
|
150
150
|
Examples:
|
|
151
151
|
1. Task: "Use a tool to summarize this document" \u2014 Do not use ExitTool if a summarization tool is available.
|
|
@@ -159,7 +159,7 @@ Examples:
|
|
|
159
159
|
`))}else y.enqueue(p.encode(m+`
|
|
160
160
|
`))};try{for(;;){let{done:m,value:g}=await i.read();if(m){a.trim()&&u(a,c,o);break}let y=t.decode(g,{stream:!0});a+=y;let p=a.split(`
|
|
161
161
|
`);a=p.pop()||"";for(let f of p)if(f.trim())try{d(f,{controller:c,encoder:o,exitToolIndex:()=>r,setExitToolIndex:_=>r=_,exitToolResponse:()=>s,appendExitToolResponse:_=>s+=_})}catch(_){console.error("Error processing line:",f,_),c.enqueue(o.encode(f+`
|
|
162
|
-
`))}}}catch(m){console.error("Stream error:",m),c.error(m)}finally{try{i.releaseLock()}catch(m){console.error("Error releasing reader lock:",m)}c.close()}}});return new Response(l,{status:e.status,statusText:e.statusText,headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}return e}}});import{v4 as
|
|
162
|
+
`))}}}catch(m){console.error("Stream error:",m),c.error(m)}finally{try{i.releaseLock()}catch(m){console.error("Error releasing reader lock:",m)}c.close()}}});return new Response(l,{status:e.status,statusText:e.statusText,headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}return e}}});import{v4 as Gc}from"uuid";var Wt,Rs=S(()=>{"use strict";Wt=class{constructor(e){this.options=e}static TransformerName="openrouter";async transformRequestIn(e){return e.model.includes("claude")?e.messages.forEach(t=>{Array.isArray(t.content)&&t.content.forEach(o=>{o.type==="image_url"&&(o.image_url.url.startsWith("http")||(o.image_url.url=`data:${o.media_type};base64,${o.image_url.url}`),delete o.media_type)})}):e.messages.forEach(t=>{Array.isArray(t.content)?t.content.forEach(o=>{o.cache_control&&delete o.cache_control,o.type==="image_url"&&(o.image_url.url.startsWith("http")||(o.image_url.url=`${o.image_url.url}`),delete o.media_type)}):t.cache_control&&delete t.cache_control}),Object.assign(e,this.options||{}),e}async transformResponseOut(e){if(e.headers.get("Content-Type")?.includes("application/json")){let t=await e.json();return new Response(JSON.stringify(t),{status:e.status,statusText:e.statusText,headers:e.headers})}else if(e.headers.get("Content-Type")?.includes("stream")){if(!e.body)return e;let t=new TextDecoder,o=new TextEncoder,r=!1,s="",a=!1,l=!1,c="",i=new ReadableStream({async start(u){let d=e.body.getReader(),m=(y,p,f)=>{let _=y.split(`
|
|
163
163
|
`);for(let k of _)k.trim()&&p.enqueue(f.encode(k+`
|
|
164
164
|
`))},g=(y,p)=>{let{controller:f,encoder:_}=p;if(y.startsWith("data: ")&&y.trim()!=="data: [DONE]"){let k=y.slice(6);try{let h=JSON.parse(k);if(h.usage&&(this.logger?.debug({usage:h.usage,hasToolCall:l},"usage"),h.choices[0].finish_reason=l?"tool_calls":"stop"),h.choices?.[0]?.finish_reason==="error"){f.enqueue(_.encode(`data: ${JSON.stringify({error:h.choices?.[0].error})}
|
|
165
165
|
|
|
@@ -169,7 +169,7 @@ Examples:
|
|
|
169
169
|
|
|
170
170
|
`;f.enqueue(_.encode(O));let P={...h,choices:[{...h.choices?.[0],delta:{...h.choices[0].delta,content:A}}]};P.choices?.[0]?.delta&&(delete P.choices[0].delta.reasoning,delete P.choices[0].delta.reasoning_content);let E=`data: ${JSON.stringify(P)}
|
|
171
171
|
|
|
172
|
-
`;f.enqueue(_.encode(E));return}h.choices?.[0]?.delta?.reasoning&&delete h.choices[0].delta.reasoning,h.choices?.[0]?.delta?.reasoning_content&&delete h.choices[0].delta.reasoning_content,h.choices?.[0]?.delta?.tool_calls?.length&&!Number.isNaN(parseInt(h.choices?.[0]?.delta?.tool_calls[0].id,10))&&h.choices?.[0]?.delta?.tool_calls.forEach(T=>{T.id=`call_${
|
|
172
|
+
`;f.enqueue(_.encode(E));return}h.choices?.[0]?.delta?.reasoning&&delete h.choices[0].delta.reasoning,h.choices?.[0]?.delta?.reasoning_content&&delete h.choices[0].delta.reasoning_content,h.choices?.[0]?.delta?.tool_calls?.length&&!Number.isNaN(parseInt(h.choices?.[0]?.delta?.tool_calls[0].id,10))&&h.choices?.[0]?.delta?.tool_calls.forEach(T=>{T.id=`call_${Gc()}`}),h.choices?.[0]?.delta?.tool_calls?.length&&!l&&(l=!0);let x=h.choices?.[0]?.delta,v=x&&Object.keys(x).length>0,C=h.choices?.[0]?.finish_reason,R=h.usage;if(v||C||R){let T=`data: ${JSON.stringify(h)}
|
|
173
173
|
|
|
174
174
|
`;f.enqueue(_.encode(T))}}catch{f.enqueue(_.encode(y+`
|
|
175
175
|
`))}}else f.enqueue(_.encode(y+`
|
|
@@ -177,9 +177,9 @@ Examples:
|
|
|
177
177
|
`);c=k.pop()||"";for(let h of k)if(h.trim())try{g(h,{controller:u,encoder:o,hasTextContent:()=>r,setHasTextContent:b=>r=b,reasoningContent:()=>s,appendReasoningContent:b=>s+=b,isReasoningComplete:()=>a,setReasoningComplete:b=>a=b})}catch(b){console.error("Error processing line:",h,b),u.enqueue(o.encode(h+`
|
|
178
178
|
`))}continue}let _=c.split(`
|
|
179
179
|
`);c=_.pop()||"";for(let k of _)if(k.trim())try{g(k,{controller:u,encoder:o,hasTextContent:()=>r,setHasTextContent:h=>r=h,reasoningContent:()=>s,appendReasoningContent:h=>s+=h,isReasoningComplete:()=>a,setReasoningComplete:h=>a=h})}catch(h){console.error("Error processing line:",k,h),u.enqueue(o.encode(k+`
|
|
180
|
-
`))}}}catch(y){console.error("Stream error:",y),u.error(y)}finally{try{d.releaseLock()}catch(y){console.error("Error releasing reader lock:",y)}u.close()}}});return new Response(i,{status:e.status,statusText:e.statusText,headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}return e}}});var Gt,
|
|
180
|
+
`))}}}catch(y){console.error("Stream error:",y),u.error(y)}finally{try{d.releaseLock()}catch(y){console.error("Error releasing reader lock:",y)}u.close()}}});return new Response(i,{status:e.status,statusText:e.statusText,headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}return e}}});var Gt,ws=S(()=>{"use strict";Gt=class{constructor(e){this.options=e;this.max_tokens=this.options?.max_tokens}static TransformerName="maxtoken";max_tokens;async transformRequestIn(e){return e.max_tokens&&e.max_tokens>this.max_tokens&&(e.max_tokens=this.max_tokens),e}}});import{v4 as Vc}from"uuid";var Vt,Ss=S(()=>{"use strict";Vt=class{name="groq";async transformRequestIn(e){return e.messages.forEach(t=>{Array.isArray(t.content)?t.content.forEach(o=>{o.cache_control&&delete o.cache_control}):t.cache_control&&delete t.cache_control}),Array.isArray(e.tools)&&e.tools.forEach(t=>{delete t.function.parameters.$schema}),e}async transformResponseOut(e){if(e.headers.get("Content-Type")?.includes("application/json")){let t=await e.json();return new Response(JSON.stringify(t),{status:e.status,statusText:e.statusText,headers:e.headers})}else if(e.headers.get("Content-Type")?.includes("stream")){if(!e.body)return e;let t=new TextDecoder,o=new TextEncoder,r=!1,s="",a=!1,l="",c=new ReadableStream({async start(i){let u=e.body.getReader(),d=(g,y,p)=>{let f=g.split(`
|
|
181
181
|
`);for(let _ of f)_.trim()&&y.enqueue(p.encode(_+`
|
|
182
|
-
`))},m=(g,y)=>{let{controller:p,encoder:f}=y;if(g.startsWith("data: ")&&g.trim()!=="data: [DONE]"){let _=g.slice(6);try{let k=JSON.parse(_);if(k.error)throw new Error(JSON.stringify(k));k.choices?.[0]?.delta?.content&&!y.hasTextContent()&&y.setHasTextContent(!0),k.choices?.[0]?.delta?.tool_calls?.length&&k.choices?.[0]?.delta?.tool_calls.forEach(b=>{b.id=`call_${
|
|
182
|
+
`))},m=(g,y)=>{let{controller:p,encoder:f}=y;if(g.startsWith("data: ")&&g.trim()!=="data: [DONE]"){let _=g.slice(6);try{let k=JSON.parse(_);if(k.error)throw new Error(JSON.stringify(k));k.choices?.[0]?.delta?.content&&!y.hasTextContent()&&y.setHasTextContent(!0),k.choices?.[0]?.delta?.tool_calls?.length&&k.choices?.[0]?.delta?.tool_calls.forEach(b=>{b.id=`call_${Vc()}`}),k.choices?.[0]?.delta?.tool_calls?.length&&y.hasTextContent()&&(typeof k.choices[0].index=="number"?k.choices[0].index+=1:k.choices[0].index=1);let h=`data: ${JSON.stringify(k)}
|
|
183
183
|
|
|
184
184
|
`;p.enqueue(f.encode(h))}catch{p.enqueue(f.encode(g+`
|
|
185
185
|
`))}}else p.enqueue(f.encode(g+`
|
|
@@ -187,9 +187,9 @@ Examples:
|
|
|
187
187
|
`);l=_.pop()||"";for(let k of _)if(k.trim())try{m(k,{controller:i,encoder:o,hasTextContent:()=>r,setHasTextContent:h=>r=h,reasoningContent:()=>s,appendReasoningContent:h=>s+=h,isReasoningComplete:()=>a,setReasoningComplete:h=>a=h})}catch(h){console.error("Error processing line:",k,h),i.enqueue(o.encode(k+`
|
|
188
188
|
`))}continue}let f=l.split(`
|
|
189
189
|
`);l=f.pop()||"";for(let _ of f)if(_.trim())try{m(_,{controller:i,encoder:o,hasTextContent:()=>r,setHasTextContent:k=>r=k,reasoningContent:()=>s,appendReasoningContent:k=>s+=k,isReasoningComplete:()=>a,setReasoningComplete:k=>a=k})}catch(k){console.error("Error processing line:",_,k),i.enqueue(o.encode(_+`
|
|
190
|
-
`))}}}catch(g){console.error("Stream error:",g),i.error(g)}finally{try{u.releaseLock()}catch(g){console.error("Error releasing reader lock:",g)}i.close()}}});return new Response(c,{status:e.status,statusText:e.statusText,headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}return e}}});var Qt,
|
|
190
|
+
`))}}}catch(g){console.error("Stream error:",g),i.error(g)}finally{try{u.releaseLock()}catch(g){console.error("Error releasing reader lock:",g)}i.close()}}});return new Response(c,{status:e.status,statusText:e.statusText,headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}return e}}});var Qt,Ps=S(()=>{"use strict";Qt=class{name="cleancache";async transformRequestIn(e){return Array.isArray(e.messages)&&e.messages.forEach(t=>{Array.isArray(t.content)?t.content.forEach(o=>{o.cache_control&&delete o.cache_control}):t.cache_control&&delete t.cache_control}),e}}});import Qc from"json5";import{jsonrepair as Kc}from"jsonrepair";function co(n,e){if(!n||n.trim()===""||n==="{}")return"{}";try{return JSON.parse(n),e?.debug("\u5DE5\u5177\u8C03\u7528\u53C2\u6570\u6807\u51C6JSON\u89E3\u6790\u6210\u529F / Tool arguments standard JSON parsing successful"),n}catch(t){try{let o=Qc.parse(n);return e?.debug("Tool arguments JSON5 parsing successful"),JSON.stringify(o)}catch(o){try{let r=Kc(n);return e?.debug("Tool arguments safely repaired"),r}catch(r){return e?.error(`JSON parsing failed: ${t.message}. JSON5 parsing failed: ${o.message}. JSON repair failed: ${r.message}. Input data: ${JSON.stringify(n)}`),e?.debug("Returning safe empty object as fallback"),"{}"}}}}var As=S(()=>{});var Kt,Os=S(()=>{"use strict";As();Kt=class{name="enhancetool";async transformResponseOut(e){if(e.headers.get("Content-Type")?.includes("application/json")){let t=await e.json();if(t?.choices?.[0]?.message?.tool_calls?.length)for(let o of t.choices[0].message.tool_calls)o.function?.arguments&&(o.function.arguments=co(o.function.arguments,this.logger));return new Response(JSON.stringify(t),{status:e.status,statusText:e.statusText,headers:e.headers})}else if(e.headers.get("Content-Type")?.includes("stream")){if(!e.body)return e;let t=new TextDecoder,o=new TextEncoder,r={},s=!1,a="",l=!1,c=!1,i="",u=new ReadableStream({async start(d){let m=e.body.getReader(),g=(f,_,k)=>{let h=f.split(`
|
|
191
191
|
`);for(let b of h)b.trim()&&_.enqueue(k.encode(b+`
|
|
192
|
-
`))},y=(f,_,k)=>{let h="";try{h=
|
|
192
|
+
`))},y=(f,_,k)=>{let h="";try{h=co(r.arguments||"",this.logger)}catch(C){console.error(`${C.message} ${C.stack} \u5DE5\u5177\u8C03\u7528\u53C2\u6570\u89E3\u6790\u5931\u8D25: ${JSON.stringify(r)}`),h=r.arguments||""}let b={role:"assistant",tool_calls:[{function:{name:r.name,arguments:h},id:r.id,index:r.index,type:"function"}]},x={...f,choices:[{...f.choices[0],delta:b}]};x.choices[0].delta.content!==void 0&&delete x.choices[0].delta.content;let v=`data: ${JSON.stringify(x)}
|
|
193
193
|
|
|
194
194
|
`;_.enqueue(k.encode(v))},p=(f,_)=>{let{controller:k,encoder:h}=_;if(f.startsWith("data: ")&&f.trim()!=="data: [DONE]"){let b=f.slice(6);try{let x=JSON.parse(b);if(x.choices?.[0]?.delta?.tool_calls?.length){let C=x.choices[0].delta.tool_calls[0];if(typeof r.index>"u"){r={index:C.index,name:C.function?.name||"",id:C.id||"",arguments:C.function?.arguments||""},C.function?.arguments&&(C.function.arguments="");let R=`data: ${JSON.stringify(x)}
|
|
195
195
|
|
|
@@ -201,7 +201,7 @@ Examples:
|
|
|
201
201
|
`);i=b.pop()||"";for(let x of b)if(x.trim())try{p(x,{controller:d,encoder:o,hasTextContent:()=>s,setHasTextContent:v=>s=v,reasoningContent:()=>a,appendReasoningContent:v=>a+=v,isReasoningComplete:()=>l,setReasoningComplete:v=>l=v})}catch(v){console.error("Error processing line:",x,v),d.enqueue(o.encode(x+`
|
|
202
202
|
`))}continue}let h=i.split(`
|
|
203
203
|
`);i=h.pop()||"";for(let b of h)if(b.trim())try{p(b,{controller:d,encoder:o,hasTextContent:()=>s,setHasTextContent:x=>s=x,reasoningContent:()=>a,appendReasoningContent:x=>a+=x,isReasoningComplete:()=>l,setReasoningComplete:x=>l=x})}catch(x){console.error("Error processing line:",b,x),d.enqueue(o.encode(b+`
|
|
204
|
-
`))}}}catch(f){console.error("Stream error:",f),d.error(f)}finally{try{m.releaseLock()}catch(f){console.error("Error releasing reader lock:",f)}d.close()}}});return new Response(u,{status:e.status,statusText:e.statusText,headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}return e}}});var Xt,
|
|
204
|
+
`))}}}catch(f){console.error("Stream error:",f),d.error(f)}finally{try{m.releaseLock()}catch(f){console.error("Error releasing reader lock:",f)}d.close()}}});return new Response(u,{status:e.status,statusText:e.statusText,headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}return e}}});var Xt,Es=S(()=>{"use strict";Xt=class{constructor(e){this.options=e;this.enable=this.options?.enable??!0}static TransformerName="reasoning";enable;async transformRequestIn(e){return this.enable?(e.reasoning&&(e.thinking={type:"enabled",budget_tokens:e.reasoning.max_tokens},e.enable_thinking=!0),e):(e.thinking={type:"disabled",budget_tokens:-1},e.enable_thinking=!1,e)}async transformResponseOut(e){if(!this.enable)return e;if(e.headers.get("Content-Type")?.includes("application/json")){let t=await e.json();return t.choices[0]?.message.reasoning_content&&(t.thinking={content:t.choices[0]?.message.reasoning_content}),new Response(JSON.stringify(t),{status:e.status,statusText:e.statusText,headers:e.headers})}else if(e.headers.get("Content-Type")?.includes("stream")){if(!e.body)return e;let t=new TextDecoder,o=new TextEncoder,r="",s=!1,a="",l=new ReadableStream({async start(c){let i=e.body.getReader(),u=(m,g,y)=>{let p=m.split(`
|
|
205
205
|
`);for(let f of p)f.trim()&&g.enqueue(y.encode(f+`
|
|
206
206
|
`))},d=(m,g)=>{let{controller:y,encoder:p}=g;if(this.logger?.debug({line:m},"Processing reason line"),m.startsWith("data: ")&&m.trim()!=="data: [DONE]")try{let f=JSON.parse(m.slice(6));if(console.log(JSON.stringify(f)),f.choices?.[0]?.delta?.reasoning_content){g.appendReasoningContent(f.choices[0].delta.reasoning_content);let _={...f,choices:[{...f.choices[0],delta:{...f.choices[0].delta,thinking:{content:f.choices[0].delta.reasoning_content}}}]};delete _.choices[0].delta.reasoning_content;let k=`data: ${JSON.stringify(_)}
|
|
207
207
|
|
|
@@ -213,7 +213,7 @@ Examples:
|
|
|
213
213
|
`))}else y.enqueue(p.encode(m+`
|
|
214
214
|
`))};try{for(;;){let{done:m,value:g}=await i.read();if(m){a.trim()&&u(a,c,o);break}let y=t.decode(g,{stream:!0});a+=y;let p=a.split(`
|
|
215
215
|
`);a=p.pop()||"";for(let f of p)if(f.trim())try{d(f,{controller:c,encoder:o,reasoningContent:()=>r,appendReasoningContent:_=>r+=_,isReasoningComplete:()=>s,setReasoningComplete:_=>s=_})}catch(_){console.error("Error processing line:",f,_),c.enqueue(o.encode(f+`
|
|
216
|
-
`))}}}catch(m){console.error("Stream error:",m),c.error(m)}finally{try{i.releaseLock()}catch(m){console.error("Error releasing reader lock:",m)}c.close()}}});return new Response(l,{status:e.status,statusText:e.statusText,headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}return e}}});var Yt,
|
|
216
|
+
`))}}}catch(m){console.error("Stream error:",m),c.error(m)}finally{try{i.releaseLock()}catch(m){console.error("Error releasing reader lock:",m)}c.close()}}});return new Response(l,{status:e.status,statusText:e.statusText,headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}return e}}});var Yt,Is=S(()=>{"use strict";Yt=class{constructor(e){this.options=e;this.max_tokens=this.options?.max_tokens,this.temperature=this.options?.temperature,this.top_p=this.options?.top_p,this.top_k=this.options?.top_k,this.repetition_penalty=this.options?.repetition_penalty}static TransformerName="sampling";max_tokens;temperature;top_p;top_k;repetition_penalty;async transformRequestIn(e){return e.max_tokens&&e.max_tokens>this.max_tokens&&(e.max_tokens=this.max_tokens),typeof this.temperature<"u"&&(e.temperature=this.temperature),typeof this.top_p<"u"&&(e.top_p=this.top_p),typeof this.top_k<"u"&&(e.top_k=this.top_k),typeof this.repetition_penalty<"u"&&(e.repetition_penalty=this.repetition_penalty),e}}});var qt,Ms=S(()=>{"use strict";qt=class{static TransformerName="maxcompletiontokens";async transformRequestIn(e){return e.max_tokens&&(e.max_completion_tokens=e.max_tokens,delete e.max_tokens),e}}});function $s(n){let e=[];for(let o=0;o<n.messages.length;o++){let r=n.messages[o],s=o===n.messages.length-1,a=r.role==="assistant",l=[];typeof r.content=="string"?l.push({type:"text",text:r.content}):Array.isArray(r.content)&&r.content.forEach(c=>{c.type==="text"?l.push({type:"text",text:c.text||""}):c.type==="image_url"&&l.push({type:"image",source:{type:"base64",media_type:c.media_type||"image/jpeg",data:c.image_url.url}})}),!(!s&&l.length===0&&!r.tool_calls&&!r.content)&&(s&&a&&l.length===0&&r.tool_calls&&l.push({type:"text",text:""}),e.push({role:r.role==="assistant"?"assistant":"user",content:l}))}let t={anthropic_version:"vertex-2023-10-16",messages:e,max_tokens:n.max_tokens||1e3,stream:n.stream||!1,...n.temperature&&{temperature:n.temperature}};return n.tools&&n.tools.length>0&&(t.tools=n.tools.map(o=>({name:o.function.name,description:o.function.description,input_schema:o.function.parameters}))),n.tool_choice&&(n.tool_choice==="auto"||n.tool_choice==="none"?t.tool_choice=n.tool_choice:typeof n.tool_choice=="string"&&(t.tool_choice={type:"tool",name:n.tool_choice})),t}function Ns(n){let e=n,o={messages:e.messages.map(r=>{let s=r.content.map(a=>a.type==="text"?{type:"text",text:a.text||""}:a.type==="image"&&a.source?{type:"image_url",image_url:{url:a.source.data},media_type:a.source.media_type}:{type:"text",text:""});return{role:r.role,content:s}}),model:n.model||"claude-sonnet-4@20250514",max_tokens:e.max_tokens,temperature:e.temperature,stream:e.stream};return e.tools&&e.tools.length>0&&(o.tools=e.tools.map(r=>({type:"function",function:{name:r.name,description:r.description,parameters:{type:"object",properties:r.input_schema.properties,required:r.input_schema.required,additionalProperties:r.input_schema.additionalProperties,$schema:r.input_schema.$schema}}}))),e.tool_choice&&(typeof e.tool_choice=="string"?o.tool_choice=e.tool_choice:e.tool_choice.type==="tool"&&(o.tool_choice=e.tool_choice.name)),o}async function Ls(n,e,t){if(n.headers.get("Content-Type")?.includes("application/json")){let o=await n.json(),r;o.tool_use&&o.tool_use.length>0&&(r=o.tool_use.map(a=>({id:a.id,type:"function",function:{name:a.name,arguments:JSON.stringify(a.input)}})));let s={id:o.id,choices:[{finish_reason:o.stop_reason||null,index:0,message:{content:o.content[0]?.text||"",role:"assistant",...r&&{tool_calls:r}}}],created:parseInt(new Date().getTime()/1e3+"",10),model:o.model,object:"chat.completion",usage:{completion_tokens:o.usage.output_tokens,prompt_tokens:o.usage.input_tokens,total_tokens:o.usage.input_tokens+o.usage.output_tokens}};return new Response(JSON.stringify(s),{status:n.status,statusText:n.statusText,headers:n.headers})}else if(n.headers.get("Content-Type")?.includes("stream")){if(!n.body)return n;let o=new TextDecoder,r=new TextEncoder,s=(l,c)=>{if(l.startsWith("data: ")){let i=l.slice(6).trim();if(i){t?.debug({chunkStr:i},`${e} chunk:`);try{let u=JSON.parse(i);if(u.type==="content_block_delta"&&u.delta?.type==="text_delta"){let d={choices:[{delta:{role:"assistant",content:u.delta.text||""},finish_reason:null,index:0,logprobs:null}],created:parseInt(new Date().getTime()/1e3+"",10),id:u.id||"",model:u.model||"",object:"chat.completion.chunk",system_fingerprint:"fp_a49d71b8a1",usage:{completion_tokens:u.usage?.output_tokens||0,prompt_tokens:u.usage?.input_tokens||0,total_tokens:(u.usage?.input_tokens||0)+(u.usage?.output_tokens||0)}};c.enqueue(r.encode(`data: ${JSON.stringify(d)}
|
|
217
217
|
|
|
218
218
|
`))}else if(u.type==="content_block_delta"&&u.delta?.type==="input_json_delta"){let d={choices:[{delta:{tool_calls:[{index:u.index||0,function:{arguments:u.delta.partial_json||""}}]},finish_reason:null,index:0,logprobs:null}],created:parseInt(new Date().getTime()/1e3+"",10),id:u.id||"",model:u.model||"",object:"chat.completion.chunk",system_fingerprint:"fp_a49d71b8a1",usage:{completion_tokens:u.usage?.output_tokens||0,prompt_tokens:u.usage?.input_tokens||0,total_tokens:(u.usage?.input_tokens||0)+(u.usage?.output_tokens||0)}};c.enqueue(r.encode(`data: ${JSON.stringify(d)}
|
|
219
219
|
|
|
@@ -226,10 +226,10 @@ Examples:
|
|
|
226
226
|
`));else{let d={choices:[{delta:{role:"assistant",content:u.content?.[0]?.text||""},finish_reason:u.stop_reason?.toLowerCase()||null,index:0,logprobs:null}],created:parseInt(new Date().getTime()/1e3+"",10),id:u.id||"",model:u.model||"",object:"chat.completion.chunk",system_fingerprint:"fp_a49d71b8a1",usage:{completion_tokens:u.usage?.output_tokens||0,prompt_tokens:u.usage?.input_tokens||0,total_tokens:(u.usage?.input_tokens||0)+(u.usage?.output_tokens||0)}};c.enqueue(r.encode(`data: ${JSON.stringify(d)}
|
|
227
227
|
|
|
228
228
|
`))}}catch(u){t?.error(`Error parsing ${e} stream chunk`,i,u.message)}}}},a=new ReadableStream({async start(l){let c=n.body.getReader(),i="";try{for(;;){let{done:u,value:d}=await c.read();if(u){i&&s(i,l);break}i+=o.decode(d,{stream:!0});let m=i.split(`
|
|
229
|
-
`);i=m.pop()||"";for(let g of m)s(g,l)}}catch(u){l.error(u)}finally{l.close()}}});return new Response(a,{status:n.status,statusText:n.statusText,headers:n.headers})}return n}var
|
|
229
|
+
`);i=m.pop()||"";for(let g of m)s(g,l)}}catch(u){l.error(u)}finally{l.close()}}});return new Response(a,{status:n.status,statusText:n.statusText,headers:n.headers})}return n}var Fs=S(()=>{"use strict"});async function Xc(){try{let{GoogleAuth:n}=await import("google-auth-library");return(await(await new n({scopes:["https://www.googleapis.com/auth/cloud-platform"]}).getClient()).getAccessToken()).token||""}catch(n){throw console.error("Error getting access token:",n),new Error(`Failed to get access token for Vertex AI. Please ensure you have set up authentication using one of these methods:
|
|
230
230
|
1. Set GOOGLE_APPLICATION_CREDENTIALS to point to service account key file
|
|
231
231
|
2. Run "gcloud auth application-default login"
|
|
232
|
-
3. Use Google Cloud environment with default service account`)}}var Zt,
|
|
232
|
+
3. Use Google Cloud environment with default service account`)}}var Zt,Us=S(()=>{"use strict";Fs();Zt=class{name="vertex-claude";async transformRequestIn(e,t){let o=process.env.GOOGLE_CLOUD_PROJECT,r=process.env.GOOGLE_CLOUD_LOCATION||"us-east5";if(!o&&process.env.GOOGLE_APPLICATION_CREDENTIALS)try{let l=(await import("fs")).readFileSync(process.env.GOOGLE_APPLICATION_CREDENTIALS,"utf8"),c=JSON.parse(l);c&&c.project_id&&(o=c.project_id)}catch(a){console.error("Error extracting project_id from GOOGLE_APPLICATION_CREDENTIALS:",a)}if(!o)throw new Error("Project ID is required for Vertex AI. Set GOOGLE_CLOUD_PROJECT environment variable or ensure project_id is in GOOGLE_APPLICATION_CREDENTIALS file.");let s=await Xc();return{body:$s(e),config:{url:new URL(`/v1/projects/${o}/locations/${r}/publishers/anthropic/models/${e.model}:${e.stream?"streamRawPredict":"rawPredict"}`,`https://${r}-aiplatform.googleapis.com`).toString(),headers:{Authorization:`Bearer ${s}`,"Content-Type":"application/json"}}}}async transformRequestOut(e){return Ns(e)}async transformResponseOut(e){return Ls(e,this.name,this.logger)}}});var en,Ds=S(()=>{"use strict";en=class{name="cerebras";async transformRequestIn(e,t){let o=JSON.parse(JSON.stringify(e));return o.reasoning?delete o.reasoning:o.disable_reasoning=!1,{body:o,config:{headers:{Authorization:`Bearer ${t.apiKey}`,"Content-Type":"application/json"}}}}async transformResponseOut(e){return e}}});var tn,js=S(()=>{"use strict";tn=class{name="streamoptions";async transformRequestIn(e){return e.stream&&(e.stream_options={include_usage:!0}),e}}});var nn,zs=S(()=>{"use strict";nn=class{name="OpenAI";endPoint="/v1/chat/completions"}});var on,Hs=S(()=>{"use strict";on=class{static TransformerName="customparams";options;constructor(e={}){this.options=e}async transformRequestIn(e){let t={...e},o=Object.entries(this.options);for(let[r,s]of o)if(r in t)if(typeof t[r]=="object"&&typeof s=="object"&&!Array.isArray(t[r])&&!Array.isArray(s)&&t[r]!==null&&s!==null)t[r]=this.deepMergeObjects(t[r],s);else continue;else t[r]=this.cloneValue(s);return t}async transformResponseOut(e){return e}deepMergeObjects(e,t){let o={...e};for(let[r,s]of Object.entries(t))r in o&&typeof o[r]=="object"&&typeof s=="object"&&!Array.isArray(o[r])&&!Array.isArray(s)&&o[r]!==null&&s!==null?o[r]=this.deepMergeObjects(o[r],s):o[r]=this.cloneValue(s);return o}cloneValue(e){if(e===null||typeof e!="object")return e;if(Array.isArray(e))return e.map(o=>this.cloneValue(o));let t={};for(let[o,r]of Object.entries(e))t[o]=this.cloneValue(r);return t}}});import{v4 as Yc}from"uuid";var rn,Js=S(()=>{"use strict";rn=class{constructor(e){this.options=e}static TransformerName="vercel";endPoint="/v1/chat/completions";async transformRequestIn(e){return e.model.includes("claude")?e.messages.forEach(t=>{Array.isArray(t.content)&&t.content.forEach(o=>{o.type==="image_url"&&(o.image_url.url.startsWith("http")||(o.image_url.url=`data:${o.media_type};base64,${o.image_url.url}`),delete o.media_type)})}):e.messages.forEach(t=>{Array.isArray(t.content)?t.content.forEach(o=>{o.cache_control&&delete o.cache_control,o.type==="image_url"&&(o.image_url.url.startsWith("http")||(o.image_url.url=`data:${o.media_type};base64,${o.image_url.url}`),delete o.media_type)}):t.cache_control&&delete t.cache_control}),Object.assign(e,this.options||{}),e}async transformResponseOut(e){if(e.headers.get("Content-Type")?.includes("application/json")){let t=await e.json();return new Response(JSON.stringify(t),{status:e.status,statusText:e.statusText,headers:e.headers})}else if(e.headers.get("Content-Type")?.includes("stream")){if(!e.body)return e;let t=new TextDecoder,o=new TextEncoder,r=!1,s="",a=!1,l=!1,c="",i=new ReadableStream({async start(u){let d=e.body.getReader(),m=(y,p,f)=>{let _=y.split(`
|
|
233
233
|
`);for(let k of _)k.trim()&&p.enqueue(f.encode(k+`
|
|
234
234
|
`))},g=(y,p)=>{let{controller:f,encoder:_}=p;if(y.startsWith("data: ")&&y.trim()!=="data: [DONE]"){let k=y.slice(6);try{let h=JSON.parse(k);if(h.usage&&(this.logger?.debug({usage:h.usage,hasToolCall:l},"usage"),h.choices[0].finish_reason=l?"tool_calls":"stop"),h.choices?.[0]?.finish_reason==="error"&&f.enqueue(_.encode(`data: ${JSON.stringify({error:h.choices?.[0].error})}
|
|
235
235
|
|
|
@@ -237,7 +237,7 @@ Examples:
|
|
|
237
237
|
|
|
238
238
|
`;f.enqueue(_.encode(v));return}if(h.choices?.[0]?.delta?.content&&p.reasoningContent()&&!p.isReasoningComplete()){p.setReasoningComplete(!0);let v={...h,choices:[{...h.choices?.[0],delta:{...h.choices[0].delta,content:null,thinking:{content:p.reasoningContent(),signature:"ccr_think_signature"}}}]};v.choices?.[0]?.delta&&delete v.choices[0].delta.reasoning;let C=`data: ${JSON.stringify(v)}
|
|
239
239
|
|
|
240
|
-
`;f.enqueue(_.encode(C))}h.choices?.[0]?.delta?.reasoning&&delete h.choices[0].delta.reasoning,h.choices?.[0]?.delta?.tool_calls?.length&&!Number.isNaN(parseInt(h.choices?.[0]?.delta?.tool_calls[0].id,10))&&h.choices?.[0]?.delta?.tool_calls.forEach(x=>{x.id=`call_${
|
|
240
|
+
`;f.enqueue(_.encode(C))}h.choices?.[0]?.delta?.reasoning&&delete h.choices[0].delta.reasoning,h.choices?.[0]?.delta?.tool_calls?.length&&!Number.isNaN(parseInt(h.choices?.[0]?.delta?.tool_calls[0].id,10))&&h.choices?.[0]?.delta?.tool_calls.forEach(x=>{x.id=`call_${Yc()}`}),h.choices?.[0]?.delta?.tool_calls?.length&&!l&&(l=!0),h.choices?.[0]?.delta?.tool_calls?.length&&p.hasTextContent()&&(typeof h.choices[0].index=="number"?h.choices[0].index+=1:h.choices[0].index=1);let b=`data: ${JSON.stringify(h)}
|
|
241
241
|
|
|
242
242
|
`;f.enqueue(_.encode(b))}catch{f.enqueue(_.encode(y+`
|
|
243
243
|
`))}}else f.enqueue(_.encode(y+`
|
|
@@ -245,14 +245,14 @@ Examples:
|
|
|
245
245
|
`);c=k.pop()||"";for(let h of k)if(h.trim())try{g(h,{controller:u,encoder:o,hasTextContent:()=>r,setHasTextContent:b=>r=b,reasoningContent:()=>s,appendReasoningContent:b=>s+=b,isReasoningComplete:()=>a,setReasoningComplete:b=>a=b})}catch(b){console.error("Error processing line:",h,b),u.enqueue(o.encode(h+`
|
|
246
246
|
`))}continue}let _=c.split(`
|
|
247
247
|
`);c=_.pop()||"";for(let k of _)if(k.trim())try{g(k,{controller:u,encoder:o,hasTextContent:()=>r,setHasTextContent:h=>r=h,reasoningContent:()=>s,appendReasoningContent:h=>s+=h,isReasoningComplete:()=>a,setReasoningComplete:h=>a=h})}catch(h){console.error("Error processing line:",k,h),u.enqueue(o.encode(k+`
|
|
248
|
-
`))}}}catch(y){console.error("Stream error:",y),u.error(y)}finally{try{d.releaseLock()}catch(y){console.error("Error releasing reader lock:",y)}u.close()}}});return new Response(i,{status:e.status,statusText:e.statusText,headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}return e}}});var
|
|
248
|
+
`))}}}catch(y){console.error("Stream error:",y),u.error(y)}finally{try{d.releaseLock()}catch(y){console.error("Error releasing reader lock:",y)}u.close()}}});return new Response(i,{status:e.status,statusText:e.statusText,headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}return e}}});var lo,qc,sn,Bs=S(()=>{"use strict";lo=`Always think before answering. Even if the problem seems simple, always write down your reasoning process explicitly.
|
|
249
249
|
|
|
250
250
|
Output format:
|
|
251
251
|
<reasoning_content>
|
|
252
252
|
Your detailed thinking process goes here
|
|
253
253
|
</reasoning_content>
|
|
254
|
-
Your final answer must follow after the closing tag above.`,
|
|
255
|
-
${r.content}`),delete r.thinking)});let o=e.messages[e.messages.length-1];return o.role==="user"&&(Array.isArray(o.content)?o.content.push({type:"text",text:
|
|
254
|
+
Your final answer must follow after the closing tag above.`,qc=10,sn=class{name="forcereasoning";async transformRequestIn(e){let t=0;e.messages.filter(r=>r.role==="assistant").reverse().forEach(r=>{r.thinking&&(r.thinking.content&&(!r.content||t<qc)&&(t++,r.content=`<reasoning_content>${r.thinking.content}</reasoning_content>
|
|
255
|
+
${r.content}`),delete r.thinking)});let o=e.messages[e.messages.length-1];return o.role==="user"&&(Array.isArray(o.content)?o.content.push({type:"text",text:lo}):o.content=[{type:"text",text:lo},{type:"text",text:o.content||""}]),o.role==="tool"&&e.messages.push({role:"user",content:[{type:"text",text:lo}]}),e}async transformResponseOut(e){let t="<reasoning_content>",o="</reasoning_content>";if(e.headers.get("Content-Type")?.includes("application/json")){let r=await e.json();if(r.choices[0]?.message.content){let s=/<reasoning_content>(.*?)<\/reasoning_content>/s,a=r.choices[0]?.message.content.match(s);a&&a[1]&&(r.thinking={content:a[1]})}return new Response(JSON.stringify(r),{status:e.status,statusText:e.statusText,headers:e.headers})}else if(e.headers.get("Content-Type")?.includes("stream")){if(!e.body)return e;let r=0,s=new TextDecoder,a=new TextEncoder,l=new ReadableStream({async start(c){let i=e.body.getReader(),u="",d="SEARCHING",m="",g="",y=(p,f)=>{if(typeof f!="string"){p.choices?.[0]?.delta&&Object.keys(p.choices[0].delta).length>0&&!p.choices[0].delta.content&&(p.choices[0].index=r,c.enqueue(a.encode(`data: ${JSON.stringify(p)}
|
|
256
256
|
|
|
257
257
|
`)));return}let _=m+f;for(m="";_.length>0;)if(d==="SEARCHING"){let k=_.indexOf(t);if(k!==-1)_=_.substring(k+t.length),d="REASONING";else{for(let h=t.length-1;h>0;h--)if(_.endsWith(t.substring(0,h))){m=_.substring(_.length-h);break}_=""}}else if(d==="REASONING"){let k=_.indexOf(o);if(k!==-1){let h=_.substring(0,k);if(h.length>0){let v={...p.choices[0].delta,thinking:{content:h}};delete v.content;let C={...p,choices:[{...p.choices[0],delta:v,index:r}]};c.enqueue(a.encode(`data: ${JSON.stringify(C)}
|
|
258
258
|
|
|
@@ -269,7 +269,7 @@ ${r.content}`),delete r.thinking)});let o=e.messages[e.messages.length-1];return
|
|
|
269
269
|
`))}else c.enqueue(a.encode(h+`
|
|
270
270
|
`))}}}catch(p){console.error("Stream error:",p),c.error(p)}finally{try{i.releaseLock()}catch(p){console.error("Error releasing reader lock:",p)}if(d==="REASONING"){let f={choices:[{delta:{thinking:{signature:"ccr_think_signature"}}}]};c.enqueue(a.encode(`data: ${JSON.stringify(f)}
|
|
271
271
|
|
|
272
|
-
`))}c.close()}}});return new Response(l,{status:e.status,statusText:e.statusText,headers:{"Content-Type":e.headers.get("Content-Type")||"text/plain","Cache-Control":"no-cache",Connection:"keep-alive"}})}return e}}});var an,
|
|
272
|
+
`))}c.close()}}});return new Response(l,{status:e.status,statusText:e.statusText,headers:{"Content-Type":e.headers.get("Content-Type")||"text/plain","Cache-Control":"no-cache",Connection:"keep-alive"}})}return e}}});var an,Ws=S(()=>{"use strict";an=class{name="kimi";async transformRequestIn(e){return(e.thinking||e.reasoning?.enabled||e.messages.some(o=>o.thinking?.content))&&e.messages.forEach(o=>{if(o.role==="assistant"){let r=o.thinking?.content,s=o.thinking?.signature;r&&typeof r=="string"&&r.trim()&&(o.reasoning_content=r,s&&(o.reasoning_content_signature=s)),o.tool_calls&&o.tool_calls.length>0&&(o.reasoning_content||(o.reasoning_content="")),o.thinking&&delete o.thinking}}),e}async transformResponseOut(e){let t=e.headers.get("Content-Type");if(t?.includes("stream")){if(!e.body)return e;let o=new TextDecoder,r=new TextEncoder,s="",a="",l=new ReadableStream({async start(c){let i=e.body.getReader();try{for(;;){let{done:u,value:d}=await i.read();if(u){a.trim()&&c.enqueue(r.encode(a+`
|
|
273
273
|
`));break}let m=o.decode(d,{stream:!0});a+=m;let g=a.split(`
|
|
274
274
|
`);a=g.pop()||"";for(let y of g)if(y.trim())if(y.startsWith("data: ")&&y.trim()!=="data: [DONE]")try{let p=JSON.parse(y.slice(6));if(p.choices?.[0]?.delta?.reasoning_content){s+=p.choices[0].delta.reasoning_content;let f={...p,choices:[{...p.choices[0],delta:{thinking:{content:p.choices[0].delta.reasoning_content}}}]};delete f.choices[0].delta.reasoning_content,c.enqueue(r.encode(`data: ${JSON.stringify(f)}
|
|
275
275
|
|
|
@@ -279,7 +279,7 @@ ${r.content}`),delete r.thinking)});let o=e.messages[e.messages.length-1];return
|
|
|
279
279
|
|
|
280
280
|
`))}catch{c.enqueue(r.encode(y+`
|
|
281
281
|
`))}else c.enqueue(r.encode(y+`
|
|
282
|
-
`))}}catch(u){c.error(u)}finally{try{i.releaseLock()}catch{}c.close()}}});return new Response(l,{status:e.status,statusText:e.statusText,headers:{"Content-Type":t||"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}if(t?.includes("application/json")){let o=await e.json();return o.choices?.[0]?.message?.reasoning_content&&(o.choices[0].message.thinking={content:o.choices[0].message.reasoning_content},delete o.choices[0].message.reasoning_content),new Response(JSON.stringify(o),{status:e.status,statusText:e.statusText,headers:e.headers})}return e}}});import{v4 as
|
|
282
|
+
`))}}catch(u){c.error(u)}finally{try{i.releaseLock()}catch{}c.close()}}});return new Response(l,{status:e.status,statusText:e.statusText,headers:{"Content-Type":t||"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}if(t?.includes("application/json")){let o=await e.json();return o.choices?.[0]?.message?.reasoning_content&&(o.choices[0].message.thinking={content:o.choices[0].message.reasoning_content},delete o.choices[0].message.reasoning_content),new Response(JSON.stringify(o),{status:e.status,statusText:e.statusText,headers:e.headers})}return e}}});import{v4 as Zc}from"uuid";var cn,Gs=S(()=>{"use strict";cn=class{constructor(e){this.options=e}static TransformerName="opencode";endPoint="/v1/chat/completions";async transformRequestIn(e){return e.messages.forEach(t=>{Array.isArray(t.content)?t.content.forEach(o=>{o.cache_control&&delete o.cache_control,o.type==="image_url"&&(o.image_url.url.startsWith("http")||(o.image_url.url=`data:${o.media_type};base64,${o.image_url.url}`),delete o.media_type)}):t.cache_control&&delete t.cache_control}),Object.assign(e,this.options||{}),e}async transformResponseOut(e){if(e.headers.get("Content-Type")?.includes("application/json")){let t=await e.json();return t.choices?.[0]?.message?.reasoning_content&&(t.choices[0].message.thinking={content:t.choices[0].message.reasoning_content},delete t.choices[0].message.reasoning_content),new Response(JSON.stringify(t),{status:e.status,statusText:e.statusText,headers:e.headers})}if(e.headers.get("Content-Type")?.includes("stream")){if(!e.body)return e;let t=new TextDecoder,o=new TextEncoder,r=!1,s="",a=!1,l=!1,c="",i=new ReadableStream({async start(u){let d=e.body.getReader(),m=(y,p,f)=>{let _=y.split(`
|
|
283
283
|
`);for(let k of _)k.trim()&&p.enqueue(f.encode(k+`
|
|
284
284
|
`))},g=(y,p)=>{let{controller:f,encoder:_}=p;if(y.startsWith("data: ")&&y.trim()!=="data: [DONE]")try{let k=JSON.parse(y.slice(6));if(k.usage&&(k.choices[0].finish_reason=l?"tool_calls":"stop"),k.choices?.[0]?.finish_reason==="error"){f.enqueue(_.encode(`data: ${JSON.stringify({error:k.choices?.[0]?.error})}
|
|
285
285
|
|
|
@@ -289,7 +289,7 @@ ${r.content}`),delete r.thinking)});let o=e.messages[e.messages.length-1];return
|
|
|
289
289
|
|
|
290
290
|
`));let w={...k,choices:[{...k.choices?.[0],delta:{...k.choices[0].delta,content:T}}]};w.choices?.[0]?.delta&&(delete w.choices[0].delta.reasoning,delete w.choices[0].delta.reasoning_content),f.enqueue(_.encode(`data: ${JSON.stringify(w)}
|
|
291
291
|
|
|
292
|
-
`));return}k.choices?.[0]?.delta?.reasoning&&delete k.choices[0].delta.reasoning,k.choices?.[0]?.delta?.reasoning_content&&delete k.choices[0].delta.reasoning_content,k.choices?.[0]?.delta?.tool_calls?.length&&!Number.isNaN(parseInt(k.choices?.[0]?.delta?.tool_calls[0].id,10))&&k.choices?.[0]?.delta?.tool_calls.forEach(R=>{R.id=`call_${
|
|
292
|
+
`));return}k.choices?.[0]?.delta?.reasoning&&delete k.choices[0].delta.reasoning,k.choices?.[0]?.delta?.reasoning_content&&delete k.choices[0].delta.reasoning_content,k.choices?.[0]?.delta?.tool_calls?.length&&!Number.isNaN(parseInt(k.choices?.[0]?.delta?.tool_calls[0].id,10))&&k.choices?.[0]?.delta?.tool_calls.forEach(R=>{R.id=`call_${Zc()}`}),k.choices?.[0]?.delta?.tool_calls?.length&&!l&&(l=!0);let b=k.choices?.[0]?.delta,x=b&&Object.keys(b).length>0,v=k.choices?.[0]?.finish_reason,C=k.usage;(x||v||C)&&f.enqueue(_.encode(`data: ${JSON.stringify(k)}
|
|
293
293
|
|
|
294
294
|
`))}catch{f.enqueue(_.encode(y+`
|
|
295
295
|
`))}else f.enqueue(_.encode(y+`
|
|
@@ -297,22 +297,22 @@ ${r.content}`),delete r.thinking)});let o=e.messages[e.messages.length-1];return
|
|
|
297
297
|
`);c=k.pop()||"";for(let h of k)if(h.trim())try{g(h,{controller:u,encoder:o,hasTextContent:()=>r,setHasTextContent:b=>r=b,reasoningContent:()=>s,appendReasoningContent:b=>s+=b,isReasoningComplete:()=>a,setReasoningComplete:b=>a=b})}catch(b){console.error("Error processing line:",h,b),u.enqueue(o.encode(h+`
|
|
298
298
|
`))}continue}let _=c.split(`
|
|
299
299
|
`);c=_.pop()||"";for(let k of _)if(k.trim())try{g(k,{controller:u,encoder:o,hasTextContent:()=>r,setHasTextContent:h=>r=h,reasoningContent:()=>s,appendReasoningContent:h=>s+=h,isReasoningComplete:()=>a,setReasoningComplete:h=>a=h})}catch(h){console.error("Error processing line:",k,h),u.enqueue(o.encode(k+`
|
|
300
|
-
`))}}}catch(y){console.error("Stream error:",y),u.error(y)}finally{try{d.releaseLock()}catch(y){console.error("Error releasing reader lock:",y)}u.close()}}});return new Response(i,{status:e.status,statusText:e.statusText,headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}return e}}});var
|
|
300
|
+
`))}}}catch(y){console.error("Stream error:",y),u.error(y)}finally{try{d.releaseLock()}catch(y){console.error("Error releasing reader lock:",y)}u.close()}}});return new Response(i,{status:e.status,statusText:e.statusText,headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}return e}}});var Vs,Qs=S(()=>{bs();xs();Cs();Ts();vs();Rs();ws();Ss();Ps();Os();Es();Is();Ms();Us();Ds();js();zs();Hs();Js();qn();Bs();Ws();Gs();Vs={AnthropicTransformer:Ft,GeminiTransformer:zt,VertexGeminiTransformer:Ht,VertexClaudeTransformer:Zt,DeepseekTransformer:Jt,TooluseTransformer:Bt,OpenrouterTransformer:Wt,OpenAITransformer:nn,MaxTokenTransformer:Gt,GroqTransformer:Vt,CleancacheTransformer:Qt,EnhanceToolTransformer:Kt,ReasoningTransformer:Xt,SamplingTransformer:Yt,MaxCompletionTokens:qt,CerebrasTransformer:en,StreamOptionsTransformer:tn,CustomParamsTransformer:on,VercelTransformer:rn,OpenAIResponsesTransformer:we,ForceReasoningTransformer:sn,KimiTransformer:an,OpenCodeTransformer:cn}});var Me,uo=S(()=>{"use strict";Qs();Me=class{constructor(e,t){this.configService=e;this.logger=t}transformers=new Map;registerTransformer(e,t){this.transformers.set(e,t),this.logger.info(`register transformer: ${e}${t.endPoint?` (endpoint: ${t.endPoint})`:" (no endpoint)"}`)}getTransformer(e){return this.transformers.get(e)}getAllTransformers(){return new Map(this.transformers)}getTransformersWithEndpoint(){let e=[];return this.transformers.forEach((t,o)=>{typeof t=="object"&&t.endPoint&&e.push({name:o,transformer:t})}),e}getTransformersWithoutEndpoint(){let e=[];return this.transformers.forEach((t,o)=>{typeof t=="object"&&!t.endPoint&&e.push({name:o,transformer:t})}),e}removeTransformer(e){return this.transformers.delete(e)}hasTransformer(e){return this.transformers.has(e)}async registerTransformerFromConfig(e){try{if(e.path){let t=Be(Be.resolve(e.path));if(t){let o=new t(e.options);if(o&&typeof o=="object"&&(o.logger=this.logger),!o.name)throw new Error(`Transformer instance from ${e.path} does not have a name property.`);return this.registerTransformer(o.name,o),!0}}return!1}catch(t){return this.logger.error(`load transformer (${e.path})
|
|
301
301
|
error: ${t.message}
|
|
302
302
|
stack: ${t.stack}`),!1}}async initialize(){try{await this.registerDefaultTransformersInternal(),await this.loadFromConfig()}catch(e){this.logger.error(`TransformerService init error: ${e.message}
|
|
303
|
-
Stack: ${e.stack}`)}}async registerDefaultTransformersInternal(){try{Object.values(Ys).forEach(e=>{if("TransformerName"in e&&typeof e.TransformerName=="string")this.registerTransformer(e.TransformerName,e);else{let t=new e;t&&typeof t=="object"&&(t.logger=this.logger),this.registerTransformer(t.name,t)}})}catch(e){this.logger.error({error:e},"transformer regist error:")}}async loadFromConfig(){let e=this.configService.get("transformers",[]);for(let t of e)await this.registerTransformerFromConfig(t)}}});import{get_encoding as ul}from"tiktoken";var ot,Zs=S(()=>{"use strict";ot=class{type="tiktoken";name;encoding;constructor(e="cl100k_base"){this.name=`tiktoken-${e}`;try{this.encoding=ul(e)}catch{throw new Error(`Failed to initialize tiktoken encoding: ${e}`)}}async initialize(){if(!this.encoding)throw new Error("Tiktoken encoding not initialized")}async countTokens(e){let t=this.encoding;if(!t)throw new Error("Encoding not initialized");let o=0,{messages:r,system:s,tools:a}=e;return Array.isArray(r)&&r.forEach(l=>{typeof l.content=="string"?o+=t.encode(l.content).length:Array.isArray(l.content)&&l.content.forEach(c=>{if(c.type==="text")o+=t.encode(c.text).length;else if(c.type==="tool_use")o+=t.encode(JSON.stringify(c.input)).length;else if(c.type==="tool_result"){let i=typeof c.content=="string"?c.content:JSON.stringify(c.content);o+=t.encode(i).length}})}),typeof s=="string"?o+=t.encode(s).length:Array.isArray(s)&&s.forEach(l=>{l.type==="text"&&(typeof l.text=="string"?o+=t.encode(l.text).length:Array.isArray(l.text)&&l.text.forEach(c=>{o+=t.encode(c||"").length}))}),a&&a.forEach(l=>{l.description&&(o+=t.encode(l.name+l.description).length),l.input_schema&&(o+=t.encode(JSON.stringify(l.input_schema)).length)}),o}isInitialized(){return this.encoding!==void 0}encodeText(e){let t=this.encoding;if(!t)throw new Error("Encoding not initialized");return Array.from(t.encode(e))}dispose(){this.encoding&&(this.encoding.free(),this.encoding=void 0)}}});import{join as ln}from"path";import{homedir as dl}from"os";import{existsSync as fo,mkdirSync as pl}from"fs";import{promises as un}from"fs";import{Tokenizer as fl}from"@huggingface/tokenizers";var dn,ei=S(()=>{"use strict";dn=class{type="huggingface";name;modelId;logger;options;tokenizer=null;cacheDir;safeModelName;constructor(e,t,o={}){this.modelId=e,this.logger=t,this.options=o,this.cacheDir=o.cacheDir||ln(dl(),".claude-code-router",".huggingface"),this.safeModelName=e.replace(/\//g,"_").replace(/[^a-zA-Z0-9_-]/g,"_"),this.name=`huggingface-${e.split("/").pop()}`}getCachePaths(){let e=ln(this.cacheDir,this.safeModelName);return{modelDir:e,tokenizerJson:ln(e,"tokenizer.json"),tokenizerConfig:ln(e,"tokenizer_config.json")}}ensureDir(e){fo(e)||pl(e,{recursive:!0})}async loadFromCache(){try{let e=this.getCachePaths();if(!fo(e.tokenizerJson)||!fo(e.tokenizerConfig))return null;let[t,o]=await Promise.all([un.readFile(e.tokenizerJson,"utf-8"),un.readFile(e.tokenizerConfig,"utf-8")]);return{tokenizerJson:JSON.parse(t),tokenizerConfig:JSON.parse(o)}}catch(e){return this.logger?.warn(`Failed to load from cache: ${e.message}`),null}}async downloadAndCache(){let e=this.getCachePaths(),t={json:`https://huggingface.co/${this.modelId}/resolve/main/tokenizer.json`,config:`https://huggingface.co/${this.modelId}/resolve/main/tokenizer_config.json`};this.logger?.info(`Downloading tokenizer files for ${this.modelId}`);let o=new AbortController,r=setTimeout(()=>o.abort(),this.options.timeout||3e4);try{let[s,a]=await Promise.all([fetch(t.json,{signal:o.signal}),fetch(t.config,{signal:o.signal})]);if(!s.ok)throw new Error(`Failed to fetch tokenizer.json: ${s.statusText}`);let[l,c]=await Promise.all([s.json(),a.ok?a.json():Promise.resolve({})]);return this.ensureDir(e.modelDir),await Promise.all([un.writeFile(e.tokenizerJson,JSON.stringify(l,null,2)),un.writeFile(e.tokenizerConfig,JSON.stringify(c,null,2))]),{tokenizerJson:l,tokenizerConfig:c}}finally{clearTimeout(r)}}async initialize(){try{this.logger?.info(`Initializing HuggingFace tokenizer: ${this.modelId}`);let e=this.getCachePaths();this.ensureDir(this.cacheDir);let t=await this.loadFromCache()||await this.downloadAndCache();this.tokenizer=new fl(t.tokenizerJson,t.tokenizerConfig),this.logger?.info(`Tokenizer initialized: ${this.name}`)}catch(e){throw this.logger?.error(`Failed to initialize tokenizer: ${e.message}`),new Error(`Failed to initialize HuggingFace tokenizer for ${this.modelId}: ${e.message}`)}}async countTokens(e){if(!this.tokenizer)throw new Error("Tokenizer not initialized");try{let t=this.extractTextFromRequest(e);return this.tokenizer.encode(t).ids.length}catch(t){throw this.logger?.error(`Error counting tokens: ${t.message}`),t}}isInitialized(){return this.tokenizer!==null}encodeText(e){if(!this.tokenizer)throw new Error("Tokenizer not initialized");return this.tokenizer.encode(e).ids}dispose(){this.tokenizer=null}extractTextFromRequest(e){let t=[],{messages:o,system:r,tools:s}=e;if(Array.isArray(o)){for(let a of o)if(typeof a.content=="string")t.push(a.content);else if(Array.isArray(a.content))for(let l of a.content)l.type==="text"&&l.text?t.push(l.text):l.type==="tool_use"&&l.input?t.push(JSON.stringify(l.input)):l.type==="tool_result"&&t.push(typeof l.content=="string"?l.content:JSON.stringify(l.content))}if(typeof r=="string")t.push(r);else if(Array.isArray(r)){for(let a of r)if(a.type==="text"){if(typeof a.text=="string")t.push(a.text);else if(Array.isArray(a.text))for(let l of a.text)l&&t.push(l)}}if(s)for(let a of s)a.name&&t.push(a.name),a.description&&t.push(a.description),a.input_schema&&t.push(JSON.stringify(a.input_schema));return t.join(" ")}}});var pn,ti=S(()=>{"use strict";Z();pn=class{type="api";name;config;logger;options;constructor(e,t,o={}){if(!e.url||!e.apiKey)throw new Error("API tokenizer requires url and apiKey");this.config={url:e.url,apiKey:e.apiKey,requestFormat:e.requestFormat||"standard",responseField:e.responseField||"token_count",headers:e.headers||{}},this.logger=t,this.options=o;try{let r=new URL(e.url);this.name=`api-${r.hostname}`}catch{this.name=`api-${e.url}`}}async initialize(){try{new URL(this.config.url)}catch{throw new Error(`Invalid API URL: ${this.config.url}`)}}async countTokens(e){try{let t=this.formatRequestBody(e),o={"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`,...this.config.headers},r=new AbortController,s=setTimeout(()=>r.abort(),this.options.timeout||3e4),a={method:"POST",headers:o,body:JSON.stringify(t),signal:r.signal},l=this.options.resolveProxyUrl?.();l&&(a.dispatcher=V(l));let c=await fetch(this.config.url,a);if(clearTimeout(s),!c.ok)throw new Error(`API tokenizer request failed: ${c.status} ${c.statusText}`);let i=await c.json();return this.extractTokenCount(i)}catch(t){throw t.name==="AbortError"?new Error("API tokenizer request timed out"):t}}isInitialized(){return!0}dispose(){}formatRequestBody(e){switch(this.config.requestFormat){case"standard":return e;case"openai":return{model:"gpt-3.5-turbo",messages:this.extractMessagesAsOpenAIFormat(e)};case"anthropic":return{messages:e.messages||[],system:e.system,tools:e.tools};case"custom":return{text:this.extractConcatenatedText(e)};default:return e}}extractMessagesAsOpenAIFormat(e){return e.messages?e.messages.map(t=>({role:t.role,content:this.extractTextFromMessage(t)})):[]}extractTextFromMessage(e){return typeof e.content=="string"?e.content:Array.isArray(e.content)?e.content.map(t=>t.type==="text"&&t.text?t.text:t.type==="tool_use"&&t.input?JSON.stringify(t.input):t.type==="tool_result"?typeof t.content=="string"?t.content:JSON.stringify(t.content):"").join(" "):""}extractConcatenatedText(e){let t=[];return e.messages&&e.messages.forEach(o=>{t.push(this.extractTextFromMessage(o))}),typeof e.system=="string"?t.push(e.system):Array.isArray(e.system)&&e.system.forEach(o=>{o.type==="text"&&(typeof o.text=="string"?t.push(o.text):Array.isArray(o.text)&&o.text.forEach(r=>{r&&t.push(r)}))}),e.tools&&e.tools.forEach(o=>{o.name&&t.push(o.name),o.description&&t.push(o.description),o.input_schema&&t.push(JSON.stringify(o.input_schema))}),t.join(" ")}extractTokenCount(e){try{let t=this.config.responseField,o=t.split("."),r=e;for(let s of o){if(r==null)throw new Error(`Field path '${t}' not found in response`);r=r[s]}if(typeof r!="number")throw new Error(`Expected number at field path '${t}', got ${typeof r}`);return r}catch(t){throw this.logger?.error(`Failed to extract token count from API response: ${t.message}. Response: ${JSON.stringify(e)}`),new Error(`Invalid response from API tokenizer: ${t.message}`)}}}});var $e,mo=S(()=>{"use strict";Zs();ei();ti();Z();$e=class{tokenizers=new Map;configService;logger;options;fallbackTokenizer;constructor(e,t,o={}){this.configService=e,this.logger=t,this.options={timeout:o.timeout??3e4,...o}}async initialize(){try{this.fallbackTokenizer=new ot("cl100k_base"),await this.fallbackTokenizer.initialize(),this.tokenizers.set("fallback",this.fallbackTokenizer),this.logger?.info("TokenizerService initialized successfully")}catch(e){throw this.logger?.error(`TokenizerService initialization error: ${e.message}`),e}}async getTokenizer(e,t){let o=this.getCacheKey(e,t);if(this.tokenizers.has(o))return this.tokenizers.get(o);let r;try{switch(e.type){case"tiktoken":r=new ot(e.encoding||"cl100k_base");break;case"huggingface":this.logger?.info(`Initializing HuggingFace tokenizer for model: ${e.model}`),r=new dn(e.model,this.logger,{timeout:this.options.timeout});break;case"api":r=new pn(e,this.logger,{timeout:this.options.timeout,resolveProxyUrl:()=>{let s=t?this.getRawProvider(t):void 0;return se(this.configService,s)}});break;default:throw new Error(`Unknown tokenizer type: ${e.type}`)}return this.logger?.info(`Calling initialize() on ${e.type} tokenizer...`),await r.initialize(),this.tokenizers.set(o,r),this.logger?.info(`Tokenizer initialized successfully: ${e.type} (${o})`),r}catch(s){return this.logger?.error(`Failed to initialize ${e.type} tokenizer: ${s.message}`),this.logger?.error(`Error stack: ${s.stack}`),this.fallbackTokenizer||await this.initialize(),this.fallbackTokenizer}}async countTokens(e,t,o){let r=t?await this.getTokenizer(t,o):this.fallbackTokenizer;return{tokenCount:await r.countTokens(e),tokenizerUsed:r.name,cached:!1}}getTokenizerConfigForModel(e,t){let r=(this.configService.get("providers")||[]).find(s=>s.name===e);if(r?.tokenizer)return r.tokenizer.models?.[t]?r.tokenizer.models[t]:r.tokenizer.default}dispose(){this.tokenizers.forEach(e=>{try{e.dispose()}catch(t){this.logger?.error(`Error disposing tokenizer: ${t}`)}}),this.tokenizers.clear()}getCacheKey(e,t){switch(e.type){case"tiktoken":return`tiktoken:${e.encoding||"cl100k_base"}`;case"huggingface":return`hf:${e.model}`;case"api":return`api:${t||"unscoped"}:${e.url}`;default:return`unknown:${JSON.stringify(e)}`}}getRawProvider(e){return(this.configService.get("providers")||[]).find(o=>o?.name===e)}}});function vo(n){let e=Ro(n);return e?e==="kimi.com"||e.endsWith(".kimi.com")||e==="moonshot.cn"||e.endsWith(".moonshot.cn")?bl:e==="minimaxi.com"||e.endsWith(".minimaxi.com")||e==="minimax.io"||e.endsWith(".minimax.io")?xl:e==="deepseek.com"||e.endsWith(".deepseek.com")?ml:e==="openrouter.ai"||e.endsWith(".openrouter.ai")?gl:e==="siliconflow.com"||e.endsWith(".siliconflow.com")||e==="siliconflow.cn"||e.endsWith(".siliconflow.cn")?hl:e==="bigmodel.cn"||e.endsWith(".bigmodel.cn")?yl:e==="dashscope.aliyuncs.com"||e.endsWith(".dashscope.aliyuncs.com")?_l:e==="xf-yun.com"||e.endsWith(".xf-yun.com")||e==="xfyun.cn"||e.endsWith(".xfyun.cn")||e==="xfyun.com"||e.endsWith(".xfyun.com")?kl:null:null}function Cl(n){let e=Ro(n);return e?.endsWith(".siliconflow.cn")||e==="siliconflow.cn"?"https://api.siliconflow.cn/v1/user/info":"https://api.siliconflow.com/v1/user/info"}function Tl(n,e){let t=To(n);if(t.length===0)return null;let o=String(e||"").split(":").map(s=>s.trim()).filter(Boolean);return t.find(s=>{let a=s?.codingPlanAppCredentialDTO||s?.appCredential||s,l=String(a?.apiKey||a?.api_key||"").trim();return l&&o.some(c=>c.includes(l)||l.includes(c))})||t[0]}function To(n){return!n||typeof n!="object"?[]:!Array.isArray(n)&&n.codingPlanUsageDTO?[n]:Array.isArray(n)?n.flatMap(e=>To(e)):Object.values(n).flatMap(e=>To(e))}function ni(n,e){let t=n.match(new RegExp(`(?:^|;\\s*)${e}=([^;]+)`));return t?decodeURIComponent(t[1]):void 0}function Ro(n){try{return new URL(n).hostname.toLowerCase()}catch{return null}}function M(n){if(typeof n=="number")return Number.isFinite(n)?n:void 0;if(typeof n!="string")return;let e=n.trim().replace(/,/g,"");if(!e)return;let t=Number(e);return Number.isFinite(t)?t:void 0}var ne,go,ho,yo,_o,ko,bo,xo,Co,ml,gl,hl,yl,_l,kl,bl,xl,wo=S(()=>{"use strict";Z();ne=class{async fetchJson(e,t,o,r,s){let a=s||t.apiKey;if(!a)return null;let l={method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${a}`},signal:AbortSignal.timeout(o)};try{r&&(l.dispatcher=V(r));let c=await fetch(e,l);return c.ok?await c.json():null}catch{return null}}hasQuotaData(e){return e.totalBalance!==void 0||e.usedBalance!==void 0||e.remainingBalance!==void 0||e.usedDailyBalance!==void 0||e.limitDaily!==void 0||e.resetTime!==void 0}},go=class extends ne{async queryQuota(e,t,o){let r=await this.fetchJson("https://api.deepseek.com/user/balance",e,t,o),a=(Array.isArray(r?.balance_infos)?r.balance_infos:[]).find(c=>M(c?.total_balance)!==void 0);if(!a)return null;let l=M(a.total_balance);return l===void 0?null:{totalBalance:l,currency:typeof a.currency=="string"?a.currency:void 0}}},ho=class extends ne{async queryQuota(e,t,o){let s=(await this.fetchJson("https://openrouter.ai/api/v1/key",e,t,o))?.data;if(!s||typeof s!="object")return null;let a={},l=M(s.limit),c=M(s.limit_remaining),i=M(s.usage),u=M(s.usage_daily);return l!==void 0&&(a.totalBalance=l),c!==void 0&&(a.remainingBalance=c),i!==void 0&&(a.usedBalance=i),u!==void 0&&(a.usedDailyBalance=u),this.hasQuotaData(a)?a:null}},yo=class extends ne{async queryQuota(e,t,o){let r=Cl(e.baseUrl),a=(await this.fetchJson(r,e,t,o))?.data;if(!a||typeof a!="object")return null;let l={},c=M(a.totalBalance),i=M(a.balance);return c!==void 0&&(l.totalBalance=c),i!==void 0&&(l.remainingBalance=i),c!==void 0&&i!==void 0&&(l.usedBalance=Math.max(0,c-i)),this.hasQuotaData(l)?l:null}},_o=class extends ne{async queryQuota(e,t,o){if(!e.apiKey)return null;let s={method:"GET",headers:{Accept:"application/json",Authorization:e.apiKey.trim()},signal:AbortSignal.timeout(t)};try{o&&(s.dispatcher=V(o));let a=await fetch("https://api.z.ai/api/monitor/usage/quota/limit",s);if(!a.ok)return null;let l=await a.json(),c=Array.isArray(l?.data?.limits)?l.data.limits:[],i=null,u=null,d=null;for(let g of c)g.type==="TOKENS_LIMIT"?g.unit===3?i=g:g.unit===6?u=g:i||(i=g):g.type==="TIME_LIMIT"&&(d=g);let m={};if(i){let g=M(i.currentValue),y=M(i.usage),p=M(i.remaining),f=M(i.percentage);g!==void 0?m.usedDailyBalance=g:f!==void 0&&(m.usedDailyBalance=f,m.limitDaily=100),y!==void 0?m.limitDaily=y:g!==void 0&&p!==void 0&&(m.limitDaily=g+p),i.nextResetTime&&(m.resetTime=new Date(i.nextResetTime).toISOString())}if(u){let g=M(u.currentValue),y=M(u.usage),p=M(u.remaining),f=M(u.percentage);g!==void 0?m.usedBalance=g:f!==void 0&&(m.usedBalance=f,m.totalBalance=100),y!==void 0?m.totalBalance=y:g!==void 0&&p!==void 0&&(m.totalBalance=g+p),u.nextResetTime&&!m.resetTime&&(m.resetTime=new Date(u.nextResetTime).toISOString())}if(d){if(m.usedDailyBalance===void 0){let g=M(d.currentValue);g!==void 0&&(m.usedDailyBalance=g)}if(m.limitDaily===void 0){let g=M(d.usage),y=M(d.currentValue),p=M(d.remaining);g!==void 0?m.limitDaily=g:y!==void 0&&p!==void 0&&(m.limitDaily=y+p)}d.nextResetTime&&!m.resetTime&&(m.resetTime=new Date(d.nextResetTime).toISOString())}return this.hasQuotaData(m)?m:null}catch{return null}}},ko=class extends ne{async queryQuota(e,t,o){if(!e.quotaToken)return null;let r={method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded","User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",Origin:"https://bailian.console.aliyun.com",Referer:"https://bailian.console.aliyun.com/cn-beijing",Cookie:e.quotaToken},signal:AbortSignal.timeout(t)},s=JSON.stringify({Api:"zeldaEasy.broadscope-bailian.codingPlan.queryCodingPlanInstanceInfoV2",V:"1.0",Data:{queryCodingPlanInstanceInfoRequest:{commodityCode:"sfm_codingplan_public_cn",onlyLatestOne:!0},cornerstoneParam:{feTraceId:`ccr-${Date.now()}`,feURL:"https://bailian.console.aliyun.com/cn-beijing",protocol:"V2",console:"ONE_CONSOLE",productCode:"p_efm",switchAgent:10736808,switchUserType:3,domain:"bailian.console.aliyun.com",consoleSite:"BAILIAN_ALIYUN",userNickName:"",userPrincipalName:"",xsp_lang:"zh-CN"}}}),a=new URLSearchParams({params:s,region:"cn-beijing"}).toString();try{o&&(r.dispatcher=V(o));let l=await fetch("https://bailian-cs.console.aliyun.com/data/api.json?action=BroadScopeAspnGateway&product=sfm_bailian&api=zeldaEasy.broadscope-bailian.codingPlan.queryCodingPlanInstanceInfoV2",{...r,body:a});if(!l.ok)return null;let i=(await l.json())?.data?.DataV2?.data?.data?.codingPlanInstanceInfos;if(!Array.isArray(i)||i.length===0)return null;let u=i[0]?.codingPlanQuotaInfo;if(!u)return null;let d={},m=M(u.per5HourUsedQuota),g=M(u.per5HourTotalQuota);m!==void 0&&(d.usedDailyBalance=m),g!==void 0&&(d.limitDaily=g);let y=M(u.perWeekUsedQuota),p=M(u.perWeekTotalQuota);return y!==void 0&&(d.usedBalance=y),p!==void 0&&(d.totalBalance=p),this.hasQuotaData(d)?d:null}catch{return null}}},bo=class extends ne{async queryQuota(e,t,o){if(!e.quotaToken)return null;let s={method:"GET",headers:{Accept:"application/json","User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",Origin:"https://maas.xfyun.cn",Referer:"https://maas.xfyun.cn/packageSubscription",Authorization:(ni(e.quotaToken,"atp-auth-token")||ni(e.quotaToken,"tenantToken")||e.quotaToken).trim(),Cookie:e.quotaToken},signal:AbortSignal.timeout(t)};try{o&&(s.dispatcher=V(o));let a=await fetch("https://maas.xfyun.cn/api/v1/gpt-finetune/coding-plan/list?page=1&size=10",s);if(!a.ok)return null;let l=await a.json();if(l?.succeed===!1||l?.failed===!0)return null;let c=Tl(l,e.apiKey),i=c?.codingPlanUsageDTO||c?.usage||c;if(!i||typeof i!="object")return null;let u={},d=M(i.rp5hUsage),m=M(i.rp5hLimit);d!==void 0&&(u.usedDailyBalance=d),m!==void 0&&(u.limitDaily=m);let g=M(i.rpwUsage),y=M(i.rpwLimit);return g!==void 0&&(u.usedBalance=g),y!==void 0&&(u.totalBalance=y),u.remainingBalance===void 0&&y!==void 0&&g!==void 0&&(u.remainingBalance=Math.max(0,y-g)),this.hasQuotaData(u)?u:null}catch{return null}}},xo=class extends ne{async queryQuota(e,t,o){let r=e.quotaToken||e.apiKey;if(!r)return null;let s={method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${r.trim()}`},signal:AbortSignal.timeout(t)};try{o&&(s.dispatcher=V(o));let a=await fetch("https://api.kimi.com/coding/v1/usages",s);if(!a.ok)return null;let l=await a.json(),c={},i=Array.isArray(l?.limits)?l.limits:[];if(i.length>0&&i[0]?.detail){let d=i[0].detail,m=M(d.limit),g=M(d.remaining),y=d.resetTime;m!==void 0&&g!==void 0&&(c.usedDailyBalance=Math.max(0,m-g),c.limitDaily=m),y&&(c.resetTime=new Date(y).toISOString())}let u=l?.usage;if(u){let d=M(u.limit),m=M(u.remaining),g=M(u.used),y=u.resetTime;d!==void 0&&(c.totalBalance=d,g!==void 0?c.usedBalance=g:m!==void 0&&(c.usedBalance=Math.max(0,d-m),c.remainingBalance=m)),y&&(c.resetTime7d=new Date(y).toISOString(),c.resetTime||(c.resetTime=c.resetTime7d))}return this.hasQuotaData(c)?c:null}catch{return null}}},Co=class extends ne{async queryQuota(e,t,o){let r=e.quotaToken||e.apiKey;if(!r)return null;let s=Ro(e.baseUrl)||"api.minimaxi.com",a=s.endsWith(".minimax.io")||s==="minimax.io"?"api.minimax.io":"api.minimaxi.com";try{let l=[`https://${a}/v1/token_plan/remains`,`https://${a}/v1/api/openplatform/coding_plan/remains`],c=null;for(let b of l)if(c=await this.fetchJson(b,e,t,o,r.trim()),c)break;if(!c)return null;if(c?.base_resp){let b=c.base_resp.status_code;if(b!==void 0&&b!==0)return null}let i=Array.isArray(c?.model_remains)?c.model_remains:[];if(i.length===0)return null;let u=i[0],d={},m=M(u.current_interval_total_count),g=M(u.current_interval_usage_count),y=M(u.current_interval_remaining_percent),p=M(u.end_time);m!==void 0&&g!==void 0&&m>0?(d.usedDailyBalance=Math.max(0,m-g),d.limitDaily=m):y!==void 0&&(d.limitDaily=100,d.usedDailyBalance=Math.max(0,100-y)),p&&(d.resetTime=new Date(p).toISOString());let f=M(u.current_weekly_total_count),_=M(u.current_weekly_usage_count),k=M(u.current_weekly_remaining_percent),h=M(u.weekly_end_time);return f!==void 0&&_!==void 0&&f>0?(d.usedBalance=Math.max(0,f-_),d.remainingBalance=_,d.totalBalance=f):k!==void 0&&(d.totalBalance=100,d.usedBalance=Math.max(0,100-k),d.remainingBalance=k),h&&!d.resetTime&&(d.resetTime=new Date(h).toISOString()),this.hasQuotaData(d)?d:null}catch{return null}}},ml=new go,gl=new ho,hl=new yo,yl=new _o,_l=new ko,kl=new bo,bl=new xo,xl=new Co});function oi(n){return{[vl]:n,[Rl]:Rt}}function Sl(n){return n===!0||n==="true"||n===1||n==="1"}function Pl(n){let e=n.getFullYear(),t=String(n.getMonth()+1).padStart(2,"0"),o=String(n.getDate()).padStart(2,"0");return`${e}-${t}-${o}`}function Al(n){try{let e=new URL(n),t=e.pathname;return t.endsWith("/v1/messages")?t=t.slice(0,-12):t.endsWith("/messages")?t=t.slice(0,-9):t.endsWith("/v1/chat/completions")?t=t.slice(0,-20):t.endsWith("/chat/completions")&&(t=t.slice(0,-17)),t.endsWith("/v1")||(t=t.endsWith("/")?`${t}v1`:`${t}/v1`),e.pathname=`${t}/models`,e.toString()}catch{return null}}function Ol(n){try{let e=new URL(n).hostname.toLowerCase();return e.includes("moonshot")||e.includes("kimi")}catch{return!1}}async function So(n,e,t){let o=Al(n.baseUrl);if(!o)return{success:!1,error:"Cannot derive models endpoint from baseUrl"};try{let r={method:"GET",headers:{Authorization:`Bearer ${n.apiKey}`},signal:AbortSignal.timeout(e)};t&&(r.dispatcher=V(t));let s=await fetch(o,r);if(s.headers&&Ge(n.name,n.baseUrl,s.headers),s.ok)return{success:!0,headers:s.headers};if(s.status===429)return{success:!1,error:`HTTP 429: ${(await s.text().catch(()=>"")).slice(0,100)||"Rate limited"}`,headers:s.headers};if(s.status>=400&&s.status<500)return{success:!0,headers:s.headers};let a=await s.text().catch(()=>"");return{success:!1,error:`HTTP ${s.status}: ${a.slice(0,100)}`,headers:s.headers}}catch(r){return{success:!1,error:r?.message||r?.toString()||"Unknown probe error"}}}async function El(n,e,t,o){let r=n.wakeupModel||(Array.isArray(n.models)?n.models[0]:void 0);if(!r)return{success:!1,error:"No models configured for provider"};let s=n.baseUrl,a=n.baseUrl.includes("/messages")||r.includes("claude");try{let l={"Content-Type":"application/json",...oi("scheduled-wakeup")};a?(l["x-api-key"]=n.apiKey,l["anthropic-version"]="2023-06-01"):l.Authorization=`Bearer ${n.apiKey}`;let c={method:"POST",headers:l,body:JSON.stringify({model:r,messages:[{role:"user",content:"Wake up and acknowledge with a short greeting."}],max_tokens:10}),signal:AbortSignal.timeout(e)};t&&(c.dispatcher=V(t)),o?.info(`Sending scheduled wake-up call to provider ${n.name} using model ${r}...`);let i=await fetch(s,c);if(i.ok)return{success:!0};let u=await i.text().catch(()=>"");return{success:!1,error:`HTTP ${i.status}: ${u.slice(0,200)||"Unknown error"}`}}catch(l){return{success:!1,error:l?.message||l?.toString()||"Unknown wake-up error"}}}async function Il(n,e,t,o,r){let s=n.baseUrl,a=n.baseUrl.includes("/messages")||e.includes("claude");try{let l={"Content-Type":"application/json",...oi("rate-limit-probe")};a?(l["x-api-key"]=n.apiKey,l["anthropic-version"]="2023-06-01"):l.Authorization=`Bearer ${n.apiKey}`;let c={method:"POST",headers:l,body:JSON.stringify({model:e,messages:[{role:"user",content:"Hello, please reply briefly."}],max_tokens:10}),signal:AbortSignal.timeout(t)};o&&(c.dispatcher=V(o)),r?.debug?.(`Sending independent ping to rate-limited model ${n.name} (${e})...`);let i=await fetch(s,c);if(i.ok)return{success:!0};let u=await i.text().catch(()=>"");return{success:!1,error:`HTTP ${i.status}: ${u.slice(0,200)||"Unknown error"}`}}catch(l){return{success:!1,error:l?.message||l?.toString()||"Unknown ping error"}}}function ri(n,e,t,o,r){return de||(de=new fn(n,e,t,o,r)),de}function Ne(n,e,t,o,r){let s=ri(n,e,t,o,r);return s.start(),s}function Po(){de&&de.stop()}function mn(){de&&(de.stop(),de=null)}var vl,Rl,wl,fn,de,gn=S(()=>{"use strict";ee();ve();wo();Se();Hn();Z();vl="x-claude-code-router-source",Rl="x-claude-code-router-version";wl={enabled:!0,quotaProbeIntervalMinutes:10,probeTimeoutMs:15e3,initialDelayMs:5e3,excludeProviders:[]};fn=class{config;quotaProbeTimer;healthProbeTimer;wakeupTimer;rateLimitProbeTimer;lastWakeupDate=new Map;getProviders;resolveProxyUrl;logger;getConfig;running=!1;constructor(e,t,o,r,s){this.config={...wl,...t},this.getProviders=e,this.resolveProxyUrl=o,this.logger=r,this.getConfig=s}start(){if(this.running)return;let e=this.isWakeupGloballyEnabled();!this.config.enabled&&!e||(this.running=!0,setTimeout(()=>{this.running&&(this.config.enabled&&(this.runQuotaProbe(),this.runHealthProbe(),this.runRateLimitProbe()),this.runScheduledWakeup())},this.config.initialDelayMs),this.config.enabled&&(this.quotaProbeTimer=setInterval(()=>this.runQuotaProbe(),this.config.quotaProbeIntervalMinutes*60*1e3),this.healthProbeTimer=setInterval(()=>this.runHealthProbe(),300*1e3),this.rateLimitProbeTimer=setInterval(()=>this.runRateLimitProbe(),120*1e3)),this.wakeupTimer=setInterval(()=>this.runScheduledWakeup(),60*1e3),this.logger?.info("Active probe service started"))}stop(){this.running=!1,this.quotaProbeTimer&&(clearInterval(this.quotaProbeTimer),this.quotaProbeTimer=void 0),this.healthProbeTimer&&(clearInterval(this.healthProbeTimer),this.healthProbeTimer=void 0),this.rateLimitProbeTimer&&(clearInterval(this.rateLimitProbeTimer),this.rateLimitProbeTimer=void 0),this.wakeupTimer&&(clearInterval(this.wakeupTimer),this.wakeupTimer=void 0),this.logger?.info("Active probe service stopped")}async runQuotaProbe(){let e=this.getProviders().filter(s=>s?.name&&s.enabled!==!1&&!this.config.excludeProviders.includes(s.name)),t=U();if(e.length===0)return;let o=[];for(let s of e){let a=vo(s.baseUrl),l=Array.isArray(s.models)?s.models:[],c=this.resolveProxyUrl?.(s);a&&o.push({provider:s.name,models:l,type:"quota-adapter",promise:a.queryQuota(s,this.config.probeTimeoutMs,c).then(i=>{if(i){no(s.name,i),this.logger?.debug?.(`Stored quota probe result for ${s.name}`);let u=i.limitDaily!==void 0&&i.usedDailyBalance!==void 0&&i.usedDailyBalance>=i.limitDaily,d=i.totalBalance!==void 0&&i.usedBalance!==void 0&&i.usedBalance>=i.totalBalance;if(u||d){let m=u?`Quota exhausted: 5h limit reached (${i.usedDailyBalance}/${i.limitDaily})`:`Quota exhausted: 7d balance depleted (${i.usedBalance}/${i.totalBalance})`;for(let g of l){if(t.getState(s.name,g)?.rateLimitUntil){this.logger?.debug?.(`Skip forceOpen for ${s.name} (${g}): already rate-limited with active cooldown`);continue}t.forceOpen(s.name,g,m)}this.logger?.warn?.(`${m} for ${s.name}, marked as unhealthy`)}else for(let m of l){let g=t.getState(s.name,m);g&&g.status==="open"&&g.lastError?.includes("Quota exhausted")&&(t.recover(s.name,m),this.logger?.info?.(`Quota recovered for ${s.name} (${m}), marked as healthy`))}}})}),Ol(s.baseUrl)&&o.push({provider:s.name,models:l,type:"rate-limit-headers",promise:So(s,this.config.probeTimeoutMs,c).then(()=>{})})}if(o.length===0)return;this.logger?.debug?.(`Running quota probe with ${o.length} tasks for ${e.length} providers`);let r=await Promise.allSettled(o.map(s=>s.promise));for(let s=0;s<o.length;s++){let a=r[s];if(a.status==="rejected"){let l=o[s];this.logger?.warn?.(`Quota probe failed for ${l.provider} (${l.type}): ${a.reason}`)}}}async runHealthProbe(){let e=U(),t=this.getProviders().filter(r=>r?.name&&r.enabled!==!1&&!this.config.excludeProviders.includes(r.name));if(t.length===0)return;this.logger?.debug?.(`Running health probe for ${t.length} providers`);let o=await Promise.allSettled(t.map(r=>So(r,this.config.probeTimeoutMs,this.resolveProxyUrl?.(r))));for(let r=0;r<t.length;r++){let s=t[r],a=o[r],l=Array.isArray(s.models)?s.models:[];if(a.status==="fulfilled"){let c=a.value;if(c.success){let i=0;for(let u of l){let d=e.getState(s.name,u);if(d&&d.status==="open"){let m=d.lastError?.includes("Quota exhausted"),g=d.rateLimitUntil||d.lastError&&(d.lastError.includes("429")||d.lastError.toLowerCase().includes("rate limit")||d.lastError.toLowerCase().includes("rate_limit")||d.lastError.toLowerCase().includes("too many requests")||d.lastError.toLowerCase().includes("\u9650\u6D41"));if(m){this.logger?.debug?.(`Skipping health probe recovery for ${s.name} (${u}) because quota is exhausted`);continue}if(g||d.rateLimitUntil){this.logger?.debug?.(`Skipping health probe recovery for rate-limited ${s.name} (${u})`);continue}}e.recordSuccess(s.name,u),i++}i>0&&this.logger?.info?.(`Health probe succeeded for ${s.name}`)}else{for(let i of l)e.recordFailure(s.name,i,c.error);this.logger?.warn?.(`Health probe failed for ${s.name}: ${c.error}`)}}else{for(let c of l)e.recordFailure(s.name,c,a.reason?.message||"Probe error");this.logger?.warn?.(`Health probe error for ${s.name}: ${a.reason}`)}}}async runRateLimitProbe(){let e=U(),t=e.getRateLimitedModels();if(t.length===0)return;let o=this.getProviders(),r=this.config.probeTimeoutMs;this.logger?.debug?.(`Running rate-limit recovery probe for ${t.length} model(s)`);for(let s of t){let[a,...l]=s.split(","),c=l.join(",");if(!a||!c)continue;let i=e.getState(a,c);if(!i||!i.rateLimitUntil)continue;if(Date.now()>=i.rateLimitUntil){e.recover(a,c),this.logger?.info?.(`Rate-limit cooldown expired, auto-recovered ${s}`);continue}let u=o.find(d=>d?.name===a&&d.enabled!==!1);if(!u){this.logger?.warn?.(`Provider ${a} not found or disabled for rate-limit probe`);continue}try{let d=await Il(u,c,r,this.resolveProxyUrl?.(u),this.logger);if(d.success)this.logger?.info?.(`Rate-limit probe succeeded for ${s}, recovering model`),e.recover(a,c);else if(d.error&&(d.error.includes("429")||d.error.toLowerCase().includes("rate limit")||d.error.toLowerCase().includes("rate_limit")||d.error.toLowerCase().includes("too many requests")||d.error.toLowerCase().includes("\u9650\u6D41"))){let m=Date.now();i.rateLimitUntil&&i.rateLimitUntil>m?i.rateLimitUntil+=120*1e3:i.rateLimitUntil=m+120*1e3,this.logger?.debug?.(`Rate-limit probe for ${s} confirmed still limited, extending cooldown`)}else this.logger?.debug?.(`Rate-limit probe for ${s} returned non-rate-limit error: ${d.error?.slice(0,100)}`)}catch(d){this.logger?.warn?.(`Rate-limit probe exception for ${s}: ${d?.message||d}`)}}}async runScheduledWakeup(){if(!this.isWakeupGloballyEnabled())return;let e=this.getProviders().filter(l=>l?.name&&l.enabled!==!1&&l.wakeupEnabled===!0);if(e.length===0)return;let t=new Date,o=t.getHours(),r=t.getMinutes(),s=Pl(t),a=this.getConfig&&this.getConfig("WAKEUP_TIME")||"06:00";for(let l of e){let c=l.wakeupTime||a,[i,u]=c.split(":"),d=parseInt(i,10),m=parseInt(u,10);if(isNaN(d)||isNaN(m))continue;let g=o>d||o===d&&r>=m,y=(d*60+m)*6e4-(o*60+r)*6e4,p=y>0&&y<=300*1e3;(g||p)&&!this.hasWakeupFiredToday(l.name,s)&&(this.logger?.info?.(`Scheduled wake-up triggered for provider ${l.name} at ${c}`),El(l,3e4,this.resolveProxyUrl?.(l),this.logger).then(f=>{f.success?this.logger?.info?.(`Successfully woke up provider ${l.name}`):this.logger?.error?.(`Failed to wake up provider ${l.name}: ${f.error}`)}).catch(f=>{this.logger?.error?.(`Error in wake-up task for ${l.name}: ${f}`)}))}}isWakeupGloballyEnabled(){return this.getConfig?Sl(this.getConfig("WAKEUP_ENABLED")):!1}hasWakeupFiredToday(e,t){return this.lastWakeupDate.get(e)===t?!0:(this.lastWakeupDate.set(e,t),!1)}async probeProviderManually(e){let o=this.getProviders().find(a=>a.name===e);if(!o)return this.logger?.warn?.(`Provider ${e} not found for manual probe`),!1;if(o.enabled===!1)return this.logger?.warn?.(`Provider ${e} is disabled, skipping manual probe`),!1;let r=await So(o,this.config.probeTimeoutMs,this.resolveProxyUrl?.(o)),s=Array.isArray(o.models)?o.models:[];if(r.success)for(let a of s)U().recordSuccess(o.name,a);else for(let a of s)U().recordFailure(o.name,a,r.error);return r.success}},de=null});var si=S(()=>{"use strict"});var Ao,rt,ii=S(()=>{"use strict";Ao=class{plugins=new Map;pluginInstances=new Map;registerPlugin(e,t={}){this.pluginInstances.set(e.name,e),this.plugins.set(e.name,{name:e.name,enabled:t.enabled!==!1,options:t})}async enablePlugin(e,t){let o=this.plugins.get(e),r=this.pluginInstances.get(e);if(!o||!r)throw new Error(`Plugin ${e} not found`);o.enabled&&await t.register(r.register,o.options)}async enablePlugins(e){for(let[t,o]of this.plugins)if(o.enabled)try{await this.enablePlugin(t,e)}catch(r){let s=r instanceof Error?r.message:String(r);e.log?.error(`Failed to enable plugin ${t}: ${s}`)}}getPlugins(){return Array.from(this.plugins.values())}getPlugin(e){return this.pluginInstances.get(e)}hasPlugin(e){return this.pluginInstances.has(e)}isPluginEnabled(e){return this.plugins.get(e)?.enabled||!1}setPluginEnabled(e,t){let o=this.plugins.get(e);o&&(o.enabled=t)}removePlugin(e){this.plugins.delete(e),this.pluginInstances.delete(e)}clear(){this.plugins.clear(),this.pluginInstances.clear()}},rt=new Ao});var oe,Oo=S(()=>{"use strict";oe=class extends TransformStream{buffer="";currentEvent={};constructor(){super({transform:(e,t)=>{this.buffer+=e;let o=this.buffer.split(`
|
|
304
|
-
`);this.buffer=o.pop()||"";for(let r of o){let s=this.processLine(r);s&&t.enqueue(s)}},flush:e=>{if(this.buffer.trim()){let t=[];this.processLine(this.buffer.trim(),t),t.forEach(o=>e.enqueue(o))}Object.keys(this.currentEvent).length>0&&e.enqueue(this.currentEvent)}})}processLine(e,t){if(!e.trim()){if(Object.keys(this.currentEvent).length>0){let o={...this.currentEvent};return this.currentEvent={},t?(t.push(o),null):o}return null}if(e.startsWith("event:"))this.currentEvent.event=e.slice(6).trim();else if(e.startsWith("data:")){let o=e.slice(5).trim();if(o==="[DONE]")this.currentEvent.data={type:"done"};else try{this.currentEvent.data=JSON.parse(o)}catch{this.currentEvent.data={raw:o,error:"JSON parse failed"}}}else e.startsWith("id:")?this.currentEvent.id=e.slice(3).trim():e.startsWith("retry:")&&(this.currentEvent.retry=parseInt(e.slice(6).trim()));return null}}});var Le,
|
|
303
|
+
Stack: ${e.stack}`)}}async registerDefaultTransformersInternal(){try{Object.values(Vs).forEach(e=>{if("TransformerName"in e&&typeof e.TransformerName=="string")this.registerTransformer(e.TransformerName,e);else{let t=new e;t&&typeof t=="object"&&(t.logger=this.logger),this.registerTransformer(t.name,t)}})}catch(e){this.logger.error({error:e},"transformer regist error:")}}async loadFromConfig(){let e=this.configService.get("transformers",[]);for(let t of e)await this.registerTransformerFromConfig(t)}}});import{get_encoding as el}from"tiktoken";var nt,Ks=S(()=>{"use strict";nt=class{type="tiktoken";name;encoding;constructor(e="cl100k_base"){this.name=`tiktoken-${e}`;try{this.encoding=el(e)}catch{throw new Error(`Failed to initialize tiktoken encoding: ${e}`)}}async initialize(){if(!this.encoding)throw new Error("Tiktoken encoding not initialized")}async countTokens(e){let t=this.encoding;if(!t)throw new Error("Encoding not initialized");let o=0,{messages:r,system:s,tools:a}=e;return Array.isArray(r)&&r.forEach(l=>{typeof l.content=="string"?o+=t.encode(l.content).length:Array.isArray(l.content)&&l.content.forEach(c=>{if(c.type==="text")o+=t.encode(c.text).length;else if(c.type==="tool_use")o+=t.encode(JSON.stringify(c.input)).length;else if(c.type==="tool_result"){let i=typeof c.content=="string"?c.content:JSON.stringify(c.content);o+=t.encode(i).length}})}),typeof s=="string"?o+=t.encode(s).length:Array.isArray(s)&&s.forEach(l=>{l.type==="text"&&(typeof l.text=="string"?o+=t.encode(l.text).length:Array.isArray(l.text)&&l.text.forEach(c=>{o+=t.encode(c||"").length}))}),a&&a.forEach(l=>{l.description&&(o+=t.encode(l.name+l.description).length),l.input_schema&&(o+=t.encode(JSON.stringify(l.input_schema)).length)}),o}isInitialized(){return this.encoding!==void 0}encodeText(e){let t=this.encoding;if(!t)throw new Error("Encoding not initialized");return Array.from(t.encode(e))}dispose(){this.encoding&&(this.encoding.free(),this.encoding=void 0)}}});import{join as ln}from"path";import{homedir as tl}from"os";import{existsSync as po,mkdirSync as nl}from"fs";import{promises as un}from"fs";import{Tokenizer as ol}from"@huggingface/tokenizers";var dn,Xs=S(()=>{"use strict";dn=class{type="huggingface";name;modelId;logger;options;tokenizer=null;cacheDir;safeModelName;constructor(e,t,o={}){this.modelId=e,this.logger=t,this.options=o,this.cacheDir=o.cacheDir||ln(tl(),".claude-code-router",".huggingface"),this.safeModelName=e.replace(/\//g,"_").replace(/[^a-zA-Z0-9_-]/g,"_"),this.name=`huggingface-${e.split("/").pop()}`}getCachePaths(){let e=ln(this.cacheDir,this.safeModelName);return{modelDir:e,tokenizerJson:ln(e,"tokenizer.json"),tokenizerConfig:ln(e,"tokenizer_config.json")}}ensureDir(e){po(e)||nl(e,{recursive:!0})}async loadFromCache(){try{let e=this.getCachePaths();if(!po(e.tokenizerJson)||!po(e.tokenizerConfig))return null;let[t,o]=await Promise.all([un.readFile(e.tokenizerJson,"utf-8"),un.readFile(e.tokenizerConfig,"utf-8")]);return{tokenizerJson:JSON.parse(t),tokenizerConfig:JSON.parse(o)}}catch(e){return this.logger?.warn(`Failed to load from cache: ${e.message}`),null}}async downloadAndCache(){let e=this.getCachePaths(),t={json:`https://huggingface.co/${this.modelId}/resolve/main/tokenizer.json`,config:`https://huggingface.co/${this.modelId}/resolve/main/tokenizer_config.json`};this.logger?.info(`Downloading tokenizer files for ${this.modelId}`);let o=new AbortController,r=setTimeout(()=>o.abort(),this.options.timeout||3e4);try{let[s,a]=await Promise.all([fetch(t.json,{signal:o.signal}),fetch(t.config,{signal:o.signal})]);if(!s.ok)throw new Error(`Failed to fetch tokenizer.json: ${s.statusText}`);let[l,c]=await Promise.all([s.json(),a.ok?a.json():Promise.resolve({})]);return this.ensureDir(e.modelDir),await Promise.all([un.writeFile(e.tokenizerJson,JSON.stringify(l,null,2)),un.writeFile(e.tokenizerConfig,JSON.stringify(c,null,2))]),{tokenizerJson:l,tokenizerConfig:c}}finally{clearTimeout(r)}}async initialize(){try{this.logger?.info(`Initializing HuggingFace tokenizer: ${this.modelId}`);let e=this.getCachePaths();this.ensureDir(this.cacheDir);let t=await this.loadFromCache()||await this.downloadAndCache();this.tokenizer=new ol(t.tokenizerJson,t.tokenizerConfig),this.logger?.info(`Tokenizer initialized: ${this.name}`)}catch(e){throw this.logger?.error(`Failed to initialize tokenizer: ${e.message}`),new Error(`Failed to initialize HuggingFace tokenizer for ${this.modelId}: ${e.message}`)}}async countTokens(e){if(!this.tokenizer)throw new Error("Tokenizer not initialized");try{let t=this.extractTextFromRequest(e);return this.tokenizer.encode(t).ids.length}catch(t){throw this.logger?.error(`Error counting tokens: ${t.message}`),t}}isInitialized(){return this.tokenizer!==null}encodeText(e){if(!this.tokenizer)throw new Error("Tokenizer not initialized");return this.tokenizer.encode(e).ids}dispose(){this.tokenizer=null}extractTextFromRequest(e){let t=[],{messages:o,system:r,tools:s}=e;if(Array.isArray(o)){for(let a of o)if(typeof a.content=="string")t.push(a.content);else if(Array.isArray(a.content))for(let l of a.content)l.type==="text"&&l.text?t.push(l.text):l.type==="tool_use"&&l.input?t.push(JSON.stringify(l.input)):l.type==="tool_result"&&t.push(typeof l.content=="string"?l.content:JSON.stringify(l.content))}if(typeof r=="string")t.push(r);else if(Array.isArray(r)){for(let a of r)if(a.type==="text"){if(typeof a.text=="string")t.push(a.text);else if(Array.isArray(a.text))for(let l of a.text)l&&t.push(l)}}if(s)for(let a of s)a.name&&t.push(a.name),a.description&&t.push(a.description),a.input_schema&&t.push(JSON.stringify(a.input_schema));return t.join(" ")}}});var pn,Ys=S(()=>{"use strict";te();pn=class{type="api";name;config;logger;options;constructor(e,t,o={}){if(!e.url||!e.apiKey)throw new Error("API tokenizer requires url and apiKey");this.config={url:e.url,apiKey:e.apiKey,requestFormat:e.requestFormat||"standard",responseField:e.responseField||"token_count",headers:e.headers||{}},this.logger=t,this.options=o;try{let r=new URL(e.url);this.name=`api-${r.hostname}`}catch{this.name=`api-${e.url}`}}async initialize(){try{new URL(this.config.url)}catch{throw new Error(`Invalid API URL: ${this.config.url}`)}}async countTokens(e){try{let t=this.formatRequestBody(e),o={"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`,...this.config.headers},r=new AbortController,s=setTimeout(()=>r.abort(),this.options.timeout||3e4),a={method:"POST",headers:o,body:JSON.stringify(t),signal:r.signal},l=this.options.resolveProxyUrl?.();l&&(a.dispatcher=G(l));let c=await fetch(this.config.url,a);if(clearTimeout(s),!c.ok)throw new Error(`API tokenizer request failed: ${c.status} ${c.statusText}`);let i=await c.json();return this.extractTokenCount(i)}catch(t){throw t.name==="AbortError"?new Error("API tokenizer request timed out"):t}}isInitialized(){return!0}dispose(){}formatRequestBody(e){switch(this.config.requestFormat){case"standard":return e;case"openai":return{model:"gpt-3.5-turbo",messages:this.extractMessagesAsOpenAIFormat(e)};case"anthropic":return{messages:e.messages||[],system:e.system,tools:e.tools};case"custom":return{text:this.extractConcatenatedText(e)};default:return e}}extractMessagesAsOpenAIFormat(e){return e.messages?e.messages.map(t=>({role:t.role,content:this.extractTextFromMessage(t)})):[]}extractTextFromMessage(e){return typeof e.content=="string"?e.content:Array.isArray(e.content)?e.content.map(t=>t.type==="text"&&t.text?t.text:t.type==="tool_use"&&t.input?JSON.stringify(t.input):t.type==="tool_result"?typeof t.content=="string"?t.content:JSON.stringify(t.content):"").join(" "):""}extractConcatenatedText(e){let t=[];return e.messages&&e.messages.forEach(o=>{t.push(this.extractTextFromMessage(o))}),typeof e.system=="string"?t.push(e.system):Array.isArray(e.system)&&e.system.forEach(o=>{o.type==="text"&&(typeof o.text=="string"?t.push(o.text):Array.isArray(o.text)&&o.text.forEach(r=>{r&&t.push(r)}))}),e.tools&&e.tools.forEach(o=>{o.name&&t.push(o.name),o.description&&t.push(o.description),o.input_schema&&t.push(JSON.stringify(o.input_schema))}),t.join(" ")}extractTokenCount(e){try{let t=this.config.responseField,o=t.split("."),r=e;for(let s of o){if(r==null)throw new Error(`Field path '${t}' not found in response`);r=r[s]}if(typeof r!="number")throw new Error(`Expected number at field path '${t}', got ${typeof r}`);return r}catch(t){throw this.logger?.error(`Failed to extract token count from API response: ${t.message}. Response: ${JSON.stringify(e)}`),new Error(`Invalid response from API tokenizer: ${t.message}`)}}}});var $e,fo=S(()=>{"use strict";Ks();Xs();Ys();te();$e=class{tokenizers=new Map;configService;logger;options;fallbackTokenizer;constructor(e,t,o={}){this.configService=e,this.logger=t,this.options={timeout:o.timeout??3e4,...o}}async initialize(){try{this.fallbackTokenizer=new nt("cl100k_base"),await this.fallbackTokenizer.initialize(),this.tokenizers.set("fallback",this.fallbackTokenizer),this.logger?.info("TokenizerService initialized successfully")}catch(e){throw this.logger?.error(`TokenizerService initialization error: ${e.message}`),e}}async getTokenizer(e,t){let o=this.getCacheKey(e,t);if(this.tokenizers.has(o))return this.tokenizers.get(o);let r;try{switch(e.type){case"tiktoken":r=new nt(e.encoding||"cl100k_base");break;case"huggingface":this.logger?.info(`Initializing HuggingFace tokenizer for model: ${e.model}`),r=new dn(e.model,this.logger,{timeout:this.options.timeout});break;case"api":r=new pn(e,this.logger,{timeout:this.options.timeout,resolveProxyUrl:()=>{let s=t?this.getRawProvider(t):void 0;return ie(this.configService,s)}});break;default:throw new Error(`Unknown tokenizer type: ${e.type}`)}return this.logger?.info(`Calling initialize() on ${e.type} tokenizer...`),await r.initialize(),this.tokenizers.set(o,r),this.logger?.info(`Tokenizer initialized successfully: ${e.type} (${o})`),r}catch(s){return this.logger?.error(`Failed to initialize ${e.type} tokenizer: ${s.message}`),this.logger?.error(`Error stack: ${s.stack}`),this.fallbackTokenizer||await this.initialize(),this.fallbackTokenizer}}async countTokens(e,t,o){let r=t?await this.getTokenizer(t,o):this.fallbackTokenizer;return{tokenCount:await r.countTokens(e),tokenizerUsed:r.name,cached:!1}}getTokenizerConfigForModel(e,t){let r=(this.configService.get("providers")||[]).find(s=>s.name===e);if(r?.tokenizer)return r.tokenizer.models?.[t]?r.tokenizer.models[t]:r.tokenizer.default}dispose(){this.tokenizers.forEach(e=>{try{e.dispose()}catch(t){this.logger?.error(`Error disposing tokenizer: ${t}`)}}),this.tokenizers.clear()}getCacheKey(e,t){switch(e.type){case"tiktoken":return`tiktoken:${e.encoding||"cl100k_base"}`;case"huggingface":return`hf:${e.model}`;case"api":return`api:${t||"unscoped"}:${e.url}`;default:return`unknown:${JSON.stringify(e)}`}}getRawProvider(e){return(this.configService.get("providers")||[]).find(o=>o?.name===e)}}});function qs(n){if(!n||typeof n!="object"||ul(n))return null;for(let t of ll(n)){let o=cl(t);if(o)return o}return null}function cl(n){if(!n||typeof n!="object")return null;let e={},t=fn(n,rl);if(t!==void 0){let a=Zs(t);e.usedDailyBalance=a,e.limitDaily=100}let o=fn(n,sl);if(o!==void 0){let a=Zs(o);e.usedBalance=a,e.totalBalance=100}let r=fn(n,il);if(r!==void 0){let a=ei(r);a&&(e.resetTime=a)}let s=fn(n,al);if(s!==void 0){let a=ei(s);a&&(e.resetTime7d=a,e.resetTime||(e.resetTime=a))}return e.usedDailyBalance===void 0&&e.limitDaily===void 0&&e.usedBalance===void 0&&e.totalBalance===void 0&&e.resetTime===void 0?null:e}function Zs(n){return!Number.isFinite(n)||n<=0?0:Math.round(n*1e4)/100}function fn(n,e){for(let t of e){let o=M(n?.[t]);if(o!==void 0)return o}}function ll(n){let e=[],t=new WeakSet,o=["data","Data","DataV2"],r=s=>{if(!(!s||typeof s!="object")&&!t.has(s)){t.add(s),e.push(s);for(let a of o)s[a]&&typeof s[a]=="object"&&r(s[a])}};return r(n),e}function ul(n){let e=n?.data;return e&&typeof e=="object"&&(e.success===!1||e.errorCode||e.errorMsg)?String(e.errorCode||e.errorMsg||"gateway-error"):null}function ei(n){if(typeof n!="string"&&typeof n!="number")return;let e=n;if(typeof n=="number"&&n<1e12&&(e=n*1e3),typeof n=="string"){let o=Number(n.trim());Number.isFinite(o)&&o<1e12&&(e=o*1e3)}let t=new Date(e);return isNaN(t.getTime())?void 0:t.toISOString()}function Ro(n){let e=wo(n);return e?e==="kimi.com"||e.endsWith(".kimi.com")||e==="moonshot.cn"||e.endsWith(".moonshot.cn")?_l:e==="minimaxi.com"||e.endsWith(".minimaxi.com")||e==="minimax.io"||e.endsWith(".minimax.io")?kl:e==="deepseek.com"||e.endsWith(".deepseek.com")?dl:e==="openrouter.ai"||e.endsWith(".openrouter.ai")?pl:e==="siliconflow.com"||e.endsWith(".siliconflow.com")||e==="siliconflow.cn"||e.endsWith(".siliconflow.cn")?fl:e==="bigmodel.cn"||e.endsWith(".bigmodel.cn")?ml:e==="dashscope.aliyuncs.com"||e.endsWith(".dashscope.aliyuncs.com")?gl:e==="maas.aliyuncs.com"||e.endsWith(".maas.aliyuncs.com")?hl:e==="xf-yun.com"||e.endsWith(".xf-yun.com")||e==="xfyun.cn"||e.endsWith(".xfyun.cn")||e==="xfyun.com"||e.endsWith(".xfyun.com")?yl:null:null}function bl(n){let e=wo(n);return e?.endsWith(".siliconflow.cn")||e==="siliconflow.cn"?"https://api.siliconflow.cn/v1/user/info":"https://api.siliconflow.com/v1/user/info"}function xl(n,e){let t=To(n);if(t.length===0)return null;let o=String(e||"").split(":").map(s=>s.trim()).filter(Boolean);return t.find(s=>{let a=s?.codingPlanAppCredentialDTO||s?.appCredential||s,l=String(a?.apiKey||a?.api_key||"").trim();return l&&o.some(c=>c.includes(l)||l.includes(c))})||t[0]}function To(n){return!n||typeof n!="object"?[]:!Array.isArray(n)&&n.codingPlanUsageDTO?[n]:Array.isArray(n)?n.flatMap(e=>To(e)):Object.values(n).flatMap(e=>To(e))}function vo(n,e){let t=n.match(new RegExp(`(?:^|;\\s*)${e}=([^;]+)`));return t?decodeURIComponent(t[1]):void 0}function wo(n){try{return new URL(n).hostname.toLowerCase()}catch{return null}}function M(n){if(typeof n=="number")return Number.isFinite(n)?n:void 0;if(typeof n!="string")return;let e=n.trim().replace(/,/g,"");if(!e)return;let t=Number(e);return Number.isFinite(t)?t:void 0}var oe,mo,go,ho,yo,_o,rl,sl,il,al,ko,bo,xo,Co,dl,pl,fl,ml,gl,hl,yl,_l,kl,So=S(()=>{"use strict";te();oe=class{async fetchJson(e,t,o,r,s){let a=s||t.apiKey;if(!a)return null;let l={method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${a}`},signal:AbortSignal.timeout(o)};try{r&&(l.dispatcher=G(r));let c=await fetch(e,l);return c.ok?await c.json():null}catch{return null}}hasQuotaData(e){return e.totalBalance!==void 0||e.usedBalance!==void 0||e.remainingBalance!==void 0||e.usedDailyBalance!==void 0||e.limitDaily!==void 0||e.resetTime!==void 0}},mo=class extends oe{async queryQuota(e,t,o){let r=await this.fetchJson("https://api.deepseek.com/user/balance",e,t,o),a=(Array.isArray(r?.balance_infos)?r.balance_infos:[]).find(c=>M(c?.total_balance)!==void 0);if(!a)return null;let l=M(a.total_balance);return l===void 0?null:{totalBalance:l,currency:typeof a.currency=="string"?a.currency:void 0}}},go=class extends oe{async queryQuota(e,t,o){let s=(await this.fetchJson("https://openrouter.ai/api/v1/key",e,t,o))?.data;if(!s||typeof s!="object")return null;let a={},l=M(s.limit),c=M(s.limit_remaining),i=M(s.usage),u=M(s.usage_daily);return l!==void 0&&(a.totalBalance=l),c!==void 0&&(a.remainingBalance=c),i!==void 0&&(a.usedBalance=i),u!==void 0&&(a.usedDailyBalance=u),this.hasQuotaData(a)?a:null}},ho=class extends oe{async queryQuota(e,t,o){let r=bl(e.baseUrl),a=(await this.fetchJson(r,e,t,o))?.data;if(!a||typeof a!="object")return null;let l={},c=M(a.totalBalance),i=M(a.balance);return c!==void 0&&(l.totalBalance=c),i!==void 0&&(l.remainingBalance=i),c!==void 0&&i!==void 0&&(l.usedBalance=Math.max(0,c-i)),this.hasQuotaData(l)?l:null}},yo=class extends oe{async queryQuota(e,t,o){if(!e.apiKey)return null;let s={method:"GET",headers:{Accept:"application/json",Authorization:e.apiKey.trim()},signal:AbortSignal.timeout(t)};try{o&&(s.dispatcher=G(o));let a=await fetch("https://api.z.ai/api/monitor/usage/quota/limit",s);if(!a.ok)return null;let l=await a.json(),c=Array.isArray(l?.data?.limits)?l.data.limits:[],i=null,u=null,d=null;for(let g of c)g.type==="TOKENS_LIMIT"?g.unit===3?i=g:g.unit===6?u=g:i||(i=g):g.type==="TIME_LIMIT"&&(d=g);let m={};if(i){let g=M(i.currentValue),y=M(i.usage),p=M(i.remaining),f=M(i.percentage);g!==void 0?m.usedDailyBalance=g:f!==void 0&&(m.usedDailyBalance=f,m.limitDaily=100),y!==void 0?m.limitDaily=y:g!==void 0&&p!==void 0&&(m.limitDaily=g+p),i.nextResetTime&&(m.resetTime=new Date(i.nextResetTime).toISOString())}if(u){let g=M(u.currentValue),y=M(u.usage),p=M(u.remaining),f=M(u.percentage);g!==void 0?m.usedBalance=g:f!==void 0&&(m.usedBalance=f,m.totalBalance=100),y!==void 0?m.totalBalance=y:g!==void 0&&p!==void 0&&(m.totalBalance=g+p),u.nextResetTime&&!m.resetTime&&(m.resetTime=new Date(u.nextResetTime).toISOString())}if(d){if(m.usedDailyBalance===void 0){let g=M(d.currentValue);g!==void 0&&(m.usedDailyBalance=g)}if(m.limitDaily===void 0){let g=M(d.usage),y=M(d.currentValue),p=M(d.remaining);g!==void 0?m.limitDaily=g:y!==void 0&&p!==void 0&&(m.limitDaily=y+p)}d.nextResetTime&&!m.resetTime&&(m.resetTime=new Date(d.nextResetTime).toISOString())}return this.hasQuotaData(m)?m:null}catch{return null}}},_o=class extends oe{async queryQuota(e,t,o){if(!e.quotaToken)return null;let r={method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded","User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",Origin:"https://bailian.console.aliyun.com",Referer:"https://bailian.console.aliyun.com/cn-beijing",Cookie:e.quotaToken},signal:AbortSignal.timeout(t)},s=JSON.stringify({Api:"zeldaEasy.broadscope-bailian.codingPlan.queryCodingPlanInstanceInfoV2",V:"1.0",Data:{queryCodingPlanInstanceInfoRequest:{commodityCode:"sfm_codingplan_public_cn",onlyLatestOne:!0},cornerstoneParam:{feTraceId:`ccr-${Date.now()}`,feURL:"https://bailian.console.aliyun.com/cn-beijing",protocol:"V2",console:"ONE_CONSOLE",productCode:"p_efm",switchAgent:10736808,switchUserType:3,domain:"bailian.console.aliyun.com",consoleSite:"BAILIAN_ALIYUN",userNickName:"",userPrincipalName:"",xsp_lang:"zh-CN"}}}),a=new URLSearchParams({params:s,region:"cn-beijing"}).toString();try{o&&(r.dispatcher=G(o));let l=await fetch("https://bailian-cs.console.aliyun.com/data/api.json?action=BroadScopeAspnGateway&product=sfm_bailian&api=zeldaEasy.broadscope-bailian.codingPlan.queryCodingPlanInstanceInfoV2",{...r,body:a});if(!l.ok)return null;let i=(await l.json())?.data?.DataV2?.data?.data?.codingPlanInstanceInfos;if(!Array.isArray(i)||i.length===0)return null;let u=i[0]?.codingPlanQuotaInfo;if(!u)return null;let d={},m=M(u.per5HourUsedQuota),g=M(u.per5HourTotalQuota);m!==void 0&&(d.usedDailyBalance=m),g!==void 0&&(d.limitDaily=g);let y=M(u.perWeekUsedQuota),p=M(u.perWeekTotalQuota);return y!==void 0&&(d.usedBalance=y),p!==void 0&&(d.totalBalance=p),this.hasQuotaData(d)?d:null}catch{return null}}};rl=["per5HourPercentage","per5HourUsedPercentage","fiveHourPercentage"],sl=["per1WeekPercentage","perWeekPercentage","per1WeekUsedPercentage"],il=["per5HourResetTime","per5HourNextResetTime","fiveHourResetTime"],al=["per1WeekResetTime","per1WeekNextResetTime","perWeekResetTime"];ko=class extends oe{async queryQuota(e,t,o){let r=e.quotaToken?.trim();if(!r)return null;let s=e.quotaSecToken?.trim();if(s){try{let a=await this.queryOfficialEndpoint(r,s,t,o);if(a)return a}catch{}return this.queryLegacyEndpoint(r,t,o)}return this.queryLegacyEndpoint(r,t,o)}async queryOfficialEndpoint(e,t,o,r){let s="zeldaHttp.apikeyMgr./tokenplan/personal/api/v2/usage",a=vo(e,"cna")||"",l=JSON.stringify({Api:s,V:"1.0",Data:{cornerstoneParam:{feTraceId:`ccr-${Date.now()}`,feURL:"https://bailian.console.aliyun.com/cn-beijing/?tab=plan#/efm/subscription/token-plan/personal",protocol:"V2",console:"ONE_CONSOLE",productCode:"p_efm",switchAgent:10736808,switchUserType:3,domain:"bailian.console.aliyun.com",consoleSite:"BAILIAN_ALIYUN",userNickName:"",userPrincipalName:"",xsp_lang:"zh-CN","X-Anonymous-Id":a}}}),c=new URLSearchParams({params:l,region:"cn-beijing",sec_token:t}).toString(),i={method:"POST",headers:{Accept:"application/json","Content-Type":"application/x-www-form-urlencoded",Cookie:e,"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",Origin:"https://bailian.console.aliyun.com",Referer:"https://bailian.console.aliyun.com/cn-beijing/?tab=plan"},body:c,signal:AbortSignal.timeout(o)};try{r&&(i.dispatcher=G(r));let u=await fetch(`https://bailian-cs.console.aliyun.com/data/api.json?action=BroadScopeAspnGateway&product=sfm_bailian&api=${encodeURIComponent(s)}&_v=undefined`,i);if(!u.ok)return null;let d=await u.json();return qs(d)}catch{return null}}async queryLegacyEndpoint(e,t,o){let r="zeldaHttp.apikeyMgr./tokenplan/personal/api/v2/usage",s=JSON.stringify({Api:r,V:"1.0",Data:{cornerstoneParam:{feTraceId:`ccr-${Date.now()}`,feURL:"https://bailian.console.aliyun.com/",protocol:"V2",console:"ONE_CONSOLE",productCode:"p_efm",domain:"bailian.console.aliyun.com",consoleSite:"BAILIAN_ALIYUN",xsp_lang:"zh-CN"}}}),a=new URLSearchParams({params:s,region:"cn-beijing"}).toString(),l={method:"POST",headers:{Accept:"application/json","Content-Type":"application/x-www-form-urlencoded",Cookie:e,"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",Origin:"https://bailian.console.aliyun.com",Referer:"https://bailian.console.aliyun.com/"},body:a,signal:AbortSignal.timeout(t)};try{o&&(l.dispatcher=G(o));let c=await fetch(`https://cs-data.qianwenai.com/data/api.json?product=sfm_bailian&action=BroadScopeAspnGateway&api=${encodeURIComponent(r)}`,l);if(!c.ok)return null;let i=await c.json();return qs(i)}catch{return null}}},bo=class extends oe{async queryQuota(e,t,o){if(!e.quotaToken)return null;let s={method:"GET",headers:{Accept:"application/json","User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",Origin:"https://maas.xfyun.cn",Referer:"https://maas.xfyun.cn/packageSubscription",Authorization:(vo(e.quotaToken,"atp-auth-token")||vo(e.quotaToken,"tenantToken")||e.quotaToken).trim(),Cookie:e.quotaToken},signal:AbortSignal.timeout(t)};try{o&&(s.dispatcher=G(o));let a=await fetch("https://maas.xfyun.cn/api/v1/gpt-finetune/coding-plan/list?page=1&size=10",s);if(!a.ok)return null;let l=await a.json();if(l?.succeed===!1||l?.failed===!0)return null;let c=xl(l,e.apiKey),i=c?.codingPlanUsageDTO||c?.usage||c;if(!i||typeof i!="object")return null;let u={},d=M(i.rp5hUsage),m=M(i.rp5hLimit);d!==void 0&&(u.usedDailyBalance=d),m!==void 0&&(u.limitDaily=m);let g=M(i.rpwUsage),y=M(i.rpwLimit);return g!==void 0&&(u.usedBalance=g),y!==void 0&&(u.totalBalance=y),u.remainingBalance===void 0&&y!==void 0&&g!==void 0&&(u.remainingBalance=Math.max(0,y-g)),this.hasQuotaData(u)?u:null}catch{return null}}},xo=class extends oe{async queryQuota(e,t,o){let r=e.quotaToken||e.apiKey;if(!r)return null;let s={method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${r.trim()}`},signal:AbortSignal.timeout(t)};try{o&&(s.dispatcher=G(o));let a=await fetch("https://api.kimi.com/coding/v1/usages",s);if(!a.ok)return null;let l=await a.json(),c={},i=Array.isArray(l?.limits)?l.limits:[];if(i.length>0&&i[0]?.detail){let d=i[0].detail,m=M(d.limit),g=M(d.remaining),y=d.resetTime;m!==void 0&&g!==void 0&&(c.usedDailyBalance=Math.max(0,m-g),c.limitDaily=m),y&&(c.resetTime=new Date(y).toISOString())}let u=l?.usage;if(u){let d=M(u.limit),m=M(u.remaining),g=M(u.used),y=u.resetTime;d!==void 0&&(c.totalBalance=d,g!==void 0?c.usedBalance=g:m!==void 0&&(c.usedBalance=Math.max(0,d-m),c.remainingBalance=m)),y&&(c.resetTime7d=new Date(y).toISOString(),c.resetTime||(c.resetTime=c.resetTime7d))}return this.hasQuotaData(c)?c:null}catch{return null}}},Co=class extends oe{async queryQuota(e,t,o){let r=e.quotaToken||e.apiKey;if(!r)return null;let s=wo(e.baseUrl)||"api.minimaxi.com",a=s.endsWith(".minimax.io")||s==="minimax.io"?"api.minimax.io":"api.minimaxi.com";try{let l=[`https://${a}/v1/token_plan/remains`,`https://${a}/v1/api/openplatform/coding_plan/remains`],c=null;for(let b of l)if(c=await this.fetchJson(b,e,t,o,r.trim()),c)break;if(!c)return null;if(c?.base_resp){let b=c.base_resp.status_code;if(b!==void 0&&b!==0)return null}let i=Array.isArray(c?.model_remains)?c.model_remains:[];if(i.length===0)return null;let u=i[0],d={},m=M(u.current_interval_total_count),g=M(u.current_interval_usage_count),y=M(u.current_interval_remaining_percent),p=M(u.end_time);m!==void 0&&g!==void 0&&m>0?(d.usedDailyBalance=Math.max(0,m-g),d.limitDaily=m):y!==void 0&&(d.limitDaily=100,d.usedDailyBalance=Math.max(0,100-y)),p&&(d.resetTime=new Date(p).toISOString());let f=M(u.current_weekly_total_count),_=M(u.current_weekly_usage_count),k=M(u.current_weekly_remaining_percent),h=M(u.weekly_end_time);return f!==void 0&&_!==void 0&&f>0?(d.usedBalance=Math.max(0,f-_),d.remainingBalance=_,d.totalBalance=f):k!==void 0&&(d.totalBalance=100,d.usedBalance=Math.max(0,100-k),d.remainingBalance=k),h&&!d.resetTime&&(d.resetTime=new Date(h).toISOString()),this.hasQuotaData(d)?d:null}catch{return null}}},dl=new mo,pl=new go,fl=new ho,ml=new yo,gl=new _o,hl=new ko,yl=new bo,_l=new xo,kl=new Co});function ti(n){return{[Cl]:n,[Tl]:Rt}}function Rl(n){return n===!0||n==="true"||n===1||n==="1"}function wl(n){let e=n.getFullYear(),t=String(n.getMonth()+1).padStart(2,"0"),o=String(n.getDate()).padStart(2,"0");return`${e}-${t}-${o}`}function Sl(n){try{let e=new URL(n),t=e.pathname;return t.endsWith("/v1/messages")?t=t.slice(0,-12):t.endsWith("/messages")?t=t.slice(0,-9):t.endsWith("/v1/chat/completions")?t=t.slice(0,-20):t.endsWith("/chat/completions")&&(t=t.slice(0,-17)),t.endsWith("/v1")||(t=t.endsWith("/")?`${t}v1`:`${t}/v1`),e.pathname=`${t}/models`,e.toString()}catch{return null}}function Pl(n){try{let e=new URL(n).hostname.toLowerCase();return e.includes("moonshot")||e.includes("kimi")}catch{return!1}}async function Po(n,e,t){let o=Sl(n.baseUrl);if(!o)return{success:!1,error:"Cannot derive models endpoint from baseUrl"};try{let r={method:"GET",headers:{Authorization:`Bearer ${n.apiKey}`},signal:AbortSignal.timeout(e)};t&&(r.dispatcher=G(t));let s=await fetch(o,r);if(s.headers&&Ge(n.name,n.baseUrl,s.headers),s.ok)return{success:!0,headers:s.headers};if(s.status===429)return{success:!1,error:`HTTP 429: ${(await s.text().catch(()=>"")).slice(0,100)||"Rate limited"}`,headers:s.headers};if(s.status>=400&&s.status<500)return{success:!0,headers:s.headers};let a=await s.text().catch(()=>"");return{success:!1,error:`HTTP ${s.status}: ${a.slice(0,100)}`,headers:s.headers}}catch(r){return{success:!1,error:r?.message||r?.toString()||"Unknown probe error"}}}async function Al(n,e,t,o){let r=n.wakeupModel||(Array.isArray(n.models)?n.models[0]:void 0);if(!r)return{success:!1,error:"No models configured for provider"};let s=n.baseUrl,a=n.baseUrl.includes("/messages")||r.includes("claude");try{let l={"Content-Type":"application/json",...ti("scheduled-wakeup")};a?(l["x-api-key"]=n.apiKey,l["anthropic-version"]="2023-06-01"):l.Authorization=`Bearer ${n.apiKey}`;let c={method:"POST",headers:l,body:JSON.stringify({model:r,messages:[{role:"user",content:"Wake up and acknowledge with a short greeting."}],max_tokens:10}),signal:AbortSignal.timeout(e)};t&&(c.dispatcher=G(t)),o?.info(`Sending scheduled wake-up call to provider ${n.name} using model ${r}...`);let i=await fetch(s,c);if(i.ok)return{success:!0};let u=await i.text().catch(()=>"");return{success:!1,error:`HTTP ${i.status}: ${u.slice(0,200)||"Unknown error"}`}}catch(l){return{success:!1,error:l?.message||l?.toString()||"Unknown wake-up error"}}}async function Ol(n,e,t,o,r){let s=n.baseUrl,a=n.baseUrl.includes("/messages")||e.includes("claude");try{let l={"Content-Type":"application/json",...ti("rate-limit-probe")};a?(l["x-api-key"]=n.apiKey,l["anthropic-version"]="2023-06-01"):l.Authorization=`Bearer ${n.apiKey}`;let c={method:"POST",headers:l,body:JSON.stringify({model:e,messages:[{role:"user",content:"Hello, please reply briefly."}],max_tokens:10}),signal:AbortSignal.timeout(t)};o&&(c.dispatcher=G(o)),r?.debug?.(`Sending independent ping to rate-limited model ${n.name} (${e})...`);let i=await fetch(s,c);if(i.ok)return{success:!0};let u=await i.text().catch(()=>"");return{success:!1,error:`HTTP ${i.status}: ${u.slice(0,200)||"Unknown error"}`}}catch(l){return{success:!1,error:l?.message||l?.toString()||"Unknown ping error"}}}function ni(n,e,t,o,r){return de||(de=new mn(n,e,t,o,r)),de}function Ne(n,e,t,o,r){let s=ni(n,e,t,o,r);return s.start(),s}function Ao(){de&&de.stop()}function gn(){de&&(de.stop(),de=null)}var Cl,Tl,vl,mn,de,hn=S(()=>{"use strict";ne();Re();So();Pe();Hn();te();Cl="x-claude-code-router-source",Tl="x-claude-code-router-version";vl={enabled:!0,quotaProbeIntervalMinutes:10,probeTimeoutMs:15e3,initialDelayMs:5e3,excludeProviders:[]};mn=class{config;quotaProbeTimer;healthProbeTimer;wakeupTimer;rateLimitProbeTimer;lastWakeupDate=new Map;getProviders;resolveProxyUrl;logger;getConfig;running=!1;constructor(e,t,o,r,s){this.config={...vl,...t},this.getProviders=e,this.resolveProxyUrl=o,this.logger=r,this.getConfig=s}start(){if(this.running)return;let e=this.isWakeupGloballyEnabled();!this.config.enabled&&!e||(this.running=!0,setTimeout(()=>{this.running&&(this.config.enabled&&(this.runQuotaProbe(),this.runHealthProbe(),this.runRateLimitProbe()),this.runScheduledWakeup())},this.config.initialDelayMs),this.config.enabled&&(this.quotaProbeTimer=setInterval(()=>this.runQuotaProbe(),this.config.quotaProbeIntervalMinutes*60*1e3),this.healthProbeTimer=setInterval(()=>this.runHealthProbe(),300*1e3),this.rateLimitProbeTimer=setInterval(()=>this.runRateLimitProbe(),120*1e3)),this.wakeupTimer=setInterval(()=>this.runScheduledWakeup(),60*1e3),this.logger?.info("Active probe service started"))}stop(){this.running=!1,this.quotaProbeTimer&&(clearInterval(this.quotaProbeTimer),this.quotaProbeTimer=void 0),this.healthProbeTimer&&(clearInterval(this.healthProbeTimer),this.healthProbeTimer=void 0),this.rateLimitProbeTimer&&(clearInterval(this.rateLimitProbeTimer),this.rateLimitProbeTimer=void 0),this.wakeupTimer&&(clearInterval(this.wakeupTimer),this.wakeupTimer=void 0),this.logger?.info("Active probe service stopped")}async runQuotaProbe(){let e=this.getProviders().filter(s=>s?.name&&s.enabled!==!1&&!this.config.excludeProviders.includes(s.name)),t=U();if(e.length===0)return;let o=[];for(let s of e){let a=Ro(s.baseUrl),l=Array.isArray(s.models)?s.models:[],c=this.resolveProxyUrl?.(s);if(!a){let i;try{i=new URL(s.baseUrl).hostname}catch{i=void 0}this.logger?.debug?.(`No quota adapter for provider ${s.name}`+(i?` (host: ${i})`:"")+" \u2014 skipping quota probe")}a&&o.push({provider:s.name,models:l,type:"quota-adapter",promise:a.queryQuota(s,this.config.probeTimeoutMs,c).then(i=>{if(i){no(s.name,i),this.logger?.debug?.(`Stored quota probe result for ${s.name}`);let u=i.limitDaily!==void 0&&i.usedDailyBalance!==void 0&&i.usedDailyBalance>=i.limitDaily,d=i.totalBalance!==void 0&&i.usedBalance!==void 0&&i.usedBalance>=i.totalBalance;if(u||d){let m=u?`Quota exhausted: 5h limit reached (${i.usedDailyBalance}/${i.limitDaily})`:`Quota exhausted: 7d balance depleted (${i.usedBalance}/${i.totalBalance})`;for(let g of l){if(t.getState(s.name,g)?.rateLimitUntil){this.logger?.debug?.(`Skip forceOpen for ${s.name} (${g}): already rate-limited with active cooldown`);continue}t.forceOpen(s.name,g,m)}this.logger?.warn?.(`${m} for ${s.name}, marked as unhealthy`)}else for(let m of l){let g=t.getState(s.name,m);g&&g.status==="open"&&g.lastError?.includes("Quota exhausted")&&(t.recover(s.name,m),this.logger?.info?.(`Quota recovered for ${s.name} (${m}), marked as healthy`))}}})}),Pl(s.baseUrl)&&o.push({provider:s.name,models:l,type:"rate-limit-headers",promise:Po(s,this.config.probeTimeoutMs,c).then(()=>{})})}if(o.length===0)return;this.logger?.debug?.(`Running quota probe with ${o.length} tasks for ${e.length} providers`);let r=await Promise.allSettled(o.map(s=>s.promise));for(let s=0;s<o.length;s++){let a=r[s];if(a.status==="rejected"){let l=o[s];this.logger?.warn?.(`Quota probe failed for ${l.provider} (${l.type}): ${a.reason}`)}}}async runHealthProbe(){let e=U(),t=this.getProviders().filter(r=>r?.name&&r.enabled!==!1&&!this.config.excludeProviders.includes(r.name));if(t.length===0)return;this.logger?.debug?.(`Running health probe for ${t.length} providers`);let o=await Promise.allSettled(t.map(r=>Po(r,this.config.probeTimeoutMs,this.resolveProxyUrl?.(r))));for(let r=0;r<t.length;r++){let s=t[r],a=o[r],l=Array.isArray(s.models)?s.models:[];if(a.status==="fulfilled"){let c=a.value;if(c.success){let i=0;for(let u of l){let d=e.getState(s.name,u);if(d&&d.status==="open"){let m=d.lastError?.includes("Quota exhausted"),g=d.rateLimitUntil||d.lastError&&(d.lastError.includes("429")||d.lastError.toLowerCase().includes("rate limit")||d.lastError.toLowerCase().includes("rate_limit")||d.lastError.toLowerCase().includes("too many requests")||d.lastError.toLowerCase().includes("\u9650\u6D41"));if(m){this.logger?.debug?.(`Skipping health probe recovery for ${s.name} (${u}) because quota is exhausted`);continue}if(g||d.rateLimitUntil){this.logger?.debug?.(`Skipping health probe recovery for rate-limited ${s.name} (${u})`);continue}}e.recordSuccess(s.name,u),i++}i>0&&this.logger?.info?.(`Health probe succeeded for ${s.name}`)}else{for(let i of l)e.recordFailure(s.name,i,c.error);this.logger?.warn?.(`Health probe failed for ${s.name}: ${c.error}`)}}else{for(let c of l)e.recordFailure(s.name,c,a.reason?.message||"Probe error");this.logger?.warn?.(`Health probe error for ${s.name}: ${a.reason}`)}}}async runRateLimitProbe(){let e=U(),t=e.getRateLimitedModels();if(t.length===0)return;let o=this.getProviders(),r=this.config.probeTimeoutMs;this.logger?.debug?.(`Running rate-limit recovery probe for ${t.length} model(s)`);for(let s of t){let[a,...l]=s.split(","),c=l.join(",");if(!a||!c)continue;let i=e.getState(a,c);if(!i||!i.rateLimitUntil)continue;if(Date.now()>=i.rateLimitUntil){e.recover(a,c),this.logger?.info?.(`Rate-limit cooldown expired, auto-recovered ${s}`);continue}let u=o.find(d=>d?.name===a&&d.enabled!==!1);if(!u){this.logger?.warn?.(`Provider ${a} not found or disabled for rate-limit probe`);continue}try{let d=await Ol(u,c,r,this.resolveProxyUrl?.(u),this.logger);if(d.success)this.logger?.info?.(`Rate-limit probe succeeded for ${s}, recovering model`),e.recover(a,c);else if(d.error&&(d.error.includes("429")||d.error.toLowerCase().includes("rate limit")||d.error.toLowerCase().includes("rate_limit")||d.error.toLowerCase().includes("too many requests")||d.error.toLowerCase().includes("\u9650\u6D41"))){let m=Date.now();i.rateLimitUntil&&i.rateLimitUntil>m?i.rateLimitUntil+=120*1e3:i.rateLimitUntil=m+120*1e3,this.logger?.debug?.(`Rate-limit probe for ${s} confirmed still limited, extending cooldown`)}else this.logger?.debug?.(`Rate-limit probe for ${s} returned non-rate-limit error: ${d.error?.slice(0,100)}`)}catch(d){this.logger?.warn?.(`Rate-limit probe exception for ${s}: ${d?.message||d}`)}}}async runScheduledWakeup(){if(!this.isWakeupGloballyEnabled())return;let e=this.getProviders().filter(l=>l?.name&&l.enabled!==!1&&l.wakeupEnabled===!0);if(e.length===0)return;let t=new Date,o=t.getHours(),r=t.getMinutes(),s=wl(t),a=this.getConfig&&this.getConfig("WAKEUP_TIME")||"06:00";for(let l of e){let c=l.wakeupTime||a,[i,u]=c.split(":"),d=parseInt(i,10),m=parseInt(u,10);if(isNaN(d)||isNaN(m))continue;let g=o>d||o===d&&r>=m,y=(d*60+m)*6e4-(o*60+r)*6e4,p=y>0&&y<=300*1e3;(g||p)&&!this.hasWakeupFiredToday(l.name,s)&&(this.logger?.info?.(`Scheduled wake-up triggered for provider ${l.name} at ${c}`),Al(l,3e4,this.resolveProxyUrl?.(l),this.logger).then(f=>{f.success?this.logger?.info?.(`Successfully woke up provider ${l.name}`):this.logger?.error?.(`Failed to wake up provider ${l.name}: ${f.error}`)}).catch(f=>{this.logger?.error?.(`Error in wake-up task for ${l.name}: ${f}`)}))}}isWakeupGloballyEnabled(){return this.getConfig?Rl(this.getConfig("WAKEUP_ENABLED")):!1}hasWakeupFiredToday(e,t){return this.lastWakeupDate.get(e)===t?!0:(this.lastWakeupDate.set(e,t),!1)}async probeProviderManually(e){let o=this.getProviders().find(a=>a.name===e);if(!o)return this.logger?.warn?.(`Provider ${e} not found for manual probe`),!1;if(o.enabled===!1)return this.logger?.warn?.(`Provider ${e} is disabled, skipping manual probe`),!1;let r=await Po(o,this.config.probeTimeoutMs,this.resolveProxyUrl?.(o)),s=Array.isArray(o.models)?o.models:[];if(r.success)for(let a of s)U().recordSuccess(o.name,a);else for(let a of s)U().recordFailure(o.name,a,r.error);return r.success}},de=null});var oi=S(()=>{"use strict"});var Oo,ot,ri=S(()=>{"use strict";Oo=class{plugins=new Map;pluginInstances=new Map;registerPlugin(e,t={}){this.pluginInstances.set(e.name,e),this.plugins.set(e.name,{name:e.name,enabled:t.enabled!==!1,options:t})}async enablePlugin(e,t){let o=this.plugins.get(e),r=this.pluginInstances.get(e);if(!o||!r)throw new Error(`Plugin ${e} not found`);o.enabled&&await t.register(r.register,o.options)}async enablePlugins(e){for(let[t,o]of this.plugins)if(o.enabled)try{await this.enablePlugin(t,e)}catch(r){let s=r instanceof Error?r.message:String(r);e.log?.error(`Failed to enable plugin ${t}: ${s}`)}}getPlugins(){return Array.from(this.plugins.values())}getPlugin(e){return this.pluginInstances.get(e)}hasPlugin(e){return this.pluginInstances.has(e)}isPluginEnabled(e){return this.plugins.get(e)?.enabled||!1}setPluginEnabled(e,t){let o=this.plugins.get(e);o&&(o.enabled=t)}removePlugin(e){this.plugins.delete(e),this.pluginInstances.delete(e)}clear(){this.plugins.clear(),this.pluginInstances.clear()}},ot=new Oo});var se,Eo=S(()=>{"use strict";se=class extends TransformStream{buffer="";currentEvent={};constructor(){super({transform:(e,t)=>{this.buffer+=e;let o=this.buffer.split(`
|
|
304
|
+
`);this.buffer=o.pop()||"";for(let r of o){let s=this.processLine(r);s&&t.enqueue(s)}},flush:e=>{if(this.buffer.trim()){let t=[];this.processLine(this.buffer.trim(),t),t.forEach(o=>e.enqueue(o))}Object.keys(this.currentEvent).length>0&&e.enqueue(this.currentEvent)}})}processLine(e,t){if(!e.trim()){if(Object.keys(this.currentEvent).length>0){let o={...this.currentEvent};return this.currentEvent={},t?(t.push(o),null):o}return null}if(e.startsWith("event:"))this.currentEvent.event=e.slice(6).trim();else if(e.startsWith("data:")){let o=e.slice(5).trim();if(o==="[DONE]")this.currentEvent.data={type:"done"};else try{this.currentEvent.data=JSON.parse(o)}catch{this.currentEvent.data={raw:o,error:"JSON parse failed"}}}else e.startsWith("id:")?this.currentEvent.id=e.slice(3).trim():e.startsWith("retry:")&&(this.currentEvent.retry=parseInt(e.slice(6).trim()));return null}}});var Le,Io=S(()=>{"use strict";Le=class extends TransformStream{constructor(){super({transform:(e,t)=>{let o="";e.event&&(o+=`event: ${e.event}
|
|
305
305
|
`),e.id&&(o+=`id: ${e.id}
|
|
306
306
|
`),e.retry&&(o+=`retry: ${e.retry}
|
|
307
307
|
`),e.data&&(e.data.type==="done"?o+=`data: [DONE]
|
|
308
308
|
`:o+=`data: ${JSON.stringify(e.data)}
|
|
309
309
|
`),o+=`
|
|
310
|
-
`,t.enqueue(o)}})}}});var
|
|
310
|
+
`,t.enqueue(o)}})}}});var yn,Mo=S(()=>{"use strict";yn=(n,e)=>{let t=n.getReader();return new ReadableStream({async start(o){try{for(;;){let{done:r,value:s}=await t.read();if(r){o.close();break}let a=await e(s,o);a!==void 0&&o.enqueue(a)}}catch(r){o.error(r)}finally{t.releaseLock()}}})}});var $o=S(()=>{"use strict";Eo();Io();Mo()});var si=S(()=>{"use strict"});var rt,No=S(()=>{"use strict";rt=class{type="console";config;colors={reset:"\x1B[0m",bright:"\x1B[1m",dim:"\x1B[2m",red:"\x1B[31m",green:"\x1B[32m",yellow:"\x1B[33m",blue:"\x1B[34m",magenta:"\x1B[35m",cyan:"\x1B[36m",white:"\x1B[37m"};constructor(e={}){this.config={colors:!0,level:"log",...e}}formatData(e,t){let{format:o="text",timestamp:r=!0,prefix:s,metadata:a}=t||{},l="";if(r){let c=new Date().toISOString();l+=this.config.colors?`${this.colors.cyan}[${c}]${this.colors.reset} `:`[${c}] `}switch(s&&(l+=this.config.colors?`${this.colors.bright}${s}${this.colors.reset} `:`${s} `),o){case"json":l+=JSON.stringify(e,null,2);break;case"markdown":typeof e=="object"?l+=this.toMarkdown(e):l+=String(e);break;case"text":default:typeof e=="object"?l+=JSON.stringify(e,null,2):l+=String(e);break}return a&&Object.keys(a).length>0&&(l+=`
|
|
311
311
|
`+(this.config.colors?`${this.colors.dim}`:""),l+="Metadata: "+JSON.stringify(a,null,2),this.config.colors&&(l+=this.colors.reset)),l}toMarkdown(e,t=0){let o=" ".repeat(t);return Array.isArray(e)?e.map(r=>typeof r=="object"?`${o}-
|
|
312
312
|
${this.toMarkdown(r,t+1)}`:`${o}- ${r}`).join(`
|
|
313
313
|
`):typeof e=="object"&&e!==null?Object.entries(e).map(([r,s])=>typeof s=="object"&&s!==null?`${o}${r}:
|
|
314
314
|
${this.toMarkdown(s,t+1)}`:`${o}${r}: ${s}`).join(`
|
|
315
|
-
`):`${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 it,No=S(()=>{"use strict";it=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:a}=t||{},l={data:e};return r&&(l.timestamp=new Date().toISOString()),s&&(l.prefix=s),a&&Object.keys(a).length>0&&(l.metadata=a),l}async sendRequest(e,t,o,r,s){let a=new AbortController,l=setTimeout(()=>a.abort(),s);try{let c=await fetch(e,{method:t,headers:o,body:JSON.stringify(r),signal:a.signal});if(clearTimeout(l),!c.ok)throw new Error(`HTTP ${c.status}: ${c.statusText}`);return c}catch(c){throw clearTimeout(l),c}}delay(e){return new Promise(t=>setTimeout(t,e))}async sendWithRetry(e,t,o,r,s,a){let l=null;for(let c=1;c<=a.maxAttempts;c++)try{return await this.sendRequest(e,t,o,r,s)}catch(i){if(l=i,c===a.maxAttempts)break;let u=a.backoffMs*Math.pow(2,c-1);console.warn(`[WebhookOutputHandler] Request failed (attempt ${c}/${a.maxAttempts}), retrying in ${u}ms...`,i.message),await this.delay(u)}throw l}async output(e,t={}){let o=t.timeout||this.defaultTimeout;try{let r=this.buildHeaders(),s=this.buildBody(e,t),a=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{writeFileSync as Ml,existsSync as $l,mkdirSync as Nl}from"fs";import{join as ci}from"path";import{tmpdir as Ll}from"os";var at,Lo=S(()=>{"use strict";at=class{type="temp-file";config;baseDir;constructor(e={}){this.config={subdirectory:"claude-code-router",extension:"json",includeTimestamp:!1,prefix:"session",...e};let t=Ll();this.baseDir=ci(t,this.config.subdirectory),this.ensureDir()}ensureDir(){try{$l(this.baseDir)||Nl(this.baseDir,{recursive:!0})}catch{}}getFilePath(e){let t=this.config.prefix||"session",o=this.config.extension?`.${this.config.extension}`:"",r;if(this.config.includeTimestamp){let s=Date.now();r=`${t}-${e}-${s}${o}`}else r=`${t}-${e}${o}`;return ci(this.baseDir,r)}async output(e,t={}){try{let o=t.metadata?.sessionId;if(!o)return!1;let r={...e,timestamp:Date.now(),sessionId:o},s=this.getFilePath(o);return Ml(s,JSON.stringify(r,null,2),"utf-8"),!0}catch{return!1}}getBaseDir(){return this.baseDir}}});var Fo,Fe,li=S(()=>{"use strict";$o();No();Lo();Fo=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 st(e.config);case"webhook":return new it(e.config);case"temp-file":return new at(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([a,l])=>{try{await l.output(e,o)?r.success.push(a):r.failed.push(a)}catch(c){console.error(`[OutputManager] Handler ${a} failed:`,c),r.failed.push(a)}});return await Promise.all(s),r}async outputTo(e,t,o){let r={...this.defaultOptions,...o},s={success:[],failed:[]},a=e.map(async l=>{let c=this.handlers.get(l);if(!c){console.warn(`[OutputManager] Handler ${l} not found`),s.failed.push(l);return}try{await c.output(t,r)?s.success.push(l):s.failed.push(l)}catch(i){console.error(`[OutputManager] Handler ${l} failed:`,i),s.failed.push(l)}});return await Promise.all(a),s}async outputToType(e,t,o){let r=Array.from(this.handlers.entries()).filter(([s,a])=>a.type===e).map(([s])=>s);return this.outputTo(r,t,o)}},Fe=new Fo});var Uo=S(()=>{"use strict";ai();$o();No();Lo();li()});import Fl from"fastify-plugin";function ui(n,e,t=0){if(n<=0)return 0;let o=Math.max((e-t)/1e3,Ul);return Math.round(n/o)}function lt(n){let e=(n.match(/[\u4e00-\u9fa5]/g)||[]).length,t=n.length-e;return Math.ceil(e/1.5+t/4)}async function di(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()},a={prefix:r,metadata:{sessionId:n.sessionId},...t};for(let l of e)try{await Fe.outputToType(l,s,a)}catch(c){console.error(`[TokenSpeedPlugin] Failed to output to ${l}:`,c)}}var ct,Do,Ul,yn,pi=S(()=>{"use strict";Mo();Uo();Xe();ct=new Map,Do=new Map,Ul=1,yn={name:"token-speed",version:"1.0.0",description:"Statistics for streaming response token generation speed",register:Fl(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)Fe.registerHandlers(t.outputHandlers);else{let a=[];for(let l of o)l==="console"?a.push({type:"console",enabled:!0,config:{colors:!0,level:"log"}}):l==="temp-file"?a.push({type:"temp-file",enabled:!0,config:{subdirectory:"claude-code-router",extension:"json",includeTimestamp:!0,prefix:"session"}}):l==="webhook"&&console.warn("[TokenSpeedPlugin] Webhook reporter requires explicit configuration in outputHandlers");a.length>0&&Fe.registerHandlers(a)}t.outputOptions&&Fe.setDefaultOptions(t.outputOptions);let r=async a=>{let l=n.tokenizerService;if(!l)return n.log?.warn("TokenizerService not available"),null;if(!a.provider||!a.model)return null;let c=a.provider,i=a.model,u=`${c}:${i}`;if(Do.has(u))return Do.get(u);let d=l.getTokenizerConfigForModel(c,i);if(!d)return n.log?.debug(`No tokenizer config for ${c}:${i}, using fallback`),null;try{let m=await l.getTokenizer(d,c);return Do.set(u,m),n.log?.info(`Created tokenizer for ${c}:${i} - ${m.name}`),m}catch(m){return n.log?.warn(`Failed to create tokenizer for ${c}:${i}: ${m.message}`),null}},s=a=>{let l=new URL(`http://127.0.0.1${a}`).pathname;return l.endsWith("/v1/messages")||l.endsWith("/v1/responses")};n.addHook("onRequest",async a=>{s(a.url)&&(a.requestStartTime=performance.now())}),n.addHook("onSend",async(a,l,c)=>{let i=a.requestStartTime;if(!i)return;let u=a.id||Date.now().toString(),d=a.usageSessionId;if(!d)try{d=Ke(a.body?.metadata?.user_id)}catch{}if(!d){let f=a.headers?.["x-request-id"],_=Array.isArray(f)?f[0]:f;d=(typeof _=="string"?_:void 0)||u}let m=await r(a);if(c instanceof ReadableStream){ct.set(u,{requestId:u,sessionId:d,startTime:i,lastTokenTime:i,tokenCount:0,tokensPerSecond:0,stream:!0});let[f,_]=c.tee(),k=async()=>{let h=null,b=async x=>{let v=ct.get(u);if(!v)return;let C=v.firstTokenTime?v.firstTokenTime-v.startTime:0,T=(x?v.lastTokenTime:performance.now())-v.startTime;v.tokensPerSecond=ui(v.tokenCount,T,C),await di(v,o,t.outputOptions,x).catch(A=>{n.log?.warn(`Failed to output streaming stats: ${A.message}`)})};try{let v=_.pipeThrough(new TextDecoderStream).pipeThrough(new oe).getReader();for(h=setInterval(async()=>{ct.get(u)&&await b(!1)},1e3);;){let{done:C,value:R}=await v.read();if(C)break;let T=R,A=ct.get(u);if(!A)continue;let w=performance.now(),O=T.event||T.data?.type,P=T.event==="content_block_start"||T.event==="content_block_delta"||T.event==="text_block"||T.event==="content_block"||O==="response.output_text.delta"||O==="response.function_call_arguments.delta"||O==="response.reasoning_summary_text.delta";!A.firstTokenTime&&P&&(A.firstTokenTime=w,A.timeToFirstToken=Math.round(w-A.startTime));let E="";if(T.event==="content_block_delta"&&T.data?.delta){let N=T.data.delta.type;N==="text_delta"?E=T.data.delta.text||"":N==="input_json_delta"?E=T.data.delta.partial_json||"":N==="thinking_delta"&&(E=T.data.delta.thinking||"")}if((O==="response.output_text.delta"||O==="response.function_call_arguments.delta"||O==="response.reasoning_summary_text.delta")&&(E=typeof T.data?.delta=="string"?T.data.delta:""),E){let N=m&&m.encodeText?m.encodeText(E).length:lt(E);A.tokenCount+=N,A.lastTokenTime=w}(T.event==="message_stop"||O==="response.completed"||O==="response.failed")&&(h&&(clearInterval(h),h=null),await b(!0),ct.delete(u))}}catch(x){h&&clearInterval(h),x.name!=="AbortError"&&x.code!=="ERR_STREAM_PREMATURE_CLOSE"&&n.log?.warn(`Error processing token stats: ${x.message}`)}};return a.tokenSpeedCapturePromise=k().catch(h=>{console.log(h),n.log?.warn(`Background stats processing failed: ${h.message}`)}),f}let g=performance.now(),y=0,p=!1;if(c&&typeof c=="string")try{let f=JSON.parse(c);if(typeof f.usage?.output_tokens=="number")y=f.usage.output_tokens,p=!0;else{let _=f.content??f.message?.content;if(_!==void 0)if(p=!0,m)Array.isArray(_)?y=_.reduce((k,h)=>{if(h.type==="text"){let b=h.text||"";return k+(m.encodeText?m.encodeText(b).length:lt(b))}return k},0):typeof _=="string"&&(y=m.encodeText?m.encodeText(_).length:lt(_));else{let k=Array.isArray(_)?_.map(h=>h.text).join(""):typeof _=="string"?_:"";y=lt(k)}}}catch{}if(p){let f=Math.round(g-i),_=g-i,k={requestId:u,sessionId:d,startTime:i,lastTokenTime:g,tokenCount:y,tokensPerSecond:ui(y,_),timeToFirstToken:f,stream:!1};await di(k,o,t.outputOptions,!0)}return c})})}});var jo=S(()=>{"use strict";si();ii();pi();Uo()});import le from"node:fs/promises";import fi from"json5";import _n from"node:path";import{CONFIG_FILE as re,HOME_DIR as zo,PLUGINS_DIR as Dl}from"@wengine-ai/claude-code-router-shared";var Ho,kn,bn,Jo,j,xn,q,Bo,ut=S(()=>{"use strict";Ho=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(Ho);if(n!==null&&typeof n=="object"){let e={};for(let[t,o]of Object.entries(n))e[t]=Ho(o);return e}return n},kn=async n=>{try{await le.access(n)}catch{await le.mkdir(n,{recursive:!0})}},bn=async()=>{await kn(zo),await kn(Dl),await kn(_n.join(zo,"logs"))},Jo=async()=>{let n=await le.readFile(re,"utf-8");return fi.parse(n)},j=async()=>{try{let n=await le.readFile(re,"utf-8");try{let e=fi.parse(n);return Ho(e)}catch(e){console.error(`Failed to parse config file at ${re}`),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 bn();let e=await xn();e&&console.log(`Backed up existing configuration file to ${e}`);let t={PORT:3456,Providers:[],Router:{}};return await q(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 ${re}`),console.error("Error details:",n.message),process.exit(1)}},xn=async()=>{try{if(await le.access(re).then(()=>!0).catch(()=>!1)){let n=new Date().toISOString().replace(/[:.]/g,"-"),e=`${re}.${n}.bak`;await le.copyFile(re,e);try{let t=_n.dirname(re),o=_n.basename(re),s=(await le.readdir(t)).filter(a=>a.startsWith(o)&&a.endsWith(".bak")).sort().reverse();if(s.length>3)for(let a=3;a<s.length;a++){let l=_n.join(t,s[a]);await le.unlink(l)}}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},q=async n=>{await kn(zo);let e=`${JSON.stringify(n,null,2)}`;await le.writeFile(re,e)},Bo=async()=>{let n=await j();return Object.assign(process.env,n),n}});function jl(n){return n?.cache_read_input_tokens??n?.input_tokens_details?.cached_tokens??n?.prompt_tokens_details?.cached_tokens??0}function zl(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 Ue(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:jl(n),cache_creation_input_tokens:zl(n)}}function Cn(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 Wo=S(()=>{"use strict"});function Tn(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(Go(r,s))}return}if(Array.isArray(n)){for(let o of n)Tn(o,e,t);return}if(typeof n=="object")for(let o of Object.values(n))Tn(o,e,t)}}function mi(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 a=Array.isArray(r?.models)?r.models:[];for(let l of a)l&&o.add(Go(s,l))}return Tn(n?.Router,t,o),Tn(n?.fallback,t,o),o}function dt(n,e){try{let t=U();if(!t?.getAllStates||!t?.recover)return 0;let o=mi(n),r=0;for(let s of t.getAllStates()||[]){let a=s?.provider,l=s?.model;!a||!l||o.has(Go(a,l))||(t.recover(a,l),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 vn(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 Hl,Go,Rn=S(()=>{"use strict";ee();Hl="\0",Go=(n,e)=>`${n}${Hl}${e}`});function Jl(n){return/\[1m\]/i.test(n)?1e6:2e5}function Bl(n){let e=n.toLowerCase();return e.includes("haiku")||e.includes("mini")?8192:32e3}function Wl(n,e=n){let t=Jl(n),o=Bl(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,Wl(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 Vo=S(()=>{"use strict"});function Gl(n){let e=n.ip||n.connection?.remoteAddress||"";return e==="127.0.0.1"||e==="::1"||e==="::ffff:127.0.0.1"}var Sn,Qo=S(()=>{"use strict";Sn=n=>async(e,t,o)=>{if(["/","/health"].includes(e.url)||e.url.startsWith("/ui")||Gl(e))return o();let s=n.Providers||n.providers||[];if(!s||s.length===0)return o();let a=n.APIKEY;if(!a){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 l=e.headers.authorization||e.headers["x-api-key"],c=Array.isArray(l)?l[0]:l||"";if(!c){t.log.warn({url:e.url,headers:Object.keys(e.headers)},"[AUTH] No auth header"),t.status(401).send("APIKEY is missing");return}let i="";if(c.startsWith("Bearer")?i=c.split(" ")[1]:i=c,i!==a){t.log.warn({url:e.url,gotPrefix:i.slice(0,10),gotSuffix:i.slice(-6),gotLen:i.length,expectedPrefix:a.slice(0,6),expectedSuffix:a.slice(-6),expectedLen:a.length},"[AUTH] Key mismatch"),t.status(401).send("Invalid API key");return}o()}});var vi={};Fn(vi,{append:()=>gt,clear:()=>er,close:()=>uu,getOldestRecordTimestamp:()=>du,query:()=>Zo,querySummary:()=>ht,readTokenSpeedStats:()=>tr});import{existsSync as Yo,mkdirSync as Vl,readFileSync as Xo,readdirSync as Ql}from"fs";import{join as ze}from"path";import{homedir as Kl,tmpdir as Xl}from"os";import Yl from"better-sqlite3";function nu(){Yo(Pn)||Vl(Pn,{recursive:!0})}function mt(){if(fe)return fe;nu();let n=new Yl(ql);n.pragma("journal_mode = WAL"),n.pragma("synchronous = NORMAL"),n.pragma("busy_timeout = 5000");let e=n.pragma("user_version",{simple:!0})||0;return e<1&&(ou(n),n.pragma("user_version = 1")),e<2&&(n.prepare("PRAGMA table_info(usage_records)").all().some(o=>o.name==="upstream_model")||n.exec("ALTER TABLE usage_records ADD COLUMN upstream_model TEXT"),n.pragma("user_version = 2")),su(n),bi(n,!0),qo=n.prepare(`
|
|
315
|
+
`):`${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 st,Lo=S(()=>{"use strict";st=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:a}=t||{},l={data:e};return r&&(l.timestamp=new Date().toISOString()),s&&(l.prefix=s),a&&Object.keys(a).length>0&&(l.metadata=a),l}async sendRequest(e,t,o,r,s){let a=new AbortController,l=setTimeout(()=>a.abort(),s);try{let c=await fetch(e,{method:t,headers:o,body:JSON.stringify(r),signal:a.signal});if(clearTimeout(l),!c.ok)throw new Error(`HTTP ${c.status}: ${c.statusText}`);return c}catch(c){throw clearTimeout(l),c}}delay(e){return new Promise(t=>setTimeout(t,e))}async sendWithRetry(e,t,o,r,s,a){let l=null;for(let c=1;c<=a.maxAttempts;c++)try{return await this.sendRequest(e,t,o,r,s)}catch(i){if(l=i,c===a.maxAttempts)break;let u=a.backoffMs*Math.pow(2,c-1);console.warn(`[WebhookOutputHandler] Request failed (attempt ${c}/${a.maxAttempts}), retrying in ${u}ms...`,i.message),await this.delay(u)}throw l}async output(e,t={}){let o=t.timeout||this.defaultTimeout;try{let r=this.buildHeaders(),s=this.buildBody(e,t),a=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{writeFileSync as El,existsSync as Il,mkdirSync as Ml}from"fs";import{join as ii}from"path";import{tmpdir as $l}from"os";var it,Fo=S(()=>{"use strict";it=class{type="temp-file";config;baseDir;constructor(e={}){this.config={subdirectory:"claude-code-router",extension:"json",includeTimestamp:!1,prefix:"session",...e};let t=$l();this.baseDir=ii(t,this.config.subdirectory),this.ensureDir()}ensureDir(){try{Il(this.baseDir)||Ml(this.baseDir,{recursive:!0})}catch{}}getFilePath(e){let t=this.config.prefix||"session",o=this.config.extension?`.${this.config.extension}`:"",r;if(this.config.includeTimestamp){let s=Date.now();r=`${t}-${e}-${s}${o}`}else r=`${t}-${e}${o}`;return ii(this.baseDir,r)}async output(e,t={}){try{let o=t.metadata?.sessionId;if(!o)return!1;let r={...e,timestamp:Date.now(),sessionId:o},s=this.getFilePath(o);return El(s,JSON.stringify(r,null,2),"utf-8"),!0}catch{return!1}}getBaseDir(){return this.baseDir}}});var Uo,Fe,ai=S(()=>{"use strict";No();Lo();Fo();Uo=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 rt(e.config);case"webhook":return new st(e.config);case"temp-file":return new it(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([a,l])=>{try{await l.output(e,o)?r.success.push(a):r.failed.push(a)}catch(c){console.error(`[OutputManager] Handler ${a} failed:`,c),r.failed.push(a)}});return await Promise.all(s),r}async outputTo(e,t,o){let r={...this.defaultOptions,...o},s={success:[],failed:[]},a=e.map(async l=>{let c=this.handlers.get(l);if(!c){console.warn(`[OutputManager] Handler ${l} not found`),s.failed.push(l);return}try{await c.output(t,r)?s.success.push(l):s.failed.push(l)}catch(i){console.error(`[OutputManager] Handler ${l} failed:`,i),s.failed.push(l)}});return await Promise.all(a),s}async outputToType(e,t,o){let r=Array.from(this.handlers.entries()).filter(([s,a])=>a.type===e).map(([s])=>s);return this.outputTo(r,t,o)}},Fe=new Uo});var Do=S(()=>{"use strict";si();No();Lo();Fo();ai()});import Nl from"fastify-plugin";function ci(n,e,t=0){if(n<=0)return 0;let o=Math.max((e-t)/1e3,Ll);return Math.round(n/o)}function ct(n){let e=(n.match(/[\u4e00-\u9fa5]/g)||[]).length,t=n.length-e;return Math.ceil(e/1.5+t/4)}async function li(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()},a={prefix:r,metadata:{sessionId:n.sessionId},...t};for(let l of e)try{await Fe.outputToType(l,s,a)}catch(c){console.error(`[TokenSpeedPlugin] Failed to output to ${l}:`,c)}}var at,jo,Ll,_n,ui=S(()=>{"use strict";$o();Do();Xe();at=new Map,jo=new Map,Ll=1,_n={name:"token-speed",version:"1.0.0",description:"Statistics for streaming response token generation speed",register:Nl(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)Fe.registerHandlers(t.outputHandlers);else{let a=[];for(let l of o)l==="console"?a.push({type:"console",enabled:!0,config:{colors:!0,level:"log"}}):l==="temp-file"?a.push({type:"temp-file",enabled:!0,config:{subdirectory:"claude-code-router",extension:"json",includeTimestamp:!0,prefix:"session"}}):l==="webhook"&&console.warn("[TokenSpeedPlugin] Webhook reporter requires explicit configuration in outputHandlers");a.length>0&&Fe.registerHandlers(a)}t.outputOptions&&Fe.setDefaultOptions(t.outputOptions);let r=async a=>{let l=n.tokenizerService;if(!l)return n.log?.warn("TokenizerService not available"),null;if(!a.provider||!a.model)return null;let c=a.provider,i=a.model,u=`${c}:${i}`;if(jo.has(u))return jo.get(u);let d=l.getTokenizerConfigForModel(c,i);if(!d)return n.log?.debug(`No tokenizer config for ${c}:${i}, using fallback`),null;try{let m=await l.getTokenizer(d,c);return jo.set(u,m),n.log?.info(`Created tokenizer for ${c}:${i} - ${m.name}`),m}catch(m){return n.log?.warn(`Failed to create tokenizer for ${c}:${i}: ${m.message}`),null}},s=a=>{let l=new URL(`http://127.0.0.1${a}`).pathname;return l.endsWith("/v1/messages")||l.endsWith("/v1/responses")};n.addHook("onRequest",async a=>{s(a.url)&&(a.requestStartTime=performance.now())}),n.addHook("onSend",async(a,l,c)=>{let i=a.requestStartTime;if(!i)return;let u=a.id||Date.now().toString(),d=a.usageSessionId;if(!d)try{d=Ke(a.body?.metadata?.user_id)}catch{}if(!d){let f=a.headers?.["x-request-id"],_=Array.isArray(f)?f[0]:f;d=(typeof _=="string"?_:void 0)||u}let m=await r(a);if(c instanceof ReadableStream){at.set(u,{requestId:u,sessionId:d,startTime:i,lastTokenTime:i,tokenCount:0,tokensPerSecond:0,stream:!0});let[f,_]=c.tee(),k=async()=>{let h=null,b=async x=>{let v=at.get(u);if(!v)return;let C=v.firstTokenTime?v.firstTokenTime-v.startTime:0,T=(x?v.lastTokenTime:performance.now())-v.startTime;v.tokensPerSecond=ci(v.tokenCount,T,C),await li(v,o,t.outputOptions,x).catch(A=>{n.log?.warn(`Failed to output streaming stats: ${A.message}`)})};try{let v=_.pipeThrough(new TextDecoderStream).pipeThrough(new se).getReader();for(h=setInterval(async()=>{at.get(u)&&await b(!1)},1e3);;){let{done:C,value:R}=await v.read();if(C)break;let T=R,A=at.get(u);if(!A)continue;let w=performance.now(),O=T.event||T.data?.type,P=T.event==="content_block_start"||T.event==="content_block_delta"||T.event==="text_block"||T.event==="content_block"||O==="response.output_text.delta"||O==="response.function_call_arguments.delta"||O==="response.reasoning_summary_text.delta";!A.firstTokenTime&&P&&(A.firstTokenTime=w,A.timeToFirstToken=Math.round(w-A.startTime));let E="";if(T.event==="content_block_delta"&&T.data?.delta){let N=T.data.delta.type;N==="text_delta"?E=T.data.delta.text||"":N==="input_json_delta"?E=T.data.delta.partial_json||"":N==="thinking_delta"&&(E=T.data.delta.thinking||"")}if((O==="response.output_text.delta"||O==="response.function_call_arguments.delta"||O==="response.reasoning_summary_text.delta")&&(E=typeof T.data?.delta=="string"?T.data.delta:""),E){let N=m&&m.encodeText?m.encodeText(E).length:ct(E);A.tokenCount+=N,A.lastTokenTime=w}(T.event==="message_stop"||O==="response.completed"||O==="response.failed")&&(h&&(clearInterval(h),h=null),await b(!0),at.delete(u))}}catch(x){h&&clearInterval(h),x.name!=="AbortError"&&x.code!=="ERR_STREAM_PREMATURE_CLOSE"&&n.log?.warn(`Error processing token stats: ${x.message}`)}};return a.tokenSpeedCapturePromise=k().catch(h=>{console.log(h),n.log?.warn(`Background stats processing failed: ${h.message}`)}),f}let g=performance.now(),y=0,p=!1;if(c&&typeof c=="string")try{let f=JSON.parse(c);if(typeof f.usage?.output_tokens=="number")y=f.usage.output_tokens,p=!0;else{let _=f.content??f.message?.content;if(_!==void 0)if(p=!0,m)Array.isArray(_)?y=_.reduce((k,h)=>{if(h.type==="text"){let b=h.text||"";return k+(m.encodeText?m.encodeText(b).length:ct(b))}return k},0):typeof _=="string"&&(y=m.encodeText?m.encodeText(_).length:ct(_));else{let k=Array.isArray(_)?_.map(h=>h.text).join(""):typeof _=="string"?_:"";y=ct(k)}}}catch{}if(p){let f=Math.round(g-i),_=g-i,k={requestId:u,sessionId:d,startTime:i,lastTokenTime:g,tokenCount:y,tokensPerSecond:ci(y,_),timeToFirstToken:f,stream:!1};await li(k,o,t.outputOptions,!0)}return c})})}});var zo=S(()=>{"use strict";oi();ri();ui();Do()});import q from"node:fs/promises";import di from"json5";import ke from"node:path";import{CONFIG_FILE as ee,HOME_DIR as kn,PLUGINS_DIR as Fl}from"@wengine-ai/claude-code-router-shared";function pi(){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 Ho,lt,bn,Jo,j,xn,Z,Ul,Bo,ut=S(()=>{"use strict";Ho=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(Ho);if(n!==null&&typeof n=="object"){let e={};for(let[t,o]of Object.entries(n))e[t]=Ho(o);return e}return n},lt=async n=>{try{await q.access(n)}catch{await q.mkdir(n,{recursive:!0})}},bn=async()=>{await lt(kn),await lt(Fl),await lt(ke.join(kn,"logs"))},Jo=async()=>{let n=await q.readFile(ee,"utf-8");return di.parse(n)},j=async()=>{try{let n=await q.readFile(ee,"utf-8");try{let e=di.parse(n);return Ho(e)}catch(e){console.error(`Failed to parse config file at ${ee}`),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 bn();let e=await xn();e&&console.log(`Backed up existing configuration file to ${e}`);let t={PORT:3456,Providers:[],Router:{}};return await Z(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 ${ee}`),console.error("Error details:",n.message),process.exit(1)}};xn=async()=>{pi();try{if(await q.access(ee).then(()=>!0).catch(()=>!1)){let n=new Date().toISOString().replace(/[:.]/g,"-"),e=`${ee}.${n}.bak`;await q.copyFile(ee,e);try{let t=ke.dirname(ee),o=ke.basename(ee),s=(await q.readdir(t)).filter(a=>a.startsWith(o)&&a.endsWith(".bak")).sort().reverse();if(s.length>3)for(let a=3;a<s.length;a++){let l=ke.join(t,s[a]);await q.unlink(l)}}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},Z=async n=>{pi(),await lt(kn),await Ul();let e=`${JSON.stringify(n,null,2)}`;await q.writeFile(ee,e)},Ul=async()=>{if(!await q.access(ee).then(()=>!0).catch(()=>!1))return;let e=ke.join(kn,"config-history");await lt(e);let t=new Date().toISOString().replace(/[:.]/g,"-"),o=ke.join(e,`config-${t}.json`);await q.copyFile(ee,o);try{let s=(await q.readdir(e)).filter(a=>a.startsWith("config-")&&a.endsWith(".json")).sort().reverse();if(s.length>50)for(let a of s.slice(50))await q.unlink(ke.join(e,a))}catch(r){console.warn("Failed to prune config-history:",r)}},Bo=async()=>{let n=await j();return Object.assign(process.env,n),n}});function Dl(n){return n?.cache_read_input_tokens??n?.input_tokens_details?.cached_tokens??n?.prompt_tokens_details?.cached_tokens??0}function jl(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 Ue(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:Dl(n),cache_creation_input_tokens:jl(n)}}function Cn(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 Wo=S(()=>{"use strict"});function Tn(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(Go(r,s))}return}if(Array.isArray(n)){for(let o of n)Tn(o,e,t);return}if(typeof n=="object")for(let o of Object.values(n))Tn(o,e,t)}}function fi(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 a=Array.isArray(r?.models)?r.models:[];for(let l of a)l&&o.add(Go(s,l))}return Tn(n?.Router,t,o),Tn(n?.fallback,t,o),o}function dt(n,e){try{let t=U();if(!t?.getAllStates||!t?.recover)return 0;let o=fi(n),r=0;for(let s of t.getAllStates()||[]){let a=s?.provider,l=s?.model;!a||!l||o.has(Go(a,l))||(t.recover(a,l),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 vn(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 zl,Go,Rn=S(()=>{"use strict";ne();zl="\0",Go=(n,e)=>`${n}${zl}${e}`});function Hl(n){return/\[1m\]/i.test(n)?1e6:2e5}function Jl(n){let e=n.toLowerCase();return e.includes("haiku")||e.includes("mini")?8192:32e3}function Bl(n,e=n){let t=Hl(n),o=Jl(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,Bl(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 Vo=S(()=>{"use strict"});function Wl(n){let e=n.ip||n.connection?.remoteAddress||"";return e==="127.0.0.1"||e==="::1"||e==="::ffff:127.0.0.1"}var Sn,Qo=S(()=>{"use strict";Sn=n=>async(e,t,o)=>{if(["/","/health"].includes(e.url)||e.url.startsWith("/ui")||Wl(e))return o();let s=n.Providers||n.providers||[];if(!s||s.length===0)return o();let a=n.APIKEY;if(!a){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 l=e.headers.authorization||e.headers["x-api-key"],c=Array.isArray(l)?l[0]:l||"";if(!c){t.log.warn({url:e.url,headers:Object.keys(e.headers)},"[AUTH] No auth header"),t.status(401).send("APIKEY is missing");return}let i="";if(c.startsWith("Bearer")?i=c.split(" ")[1]:i=c,i!==a){t.log.warn({url:e.url,gotPrefix:i.slice(0,10),gotSuffix:i.slice(-6),gotLen:i.length,expectedPrefix:a.slice(0,6),expectedSuffix:a.slice(-6),expectedLen:a.length},"[AUTH] Key mismatch"),t.status(401).send("Invalid API key");return}o()}});var Ti={};Fn(Ti,{append:()=>gt,clear:()=>er,close:()=>lu,getOldestRecordTimestamp:()=>uu,query:()=>Zo,querySummary:()=>ht,readTokenSpeedStats:()=>tr});import{existsSync as Yo,mkdirSync as Gl,readFileSync as Xo,readdirSync as Vl}from"fs";import{join as ze}from"path";import{homedir as Ql,tmpdir as Kl}from"os";import Xl from"better-sqlite3";function tu(){Yo(Pn)||Gl(Pn,{recursive:!0})}function mt(){if(fe)return fe;tu();let n=new Xl(Yl);n.pragma("journal_mode = WAL"),n.pragma("synchronous = NORMAL"),n.pragma("busy_timeout = 5000");let e=n.pragma("user_version",{simple:!0})||0;return e<1&&(nu(n),n.pragma("user_version = 1")),e<2&&(n.prepare("PRAGMA table_info(usage_records)").all().some(o=>o.name==="upstream_model")||n.exec("ALTER TABLE usage_records ADD COLUMN upstream_model TEXT"),n.pragma("user_version = 2")),ru(n),ki(n,!0),qo=n.prepare(`
|
|
316
316
|
INSERT INTO usage_records (
|
|
317
317
|
id, timestamp, session_id, provider, original_model, model, upstream_model, model_family,
|
|
318
318
|
scenario_type, client_type, codex_account_id, codex_account_email,
|
|
@@ -326,7 +326,7 @@ ${this.toMarkdown(s,t+1)}`:`${o}${r}: ${s}`).join(`
|
|
|
326
326
|
@cache_read_input_tokens, @cache_creation_input_tokens, @ttft,
|
|
327
327
|
@tokens_per_second, @duration_ms, @status, @error_message, @response_body
|
|
328
328
|
)
|
|
329
|
-
`),fe=n,fe}function
|
|
329
|
+
`),fe=n,fe}function nu(n){n.exec(`
|
|
330
330
|
CREATE TABLE IF NOT EXISTS usage_records (
|
|
331
331
|
id TEXT PRIMARY KEY,
|
|
332
332
|
timestamp TEXT NOT NULL,
|
|
@@ -365,12 +365,12 @@ ${this.toMarkdown(s,t+1)}`:`${o}${r}: ${s}`).join(`
|
|
|
365
365
|
CREATE INDEX IF NOT EXISTS idx_usage_records_scenario_timestamp ON usage_records(scenario_type, timestamp);
|
|
366
366
|
CREATE INDEX IF NOT EXISTS idx_usage_records_client_timestamp ON usage_records(client_type, timestamp);
|
|
367
367
|
CREATE INDEX IF NOT EXISTS idx_usage_records_session_timestamp ON usage_records(session_id, timestamp);
|
|
368
|
-
`)}function
|
|
368
|
+
`)}function ou(n,e){return n.prepare("SELECT value FROM usage_meta WHERE key = ?").get(e)?.value}function pt(n,e,t){n.prepare(`
|
|
369
369
|
INSERT INTO usage_meta (key, value)
|
|
370
370
|
VALUES (?, ?)
|
|
371
371
|
ON CONFLICT(key) DO UPDATE SET value = excluded.value
|
|
372
|
-
`).run(e,t)}function
|
|
373
|
-
`)){let c=l.trim();if(c)try{let i=JSON.parse(c);if(!
|
|
372
|
+
`).run(e,t)}function ru(n){if(ou(n,mi)||!Yo(Ko))return;let e=iu(n,"INSERT OR IGNORE"),t=Xo(Ko,"utf-8"),o=0,r=0,s=0;n.transaction(()=>{for(let l of t.split(`
|
|
373
|
+
`)){let c=l.trim();if(c)try{let i=JSON.parse(c);if(!su(i)){r++;continue}e.run(yi(An(i))).changes>0?o++:s++}catch{r++}}pt(n,mi,new Date().toISOString()),pt(n,"legacy_usage_jsonl_migrated_path",Ko),pt(n,"legacy_usage_jsonl_imported_count",String(o)),pt(n,"legacy_usage_jsonl_skipped_count",String(r)),pt(n,"legacy_usage_jsonl_duplicate_count",String(s))})()}function su(n){if(!n||typeof n!="object")return!1;let e=n;return typeof e.id=="string"&&e.id.length>0&&typeof e.timestamp=="string"&&e.timestamp.length>0}function iu(n,e="INSERT"){return n.prepare(`
|
|
374
374
|
${e} INTO usage_records (
|
|
375
375
|
id, timestamp, session_id, provider, original_model, model, upstream_model, model_family,
|
|
376
376
|
scenario_type, client_type, codex_account_id, codex_account_email,
|
|
@@ -384,9 +384,9 @@ ${this.toMarkdown(s,t+1)}`:`${o}${r}: ${s}`).join(`
|
|
|
384
384
|
@cache_read_input_tokens, @cache_creation_input_tokens, @ttft,
|
|
385
385
|
@tokens_per_second, @duration_ms, @status, @error_message, @response_body
|
|
386
386
|
)
|
|
387
|
-
`)}function cu(n,e,t){if(n<=0||e==null||!Number.isFinite(e))return null;let o=t!=null&&Number.isFinite(t)?t:0,r=Math.max((e-o)/1e3,Zl);return Math.round(n/r)}function An(n){let e=Number(n.outputTokens)||0,t=Number(n.durationMs),o=Number.isFinite(t)?t:null,r=ke(n.ttft);return{...n,ttft:r,tokensPerSecond:cu(e,o,r)}}function pe(n){return typeof n=="string"?n:n==null?"":String(n)}function De(n){if(n==null)return;let e=String(n);return e.length>0?e:void 0}function ft(n){let e=Number(n);return Number.isFinite(e)?e:0}function yi(n){return n==="success"?"success":"error"}function _i(n){let e=An(n);return{id:pe(e.id),timestamp:pe(e.timestamp),session_id:pe(e.sessionId),provider:pe(e.provider),original_model:pe(e.originalModel),model:pe(e.model),upstream_model:De(e.upstreamModel)??null,model_family:pe(e.modelFamily),scenario_type:pe(e.scenarioType),client_type:De(e.clientType)??null,codex_account_id:De(e.codexAccountId)??null,codex_account_email:De(e.codexAccountEmail)??null,stream:e.stream?1:0,input_tokens:Math.trunc(ft(e.inputTokens)),output_tokens:Math.trunc(ft(e.outputTokens)),cache_read_input_tokens:Math.trunc(ft(e.cacheReadInputTokens)),cache_creation_input_tokens:Math.trunc(ft(e.cacheCreationInputTokens)),ttft:ke(e.ttft),tokens_per_second:ke(e.tokensPerSecond),duration_ms:Math.trunc(ft(e.durationMs)),status:yi(e.status),error_message:De(e.errorMessage)??null,response_body:De(e.responseBody)??null}}function ki(n){return An({id:n.id,timestamp:n.timestamp,sessionId:n.session_id,provider:n.provider,originalModel:n.original_model,model:n.model,upstreamModel:n.upstream_model??void 0,modelFamily:n.model_family,scenarioType:n.scenario_type,clientType:n.client_type??void 0,codexAccountId:n.codex_account_id??void 0,codexAccountEmail:n.codex_account_email??void 0,stream:n.stream===1,inputTokens:n.input_tokens,outputTokens:n.output_tokens,cacheReadInputTokens:n.cache_read_input_tokens,cacheCreationInputTokens:n.cache_creation_input_tokens,ttft:n.ttft,tokensPerSecond:n.tokens_per_second,durationMs:n.duration_ms,status:yi(n.status),errorMessage:n.error_message??void 0,responseBody:n.response_body??void 0})}function lu(){return new Date(Date.now()-eu*24*60*60*1e3).toISOString()}function bi(n,e=!1){let t=Date.now();!e&&t-hi<tu||(n.prepare("DELETE FROM usage_records WHERE timestamp < ?").run(lu()),hi=t)}function xi(n){let e=[],t=[];return n.startTime&&(e.push("timestamp >= ?"),t.push(n.startTime)),n.endTime&&(e.push("timestamp <= ?"),t.push(n.endTime)),n.model&&(e.push("model = ?"),t.push(n.model)),n.provider&&(e.push("provider = ?"),t.push(n.provider)),n.scenario&&(e.push("scenario_type = ?"),t.push(n.scenario)),n.clientType&&(n.clientType==="unknown"?(e.push("(client_type IS NULL OR client_type = '' OR client_type = ?)"),t.push(n.clientType)):(e.push("client_type = ?"),t.push(n.clientType))),n.sessionId&&(e.push("session_id = ?"),t.push(n.sessionId)),n.status&&(e.push("status = ?"),t.push(n.status)),{sql:e.length>0?`WHERE ${e.join(" AND ")}`:"",params:t}}function Ci(n,e){let t=xi(e);return n.prepare(`SELECT * FROM usage_records ${t.sql}`).all(...t.params).map(ki)}function Ti(n){let e={totalRequests:n.length,successCount:0,errorCount:0,totalInputTokens:0,totalOutputTokens:0,totalCacheReadInputTokens:0,totalCacheCreationInputTokens:0,avgTtft:null,avgTokensPerSecond:null,byModel:{},byProvider:{},byScenario:{},byFamily:{},byDay:{},byClient:{}},t=0,o=0,r=0,s=0;for(let a of n){let l=a.status==="success";l?e.successCount++:e.errorCount++;let c=l&&a.inputTokens||0,i=l&&a.outputTokens||0,u=l&&a.cacheReadInputTokens||0,d=l&&a.cacheCreationInputTokens||0;e.totalInputTokens+=c,e.totalOutputTokens+=i,e.totalCacheReadInputTokens+=u,e.totalCacheCreationInputTokens+=d,l&&a.ttft!=null&&(t+=a.ttft,o++),l&&a.tokensPerSecond!=null&&(r+=a.tokensPerSecond,s++);let m=a.timestamp.slice(0,10);if(je(e.byModel,a.model,c,i,u,d),je(e.byProvider,a.provider,c,i,u,d),je(e.byScenario,a.scenarioType,c,i,u,d),a.modelFamily){let g=`${a.modelFamily}/${a.scenarioType}`;je(e.byFamily,g,c,i,u,d)}je(e.byDay,m,c,i,u,d),je(e.byClient,a.clientType||"unknown",c,i,u,d)}return o>0&&(e.avgTtft=Math.round(t/o)),s>0&&(e.avgTokensPerSecond=Math.round(r/s)),e}function je(n,e,t,o,r,s){n[e]||(n[e]={count:0,inputTokens:0,outputTokens:0,cacheReadInputTokens:0,cacheCreationInputTokens:0}),n[e].count++,n[e].inputTokens+=t,n[e].outputTokens+=o,n[e].cacheReadInputTokens+=r,n[e].cacheCreationInputTokens+=s}function gt(n){let e=mt(),t=An(n);qo.run(_i(t)),bi(e)}function Zo(n){let e=mt(),t=xi(n),o=Number.isFinite(n.page)&&n.page>0?Math.floor(n.page):1,r=Number.isFinite(n.pageSize)&&n.pageSize>0?Math.floor(n.pageSize):50,s=(o-1)*r,a=e.prepare(`SELECT COUNT(*) AS count FROM usage_records ${t.sql}`).get(...t.params),l=e.prepare(`SELECT * FROM usage_records ${t.sql} ORDER BY timestamp DESC LIMIT ? OFFSET ?`).all(...t.params,r,s),c=Ti(Ci(e,n));return{records:l.map(ki),summary:c,total:a.count,page:o,pageSize:r}}function ht(n,e,t){let o=mt();return Ti(Ci(o,{startTime:n,endTime:e,status:t}))}function er(n){let e=mt();if(!n){e.prepare("DELETE FROM usage_records").run();return}e.prepare("DELETE FROM usage_records WHERE timestamp < ?").run(n)}function uu(){fe&&(fe.pragma("wal_checkpoint(TRUNCATE)"),fe.close(),fe=null,qo=null)}function ke(n){if(n==null)return null;if(typeof n=="number")return n;let e=parseFloat(String(n));return isNaN(e)?null:e}function tr(n){let e=ze(Xl(),"claude-code-router"),t=ze(e,`session-${n}.json`);if(Yo(t))try{let o=Xo(t,"utf-8"),r=JSON.parse(o);return{ttft:ke(r.timeToFirstToken),tokensPerSecond:ke(r.tokensPerSecond)}}catch{}try{let o=Ql(e),r=new RegExp(`^session-${n}-\\d+\\.json$`),s=o.filter(a=>r.test(a));if(s.length>0){let a=s.sort().reverse(),l=ze(e,a[0]);try{let c=Xo(l,"utf-8"),i=JSON.parse(c);return{ttft:ke(i.timeToFirstToken),tokensPerSecond:ke(i.tokensPerSecond)}}catch{return{ttft:null,tokensPerSecond:null}}}}catch{}return{ttft:null,tokensPerSecond:null}}function du(n,e,t){return mt().prepare("SELECT MIN(timestamp) AS timestamp FROM usage_records WHERE provider = ? AND timestamp >= ? AND timestamp <= ?").get(n,e,t)?.timestamp??void 0}var Pn,ql,Ko,Zl,eu,tu,gi,fe,qo,hi,yt=S(()=>{"use strict";Pn=ze(Kl(),".claude-code-router","data"),ql=ze(Pn,"usage.sqlite"),Ko=ze(Pn,"usage.jsonl"),Zl=1,eu=180,tu=3600*1e3,gi="legacy_usage_jsonl_migrated_at",fe=null,qo=null,hi=0});import{existsSync as pu}from"fs";import{homedir as fu}from"os";import{join as mu}from"path";import{writeFile as gu}from"fs/promises";async function Ri(){let n=fu(),e=mu(n,".claude.json");if(!pu(e)){let o={numStartups:184,autoUpdaterStatus:"enabled",userID:Array.from({length:64},()=>Math.random().toString(16)[2]).join(""),hasCompletedOnboarding:!0,lastOnboardingVersion:"1.0.17",projects:{}};await gu(e,JSON.stringify(o,null,2))}}var wi=S(()=>{"use strict"});import{existsSync as hu,readFileSync as yu}from"fs";import{join as _u}from"path";import{HOME_DIR as ku,getActiveCodexAccount as Ai,listCodexAccounts as bu,markActiveCodexAccountLimitedAndSwitch as Oi,refreshDueCodexAccounts as xu}from"@wengine-ai/claude-code-router-shared";function Cu(n){let e=n.Clients?.codex?.autoSwitchUsageThreshold;return typeof e=="number"&&Number.isFinite(e)?Math.min(100,Math.max(1,e)):95}function Tu(n){try{let e=_u(ku,"codex-accounts",`${n}.auth.json`);if(!hu(e))return{};let t=JSON.parse(yu(e,"utf8"));return{accessToken:t?.tokens?.access_token,chatGptAccountId:t?.tokens?.account_id||n}}catch{return{}}}function vu(n){let e=n?.rate_limit;if(!e)return null;let t=e.primary_window,o=e.secondary_window;return{used5h:typeof t?.used_percent=="number"?t.used_percent:void 0,used7d:typeof o?.used_percent=="number"?o.used_percent:void 0,resetAfter5h:typeof t?.reset_after_seconds=="number"?t.reset_after_seconds:void 0,resetAfter7d:typeof o?.reset_after_seconds=="number"?o.reset_after_seconds:void 0}}async function Ru(n){let{accessToken:e,chatGptAccountId:t}=Tu(n);if(!e)return null;let o={Authorization:`Bearer ${e}`,"ChatGPT-Account-Id":t||n,originator:"codex_cli_rs",Accept:"application/json","Accept-Encoding":"gzip, deflate","User-Agent":"codex_cli_rs/0.0.0"},r=["https://chatgpt.com/backend-api/wham/usage","https://chatgpt.com/backend-api/codex/usage"];for(let s of r)try{let a=await fetch(s,{headers:o,signal:AbortSignal.timeout(15e3)});if(!a.ok)continue;let l=vu(await a.json());if(l)return l}catch{}return null}function wu(n,e){let t=typeof n.used7d=="number"&&n.used7d>=e,o=typeof n.used5h=="number"&&n.used5h>=e;return t?{window:"7d",used:n.used7d,retryAfterSeconds:n.resetAfter7d}:o?{window:"5h",used:n.used5h,retryAfterSeconds:n.resetAfter5h}:null}async function Su(){try{let n=await j(),e=Ai(n);return{id:e?.id,email:e?.email}}catch{return{}}}async function Ei(){try{let n=await j();if((n.Clients?.codex||{}).autoSwitchAccounts===!1)return;let t=Cu(n),o=Math.max(1,bu(n).accounts.length);for(let r=0;r<o;r+=1){let s=Ai(n);if(!s?.id)return;let a=await Ru(s.id);if(!a)return;let l=wu(a,t);if(!l)return;let c=`Codex ${l.window} usage reached ${Math.round(l.used)}% (auto-switch threshold ${t}%)`,i=Oi(n,c,l.retryAfterSeconds);if(await q(i.config),!i.switchedAccount){console.warn(`[Codex] ${c}; no available Codex account could be switched to`);return}console.warn(`[Codex] ${c}; switched account to ${i.switchedAccount.email||i.switchedAccount.id}`),n=i.config}}catch(n){console.error("Failed to auto-switch Codex account before usage limit:",n)}}async function On(n){try{let e=await j();if((e.Clients?.codex||{}).autoSwitchAccounts===!1)return;let o=Oi(e,n);await q(o.config),o.switchedAccount?console.warn(`[Codex] Rate limit detected; switched account to ${o.switchedAccount.email||o.switchedAccount.id}`):console.warn("[Codex] Rate limit detected, but no available Codex account could be switched to")}catch(e){console.error("Failed to auto-switch Codex account after rate limit:",e)}}async function Pi(){try{let n=await j();if(n.Clients?.codex?.autoRefreshTokens===!1)return;let e=await xu(n);for(let t of e)t.refreshed?console.log(`[Codex] Refreshed tokens for account ${t.label} (${t.id})`):console.warn(`[Codex] Failed to refresh tokens for account ${t.label} (${t.id}): ${t.error}`)}catch(n){console.error("[Codex] Token refresh cycle failed:",n)}}function Ii(){if(Si)return;Si=!0,setTimeout(()=>void Pi(),6e4).unref(),setInterval(()=>void Pi(),Pu).unref()}function En(n,e){return n===429||!!(e&&/rate[\s_]limit|too many|限流|频率限制|qps_limit|token_limit|quota exhausted|usage limit|limit reached/i.test(e))}async function Mi(){return Su()}var Pu,Si,nr=S(()=>{"use strict";ut();Pu=1800*1e3,Si=!1});import{existsSync as Au,readdirSync as Ou,statSync as Eu,unlinkSync as Iu}from"fs";import{join as $i}from"path";import{HOME_DIR as Mu}from"@wengine-ai/claude-code-router-shared";function Li(n=$i(Mu,"logs")){try{if(!Au(n))return;let e=Date.now()-Nu;for(let t of Ou(n)){if(!/^ccr-.*\.log$/.test(t))continue;let o=$i(n,t),r=Eu(o);r.isFile()&&r.mtime.getTime()<e&&Iu(o)}}catch(e){console.warn("Failed to prune old server log files:",e)}}function Fi(){Ni||(Ni=!0,Li(),setInterval(Li,Lu).unref())}var $u,Nu,Lu,Ni,Ui=S(()=>{"use strict";$u=7,Nu=$u*24*60*60*1e3,Lu=1440*60*1e3,Ni=!1});async function Di(n,e){let t=e.plugins||e.Plugins||[];for(let o of t){let{name:r,enabled:s=!1,options:a={}}=o;switch(r){case"token-speed":rt.registerPlugin(yn,{enabled:s,outputHandlers:[{type:"temp-file",enabled:!0,config:{subdirectory:"claude-code-router",extension:"json",includeTimestamp:!0,prefix:"session"}}],...a});break;default:console.warn(`Unknown plugin: ${r}`);break}}await rt.enablePlugins(n)}var ji=S(()=>{"use strict";jo()});import{existsSync as Hi,mkdirSync as Fu,readFileSync as Ji,writeFileSync as Uu}from"fs";import{join as sr}from"path";import{HOME_DIR as Bi,listCodexAccounts as Du}from"@wengine-ai/claude-code-router-shared";function zi(n){if(!(typeof n!="number"||!Number.isFinite(n)))return new Date(n*1e3).toISOString()}function Gi(){if(!Hi(rr))return{};try{let n=JSON.parse(Ji(rr,"utf8"));return!n||typeof n!="object"||Array.isArray(n)?{}:n}catch{return{}}}function Vi(n){Fu(Wi,{recursive:!0}),Uu(rr,`${JSON.stringify(n,null,2)}
|
|
388
|
-
`,"utf8")}function Hu(n,e){let t=!1,o={};for(let[r,s]of Object.entries(n))e.has(r)?o[r]=s:t=!0;return t&&Vi(o),t?o:n}function Ju(n,e){if(!n?.fetchedAt)return!1;let t=Date.parse(n.fetchedAt),o=e?ju:zu;return Number.isFinite(t)&&Date.now()-t<o}function Bu(n){let e=n?.rate_limit;if(!e)return null;let t=e.primary_window,o=e.secondary_window,r={planType:typeof n.plan_type=="string"?n.plan_type:void 0,rateLimitReachedType:typeof n.rate_limit_reached_type?.type=="string"?n.rate_limit_reached_type.type:null};return typeof t?.used_percent=="number"&&(r.used5h=t.used_percent,r.reset5h=zi(t.reset_at)),typeof o?.used_percent=="number"&&(r.used7d=o.used_percent,r.reset7d=zi(o.reset_at)),r.used5h!==void 0||r.used7d!==void 0?r:null}function Wu(n){let e=sr(Bi,"codex-accounts",`${n}.auth.json`);if(!Hi(e))return null;try{return JSON.parse(Ji(e,"utf8"))}catch{return null}}async function Gu(n){let e=Wu(n),t=e?.tokens?.access_token,o=e?.tokens?.account_id||n;if(!t)return null;let r={Authorization:`Bearer ${t}`,"ChatGPT-Account-Id":o,originator:"codex_cli_rs",Accept:"application/json","Accept-Encoding":"gzip, deflate","User-Agent":"codex_cli_rs/0.0.0"},s=["https://chatgpt.com/backend-api/wham/usage","https://chatgpt.com/backend-api/codex/usage"];for(let a of s)try{let l=await fetch(a,{headers:r,signal:AbortSignal.timeout(15e3)});if(!l.ok)continue;let c=await l.json(),i=Bu(c);if(i)return i}catch{}return null}function Vu(n,e){return e?{...n,plan:e.planType||n.plan,limitedWindow:e.rateLimitReachedType?n.limitedWindow||"unknown":n.limitedWindow,usage:{used5h:e.used5h??0,used7d:e.used7d??0,limit5h:e.used5h!==void 0?100:void 0,limit7d:e.used7d!==void 0?100:void 0,reset5h:e.reset5h,reset7d:e.reset7d}}:n}function Qu(n){for(let e of n){if(or.has(e))continue;let t=(async()=>{let o=await Gu(e);if(!o)return;let r=Gi();r[e]={...o,fetchedAt:new Date().toISOString()},Vi(r)})().catch(o=>{console.error(`Failed to refresh Codex usage for ${e}:`,o)}).finally(()=>{or.delete(e)});or.set(e,t)}}async function He(n){let e=Du(n),t=new Set(e.accounts.map(a=>a.id)),o=Hu(Gi(),t),r=e.accounts.filter(a=>!Ju(o[a.id],a.active)).map(a=>a.id);r.length>0&&Qu(r);let s=e.accounts.map(a=>Vu(a,o[a.id]));return{...e,accounts:s}}var Wi,rr,ju,zu,or,Qi=S(()=>{"use strict";Wi=sr(Bi,"data"),rr=sr(Wi,"codex-usage-cache.json"),ju=60*1e3,zu=1800*1e3,or=new Map});import{join as te,isAbsolute as Ku,normalize as Xu,dirname as Yu}from"path";import{fileURLToPath as qu}from"url";import Zu from"@fastify/static";import{readdirSync as Ki,statSync as ed,readFileSync as Xi,writeFileSync as td,existsSync as ue,unlinkSync as Yi,rmSync as nd}from"fs";import{homedir as ir}from"os";import{getPresetDir as In,readManifestFromDir as ar,manifestToPresetFile as qi,saveManifest as Zi,isPresetInstalled as ea,extractPreset as od,HOME_DIR as rd,loadConfigFromManifest as sd,downloadPresetToTemp as id,findMarketPresetByName as ad,getMarketPresets as cd,applyClientSelection as ld,activateCodexAccount as ud,deleteCodexAccount as dd,disableClient as pd,enableClient as fd,exportCodexRefreshToken as ta,importCodexAccountFromRefreshToken as md,importCurrentCodexAccount as gd,isClientId as hd,listClientStatuses as na,restoreClient as yd,listProjectConfigs as _d,readProjectConfigById as cr,readProjectConfig as kd,writeProjectConfig as oa,deleteProjectConfig as bd,getClaudeProjectId as xd,getProjectConfigPath as Cd,refreshProjectTakeovers as Td,syncGlobalProjectTakeovers as vd,getProjectTakeoverClients as lr,setProjectTakeover as ur,isProjectTakeoverClient as Rd}from"@wengine-ai/claude-code-router-shared";import wd from"@fastify/multipart";import Sd from"adm-zip";function Pd(n){let e=new Date().toISOString(),t=new Date(Date.now()-300*60*1e3).toISOString(),o=new Date(Date.now()-10080*60*1e3).toISOString(),r=ht(t,e),s=ht(o,e),a=[],l=new Set;for(let c of n||[])c&&c.name&&l.add(c.name);for(let c of Object.keys(r.byProvider||{}))l.add(c);for(let c of Object.keys(s.byProvider||{}))l.add(c);for(let c of l){let i=r.byProvider[c]||{inputTokens:0,outputTokens:0},u=s.byProvider[c]||{inputTokens:0,outputTokens:0},d=(i.inputTokens||0)+(i.outputTokens||0),m=(u.inputTokens||0)+(u.outputTokens||0),g,y,p=(n||[]).find(f=>f&&f.name===c);p&&p.quota&&(g=p.quota.limit5h,y=p.quota.limit7d),a.push({provider:c,used5h:d,used7d:m,limit5h:g,limit7d:y})}return a}async function ra(n,e){let t=n.app;Ve(),Qe(),t.register(wd,{limits:{fileSize:50*1024*1024}}),t.get("/v1/models",async()=>{let l=wn(e);return{object:"list",data:l,first_id:l[0]?.id||null,last_id:l[l.length-1]?.id||null,has_more:!1}}),t.get("/v1/models/:modelId",async(l,c)=>{let i=decodeURIComponent(l.params.modelId),u=wn(e).find(d=>d.id===i);return u||(c.status(404),{type:"error",error:{type:"not_found_error",message:`Model not found: ${i}`}})}),t.post("/v1/messages/count_tokens",async(l,c)=>{let{messages:i,tools:u,system:d,model:m}=l.body,g=t._server.tokenizerService;if(m&&m.includes(",")&&g)try{let[p,f]=m.split(",");l.log?.info(`Looking up tokenizer for provider: ${p}, model: ${f}`);let _=g.getTokenizerConfigForModel(p,f);_?l.log?.info(`Using tokenizer config: ${JSON.stringify(_)}`):l.log?.warn(`No tokenizer config found for ${p},${f}, using default tiktoken`);let k=await g.countTokens({messages:i,system:d,tools:u},_,p);return{input_tokens:k.tokenCount,tokenizer:k.tokenizerUsed}}catch(p){l.log?.error(`Error using configured tokenizer: ${p.message}`),l.log?.error(p.stack)}else m?m.includes(",")?g||l.log?.warn("TokenizerService not available, using default tiktoken"):l.log?.info(`Model "${m}" does not contain comma, using default tiktoken`):l.log?.info("No model specified, using default tiktoken");return{input_tokens:It(i,d,u)}}),t.get("/api/config",async(l,c)=>await Jo()),t.get("/api/transformers",async(l,c)=>{let i=t._server.transformerService.getAllTransformers();return{transformers:Array.from(i.entries()).map(([d,m])=>({name:d,endpoint:m.endPoint||null}))}}),t.post("/api/config",async(l,c)=>{let i=l.body,u=yr(i||{});if(u.length>0)return c.status(400),{success:!1,error:"Invalid proxy URL",message:u.map(g=>`${g.key}: ${g.error}`).join("; "),proxyErrors:u};let d=await xn();d&&console.log(`Backed up existing configuration file to ${d}`),await q(i);let m;try{m=await vd(i),m.failed.length>0&&t.log?.warn?.({projectTakeoverSync:m},"Config saved but some global project takeovers failed to sync")}catch(g){t.log?.warn?.(`Config saved but global project takeover sync failed: ${g?.message||g}`)}try{let g=t._server;if(g?.configService){g.configService.reload();let y=i?.Providers||i?.providers;if(Array.isArray(y)&&g.configService.set("providers",y),ce&&g.transformerService&&(g.providerService=new ce(g.configService,g.transformerService,t.log)),dt(i,t.log),Ne&&mn){try{mn()}catch{}let p={enabled:g.configService.get("ACTIVE_PROBE_ENABLED")??!0,quotaProbeIntervalMinutes:g.configService.get("QUOTA_PROBE_INTERVAL_MINUTES")??10,probeTimeoutMs:g.configService.get("PROBE_TIMEOUT_MS")??15e3,initialDelayMs:g.configService.get("PROBE_INITIAL_DELAY_MS")??5e3,excludeProviders:g.configService.get("EXCLUDE_PROBE_PROVIDERS")??[]};g.activeProbeService=Ne(()=>g.providerService.getProviders(),p,f=>se(g.configService,f),t.log,f=>g.configService.get(f))}}}catch(g){t.log?.warn?.(`Config saved but runtime reload failed: ${g?.message||g}`)}return{success:!0,message:"Config saved successfully",projectTakeoverSync:m}}),t.get("/api/clients",async(l,c)=>{try{let i=await j();return{clients:na(i)}}catch(i){console.error("Failed to get client integrations:",i),c.status(500).send({error:i.message||"Failed to get client integrations"})}}),t.post("/api/clients/apply",async(l,c)=>{try{let i=l.body,u=Array.isArray(i?.enabled)?i.enabled:[],d=await j(),m=ld(d,u);return await q(m.config),m}catch(i){console.error("Failed to apply client integrations:",i),c.status(500).send({error:i.message||"Failed to apply client integrations"})}});async function o(l,c,i){try{let{id:u}=l.params;if(!hd(u)){c.status(404).send({error:`Unknown client: ${u}`});return}let d=await j(),m=i==="enable"?fd(d,u):i==="restore"?yd(d,u):pd(d,u);return await q(d),{success:m.success,result:m,results:[m],clients:na(d),config:d}}catch(u){console.error(`Failed to ${i} client integration:`,u),c.status(500).send({error:u.message||`Failed to ${i} client integration`})}}t.post("/api/clients/:id/enable",async(l,c)=>o(l,c,"enable")),t.post("/api/clients/:id/disable",async(l,c)=>o(l,c,"disable")),t.post("/api/clients/:id/restore",async(l,c)=>o(l,c,"restore")),t.get("/api/clients/codex/accounts",async(l,c)=>{try{let i=await j();return await He(i)}catch(i){console.error("Failed to get Codex accounts:",i),c.status(500).send({error:i.message||"Failed to get Codex accounts"})}}),t.post("/api/clients/codex/accounts/import-current",async(l,c)=>{try{let i=l.body,u=await j(),d=gd(u,i?.label);await q(d.config);let m=await He(d.config);return{...d,...m}}catch(i){console.error("Failed to import current Codex account:",i),c.status(500).send({error:i.message||"Failed to import current Codex account"})}}),t.post("/api/clients/codex/accounts/import-rt",async(l,c)=>{try{let i=l.body,u=await j(),d=await md(u,i?.refreshToken||"",i?.label);await q(d.config);let m=await He(d.config);return{...d,...m}}catch(i){console.error("Failed to import Codex account from refresh token:",i),c.status(500).send({error:i.message||"Failed to import Codex account from refresh token"})}}),t.post("/api/clients/codex/accounts/:accountId/activate",async(l,c)=>{try{let{accountId:i}=l.params,u=await j(),d=ud(u,i);await q(d.config);let m=await He(d.config);return{...d,...m}}catch(i){console.error("Failed to activate Codex account:",i),c.status(500).send({error:i.message||"Failed to activate Codex account"})}}),t.post("/api/clients/codex/accounts/:accountId/export-rt",async(l,c)=>{try{let{accountId:i}=l.params,u=await j();return ta(u,i)}catch(i){console.error("Failed to export Codex refresh token:",i),c.status(500).send({error:i.message||"Failed to export Codex refresh token"})}}),t.post("/api/clients/codex/accounts/export-rt",async(l,c)=>{try{let i=await j();return ta(i)}catch(i){console.error("Failed to export active Codex refresh token:",i),c.status(500).send({error:i.message||"Failed to export active Codex refresh token"})}}),t.delete("/api/clients/codex/accounts/:accountId",async(l,c)=>{try{let{accountId:i}=l.params,u=await j(),d=dd(u,i);await q(d.config);let m=await He(d.config);return{...d,...m}}catch(i){console.error("Failed to delete Codex account:",i),c.status(500).send({error:i.message||"Failed to delete Codex account"})}}),t.get("/api/projects",async(l,c)=>{try{let i=await _d();return{projects:await Promise.all(i.map(async d=>{let m=await lr(d.path);return{...d,ccrTakeoverClients:m,ccrTakeover:m.length>0}}))}}catch(i){console.error("Failed to list project configs:",i),c.status(500).send({error:i.message||"Failed to list project configs"})}}),t.post("/api/projects",async(l,c)=>{try{let{path:i}=l.body||{};if(!i||typeof i!="string"||!Ku(i)){c.status(400).send({error:"A valid absolute project path is required"});return}let u=Xu(i).replace(/[\\/]+$/,"")||i;if(await kd(u)){c.status(409).send({error:"Project is already configured"});return}await oa(u,{Router:{}});try{let g=await j();await ur(u,["claudeCode"],g)}catch(g){console.error("Failed to auto-enable ccr takeover for new project:",g)}let m=await lr(u);return{id:xd(u),path:u,configPath:Cd(u),Router:{},ccrTakeoverClients:m,ccrTakeover:m.length>0}}catch(i){console.error("Failed to add project config:",i),c.status(500).send({error:i.message||"Failed to add project config"})}}),t.put("/api/projects/:id",async(l,c)=>{try{let{id:i}=l.params,{Router:u}=l.body||{};if(!u||typeof u!="object"){c.status(400).send({error:"Router must be an object"});return}let d=await cr(i);if(!d){c.status(404).send({error:"Project config not found"});return}if(await oa(d.path,{Router:u}),Object.keys(u).length===0){let y=await j();await Td(d.path,y)}let g=await lr(d.path);return{id:i,path:d.path,configPath:d.configPath,Router:u,ccrTakeoverClients:g,ccrTakeover:g.length>0}}catch(i){console.error("Failed to update project config:",i),c.status(500).send({error:i.message||"Failed to update project config"})}}),t.put("/api/projects/:id/takeover",async(l,c)=>{try{let{id:i}=l.params,u=l.body||{},d;if(Array.isArray(u.clients))d=u.clients.filter(Rd);else if(typeof u.enabled=="boolean")d=u.enabled?["claudeCode"]:[];else{c.status(400).send({error:"clients (array) or enabled (boolean) is required"});return}let m=await cr(i);if(!m){c.status(404).send({error:"Project config not found"});return}let g=await j(),y=await ur(m.path,d,g);return{id:i,path:m.path,ccrTakeoverClients:y,ccrTakeover:y.length>0}}catch(i){console.error("Failed to update ccr takeover status:",i),c.status(500).send({error:i.message||"Failed to update ccr takeover status"})}}),t.delete("/api/projects/:id",async(l,c)=>{try{let{id:i}=l.params,u=await cr(i);if(!u){c.status(404).send({error:"Project config not found"});return}try{let d=await j();await ur(u.path,[],d)}catch(d){console.error("Failed to remove ccr takeover while deleting project:",d)}return await bd(u.path),{success:!0}}catch(i){console.error("Failed to delete project config:",i),c.status(500).send({error:i.message||"Failed to delete project config"})}});let r=typeof __dirname=="string"?__dirname:Yu(qu(import.meta.url)),s=ue(te(r,"index.html"))?r:ue(te(r,"..","index.html"))?te(r,".."):te(r,"..","dist");t.register(Zu,{root:s,prefix:"/ui/",maxAge:"1h"}),t.get("/ui",async(l,c)=>c.redirect("/ui/")),t.get("/api/logs/files",async(l,c)=>{try{let i=te(ir(),".claude-code-router","logs"),u=[];if(ue(i)){let d=Ki(i);for(let m of d)if(m.endsWith(".log")){let g=te(i,m),y=ed(g);u.push({name:m,path:g,size:y.size,lastModified:y.mtime.toISOString()})}u.sort((m,g)=>new Date(g.lastModified).getTime()-new Date(m.lastModified).getTime())}return u}catch(i){console.error("Failed to get log files:",i),c.status(500).send({error:"Failed to get log files"})}}),t.get("/api/logs",async(l,c)=>{try{let i=l.query.file,u;return i?u=i:u=te(ir(),".claude-code-router","logs","app.log"),ue(u)?Xi(u,"utf8").split(`
|
|
389
|
-
`).filter(g=>g.trim()):[]}catch(i){console.error("Failed to get logs:",i),c.status(500).send({error:"Failed to get logs"})}}),t.delete("/api/logs",async(l,c)=>{try{let i=l.query.file,u;return i?u=i:u=te(ir(),".claude-code-router","logs","app.log"),ue(u)&&td(u,"","utf8"),{success:!0,message:"Logs cleared successfully"}}catch(i){console.error("Failed to clear logs:",i),c.status(500).send({error:"Failed to clear logs"})}}),t.get("/api/debug-log",async()=>({enabled:xt()})),t.put("/api/debug-log",async l=>{let{enabled:c}=l.body;return zn(c),{enabled:xt()}}),t.get("/api/usage",async(l,c)=>{try{let i=l.query;return Zo({startTime:i.startDate,endTime:i.endDate,model:i.model,provider:i.provider,scenario:i.scenario,clientType:i.clientType,sessionId:i.sessionId,status:i.status,page:i.page?parseInt(i.page,10):void 0,pageSize:i.pageSize?parseInt(i.pageSize,10):void 0})}catch(i){console.error("Failed to query usage:",i),c.status(500).send({error:"Failed to query usage"})}}),t.get("/api/usage/summary",async(l,c)=>{try{let i=l.query;return ht(i.startDate,i.endDate,i.status)}catch(i){console.error("Failed to query usage summary:",i),c.status(500).send({error:"Failed to query usage summary"})}}),t.delete("/api/usage",async(l,c)=>{try{let i=l.query;return er(i.beforeDate),{success:!0,message:i.beforeDate?"Usage data cleared before "+i.beforeDate:"All usage data cleared"}}catch(i){console.error("Failed to clear usage:",i),c.status(500).send({error:"Failed to clear usage data"})}}),t.get("/api/providers/health",async(l,c)=>{try{return{states:U().getAllStates().map(d=>({provider:d.provider,model:d.model,status:d.status,failureCount:d.failureCount,successCount:d.successCount,lastFailureTime:d.lastFailureTime,lastError:d.lastError,rateLimitUntil:d.rateLimitUntil??null})),timestamp:new Date().toISOString()}}catch(i){console.error("Failed to get provider health:",i),c.status(500).send({error:"Failed to get provider health"})}}),t.post("/api/providers/probe",async(l,c)=>{try{let{providerName:i}=l.body;if(!i)return c.status(400),{error:"providerName is required"};let d=t._server?.activeProbeService;if(!d?.probeProviderManually)return c.status(503),{error:"Active probe service is not available"};let m=await d.probeProviderManually(i);return m&&vn(i,l.log),{provider:i,success:m,timestamp:new Date().toISOString()}}catch(i){console.error("Failed to probe provider:",i),c.status(500).send({error:i.message||"Failed to probe provider"})}}),t.post("/api/providers/probe-all",async(l,c)=>{try{let i=t._server,u=i?.activeProbeService;if(!u?.probeProviderManually)return c.status(503),{error:"Active probe service is not available"};let d=(i?.providerService?.getProviders?.()||[]).filter(g=>g?.name&&g.enabled!==!1),m=await Promise.all(d.map(async g=>{let y=await u.probeProviderManually(g.name);return y&&vn(g.name,l?.log),{provider:g.name,success:y}}));return{results:m,successCount:m.filter(g=>g.success).length,total:m.length,timestamp:new Date().toISOString()}}catch(i){console.error("Failed to probe all providers:",i),c.status(500).send({error:i.message||"Failed to probe all providers"})}}),t.get("/api/providers/quota",async(l,c)=>{try{let u=(await j()).Providers||[],d=Pd(u),m=new Map(d.map(p=>[p.provider,p])),g=Yn();for(let p of d){let f=g.find(_=>_.provider===p.provider);f&&f.limit!=null&&(p.limit5h=f.limit,p.used5h=f.limit-(f.remaining??0),f.reset&&(p.reset5h=new Date(f.reset*1e3).toISOString()))}let y=oo();for(let p of y){let f=m.get(p.provider);f||(f={provider:p.provider,used5h:0,used7d:0},d.push(f),m.set(p.provider,f)),typeof p.totalBalance=="number"?(f.limit7d=p.totalBalance,f.type7d=p.currency?"balance":"rateLimit",p.currency&&(f.currency=p.currency),typeof p.usedBalance=="number"?f.used7d=p.usedBalance:typeof p.remainingBalance=="number"?f.used7d=Math.max(0,p.totalBalance-p.remainingBalance):(f.used7d=0,f.limit7d=p.totalBalance)):typeof p.usedBalance=="number"&&(f.used7d=p.usedBalance),typeof p.usedDailyBalance=="number"&&(f.used5h=p.usedDailyBalance,f.type5h="rateLimit"),typeof p.limitDaily=="number"&&(f.limit5h=p.limitDaily,f.type5h="rateLimit"),typeof p.resetTime=="string"&&(p.limitDaily!==void 0?f.reset5h=p.resetTime:f.reset7d=p.resetTime),typeof p.resetTime7d=="string"&&(f.reset7d=p.resetTime7d)}return{quotas:d,timestamp:new Date().toISOString()}}catch(i){console.error("Failed to compute provider quota:",i),c.status(500).send({error:"Failed to compute provider quota"})}}),t.get("/api/presets",async(l,c)=>{try{let i=te(rd,"presets");if(!ue(i))return{presets:[]};let d=Ki(i,{withFileTypes:!0}).filter(g=>g.isDirectory()&&!g.name.startsWith(".")).map(g=>g.name),m=[];for(let g of d){let y=te(i,g);try{let p=te(y,"manifest.json"),f=Xi(p,"utf-8"),_=JSON.parse(f),{Providers:k,Router:h,PORT:b,HOST:x,API_TIMEOUT_MS:v,PROXY_URL:C,PROXY_GLOBAL_ENABLED:R,LOG:T,LOG_LEVEL:A,StatusLine:w,NON_INTERACTIVE_MODE:O,...P}=_;m.push({id:g,name:P.name||g,version:P.version||"1.0.0",description:P.description,author:P.author,homepage:P.homepage,repository:P.repository,license:P.license,keywords:P.keywords,ccrVersion:P.ccrVersion,source:P.source,sourceType:P.sourceType,checksum:P.checksum,installed:!0})}catch(p){console.error(`Failed to read preset ${g}:`,p)}}return{presets:m}}catch(i){console.error("Failed to get presets:",i),c.status(500).send({error:"Failed to get presets"})}}),t.get("/api/presets/:name",async(l,c)=>{try{let{name:i}=l.params,u=In(i);if(!ue(u)){c.status(404).send({error:"Preset not found"});return}let d=await ar(u);return{...qi(d),config:sd(d,u),userValues:d.userValues||{}}}catch(i){console.error("Failed to get preset:",i),c.status(500).send({error:i.message||"Failed to get preset"})}}),t.post("/api/presets/:name/apply",async(l,c)=>{try{let{name:i}=l.params,{secrets:u}=l.body,d=In(i);if(!ue(d)){c.status(404).send({error:"Preset not found"});return}let g={...await ar(d)};return u&&Object.keys(u).length>0&&(g.userValues={...g.userValues,...u}),await Zi(i,g),{success:!0,message:"Preset applied successfully"}}catch(i){console.error("Failed to apply preset:",i),c.status(500).send({error:i.message||"Failed to apply preset"})}}),t.delete("/api/presets/:name",async(l,c)=>{try{let{name:i}=l.params,u=In(i);if(!ue(u)){c.status(404).send({error:"Preset not found"});return}return nd(u,{recursive:!0,force:!0}),{success:!0,message:"Preset deleted successfully"}}catch(i){console.error("Failed to delete preset:",i),c.status(500).send({error:i.message||"Failed to delete preset"})}}),t.get("/api/presets/market",async(l,c)=>{try{return{presets:await cd()}}catch(i){console.error("Failed to get market presets:",i),c.status(500).send({error:i.message||"Failed to get market presets"})}}),t.post("/api/presets/install/github",async(l,c)=>{try{let{presetName:i}=l.body;if(!i){c.status(400).send({error:"Preset name is required"});return}let u=await ad(i);if(!u){c.status(400).send({error:"Preset not found in marketplace",message:`Preset '${i}' is not available in the official marketplace. Please check the available presets.`});return}if(!u.repo){c.status(400).send({error:"Invalid preset data",message:`Preset '${i}' does not have repository information`});return}let d=u.repo.match(/(?:github\.com[:/]|^)([^/]+)\/([^/\s#]+?)(?:\.git)?$/);if(!d){c.status(400).send({error:"Invalid GitHub repository URL"});return}let[,m,g]=d,y=u.name||i;if(await ea(y)){c.status(409).send({error:"Preset already installed",message:`Preset '${y}' is already installed. To update or reconfigure, please delete it first using the delete button.`,presetName:y});return}let p=`https://github.com/${m}/${g}/archive/refs/heads/main.zip`,f=await id(p),_=await a(f);if(await ea(y)){Yi(f),c.status(409).send({error:"Preset already installed",message:`Preset '${y}' was installed while downloading. Please try again.`,presetName:y});return}let k=In(y);await od(f,k);let h=await ar(k);return h.repository=u.repo,u.url&&(h.source=u.url),await Zi(y,h),Yi(f),{success:!0,presetName:y,preset:{..._.metadata,installed:!0}}}catch(i){console.error("Failed to install preset from GitHub:",i),c.status(500).send({error:i.message||"Failed to install preset from GitHub"})}});async function a(l){let c=new Sd(l),i=c.getEntry("manifest.json");if(i||(i=c.getEntries().find(m=>m.entryName.includes("manifest.json"))||null),!i)throw new Error("Invalid preset file: manifest.json not found");let u=JSON.parse(i.getData().toString("utf-8"));return qi(u)}return n}var sa=S(()=>{"use strict";et();ve();Se();Lt();gn();Z();We();ee();Rn();ut();yt();Qi();Vo()});function Ad(n){let e=n||"";return e.includes(",")&&(e=e.split(",").pop()||e),e.includes("/")&&(e=e.split("/").pop()||e),e.includes(":")&&(e=e.split(":")[0]),e.trim().toLowerCase()}function Od(n){let e=Ad(n);return[/claude/i,/gemini/i,/gpt-4o/i,/gpt-4\.1/i,/gpt-4-vision/i,/qwen.*vl/i,/glm-4v/i,/grok.*vision/i,/pixtral/i,/llava/i].some(o=>o.test(e))}function Ed(n){return n.some(e=>e.role==="user"&&Array.isArray(e.content)&&e.content.some(t=>t.type==="image"||t.type==="image_url"||Array.isArray(t?.content)&&t.content.some(o=>o.type==="image"||o.type==="image_url")))}var dr,Mn,pr,ia,aa=S(()=>{"use strict";dr=class{cache=new Map;maxSize;ttl;constructor(e=100,t=300*1e3){this.maxSize=e,this.ttl=t}evictExpired(){let e=Date.now();for(let[t,o]of this.cache)e-o.timestamp>this.ttl&&this.cache.delete(t)}trim(){if(this.cache.size<=this.maxSize)return;let e=[...this.cache.keys()].slice(0,this.cache.size-this.maxSize);for(let t of e)this.cache.delete(t)}storeImage(e,t){this.hasImage(e)||(this.evictExpired(),this.cache.set(e,{source:t,timestamp:Date.now()}),this.trim())}getImage(e){let t=this.cache.get(e);return t?Date.now()-t.timestamp>this.ttl?(this.cache.delete(e),null):t.source:null}hasImage(e){let t=this.cache.get(e);return t?Date.now()-t.timestamp>this.ttl?(this.cache.delete(e),!1):!0:!1}clear(){this.cache.clear()}size(){return this.evictExpired(),this.cache.size}},Mn=new dr;pr=class{name="image";tools;constructor(){this.tools=new Map,this.appendTools()}shouldHandle(e,t){if(!t.Router.image||e.body.model===t.Router.image||!Ed(e.body.messages))return!1;let r=e.body.messages[e.body.messages.length-1];if(!t.forceUseImageAgent){if(Od(e.body.model))return!1;if(e.body.model=t.Router.image,r.role==="user"&&Array.isArray(r.content)){let s=[];r.content.filter(a=>a.type==="tool_result").forEach(a=>{Array.isArray(a.content)&&(a.content.forEach(l=>{l.type==="image"&&s.push(l)}),a.content="read image successfully")}),r.content.push(...s)}return!1}return!0}appendTools(){this.tools.set("analyzeImage",{name:"analyzeImage",description:"Analyse image or images by ID and extract information such as OCR text, objects, layout, colors, or safety signals.",input_schema:{type:"object",properties:{imageId:{type:"array",description:"an array of IDs to analyse",items:{type:"string"}},task:{type:"string",description:"Details of task to perform on the image.The more detailed, the better"},regions:{type:"array",description:"Optional regions of interest within the image",items:{type:"object",properties:{name:{type:"string",description:"Optional label for the region"},x:{type:"number",description:"X coordinate"},y:{type:"number",description:"Y coordinate"},w:{type:"number",description:"Width of the region"},h:{type:"number",description:"Height of the region"},units:{type:"string",enum:["px","pct"],description:"Units for coordinates and size"}},required:["x","y","w","h","units"]}}},required:["imageId","task"]},handler:async(e,t)=>{let o=[],r;if(e.imageId){if(Array.isArray(e.imageId))e.imageId.forEach(l=>{let c=Mn.getImage(`${t.req.id}_Image#${l}`);c&&o.push({type:"image",source:c})});else{let l=Mn.getImage(`${t.req.id}_Image#${e.imageId}`);l&&o.push({type:"image",source:l})}r=e.imageId,delete e.imageId}let s=t.req.body.messages[t.req.body.messages.length-1];if(s.role==="user"&&Array.isArray(s.content)){let l=s.content.filter(c=>c.type==="text"&&!c.text.includes("This is an image, if you need to view or analyze it, you need to extract the imageId"));o.push(...l)}Object.keys(e).length>0&&o.push({type:"text",text:JSON.stringify(e)});let a=await fetch(`http://127.0.0.1:${t.config.PORT||3456}/v1/messages`,{method:"POST",headers:{"x-api-key":t.config.APIKEY,"content-type":"application/json"},body:JSON.stringify({model:t.config.Router.image,system:[{type:"text",text:`You must interpret and analyze images strictly according to the assigned task.
|
|
387
|
+
`)}function au(n,e,t){if(n<=0||e==null||!Number.isFinite(e))return null;let o=t!=null&&Number.isFinite(t)?t:0,r=Math.max((e-o)/1e3,ql);return Math.round(n/r)}function An(n){let e=Number(n.outputTokens)||0,t=Number(n.durationMs),o=Number.isFinite(t)?t:null,r=be(n.ttft);return{...n,ttft:r,tokensPerSecond:au(e,o,r)}}function pe(n){return typeof n=="string"?n:n==null?"":String(n)}function De(n){if(n==null)return;let e=String(n);return e.length>0?e:void 0}function ft(n){let e=Number(n);return Number.isFinite(e)?e:0}function hi(n){return n==="success"?"success":"error"}function yi(n){let e=An(n);return{id:pe(e.id),timestamp:pe(e.timestamp),session_id:pe(e.sessionId),provider:pe(e.provider),original_model:pe(e.originalModel),model:pe(e.model),upstream_model:De(e.upstreamModel)??null,model_family:pe(e.modelFamily),scenario_type:pe(e.scenarioType),client_type:De(e.clientType)??null,codex_account_id:De(e.codexAccountId)??null,codex_account_email:De(e.codexAccountEmail)??null,stream:e.stream?1:0,input_tokens:Math.trunc(ft(e.inputTokens)),output_tokens:Math.trunc(ft(e.outputTokens)),cache_read_input_tokens:Math.trunc(ft(e.cacheReadInputTokens)),cache_creation_input_tokens:Math.trunc(ft(e.cacheCreationInputTokens)),ttft:be(e.ttft),tokens_per_second:be(e.tokensPerSecond),duration_ms:Math.trunc(ft(e.durationMs)),status:hi(e.status),error_message:De(e.errorMessage)??null,response_body:De(e.responseBody)??null}}function _i(n){return An({id:n.id,timestamp:n.timestamp,sessionId:n.session_id,provider:n.provider,originalModel:n.original_model,model:n.model,upstreamModel:n.upstream_model??void 0,modelFamily:n.model_family,scenarioType:n.scenario_type,clientType:n.client_type??void 0,codexAccountId:n.codex_account_id??void 0,codexAccountEmail:n.codex_account_email??void 0,stream:n.stream===1,inputTokens:n.input_tokens,outputTokens:n.output_tokens,cacheReadInputTokens:n.cache_read_input_tokens,cacheCreationInputTokens:n.cache_creation_input_tokens,ttft:n.ttft,tokensPerSecond:n.tokens_per_second,durationMs:n.duration_ms,status:hi(n.status),errorMessage:n.error_message??void 0,responseBody:n.response_body??void 0})}function cu(){return new Date(Date.now()-Zl*24*60*60*1e3).toISOString()}function ki(n,e=!1){let t=Date.now();!e&&t-gi<eu||(n.prepare("DELETE FROM usage_records WHERE timestamp < ?").run(cu()),gi=t)}function bi(n){let e=[],t=[];return n.startTime&&(e.push("timestamp >= ?"),t.push(n.startTime)),n.endTime&&(e.push("timestamp <= ?"),t.push(n.endTime)),n.model&&(e.push("model = ?"),t.push(n.model)),n.provider&&(e.push("provider = ?"),t.push(n.provider)),n.scenario&&(e.push("scenario_type = ?"),t.push(n.scenario)),n.clientType&&(n.clientType==="unknown"?(e.push("(client_type IS NULL OR client_type = '' OR client_type = ?)"),t.push(n.clientType)):(e.push("client_type = ?"),t.push(n.clientType))),n.sessionId&&(e.push("session_id = ?"),t.push(n.sessionId)),n.status&&(e.push("status = ?"),t.push(n.status)),{sql:e.length>0?`WHERE ${e.join(" AND ")}`:"",params:t}}function xi(n,e){let t=bi(e);return n.prepare(`SELECT * FROM usage_records ${t.sql}`).all(...t.params).map(_i)}function Ci(n){let e={totalRequests:n.length,successCount:0,errorCount:0,totalInputTokens:0,totalOutputTokens:0,totalCacheReadInputTokens:0,totalCacheCreationInputTokens:0,avgTtft:null,avgTokensPerSecond:null,byModel:{},byProvider:{},byScenario:{},byFamily:{},byDay:{},byClient:{}},t=0,o=0,r=0,s=0;for(let a of n){let l=a.status==="success";l?e.successCount++:e.errorCount++;let c=l&&a.inputTokens||0,i=l&&a.outputTokens||0,u=l&&a.cacheReadInputTokens||0,d=l&&a.cacheCreationInputTokens||0;e.totalInputTokens+=c,e.totalOutputTokens+=i,e.totalCacheReadInputTokens+=u,e.totalCacheCreationInputTokens+=d,l&&a.ttft!=null&&(t+=a.ttft,o++),l&&a.tokensPerSecond!=null&&(r+=a.tokensPerSecond,s++);let m=a.timestamp.slice(0,10);if(je(e.byModel,a.model,c,i,u,d),je(e.byProvider,a.provider,c,i,u,d),je(e.byScenario,a.scenarioType,c,i,u,d),a.modelFamily){let g=`${a.modelFamily}/${a.scenarioType}`;je(e.byFamily,g,c,i,u,d)}je(e.byDay,m,c,i,u,d),je(e.byClient,a.clientType||"unknown",c,i,u,d)}return o>0&&(e.avgTtft=Math.round(t/o)),s>0&&(e.avgTokensPerSecond=Math.round(r/s)),e}function je(n,e,t,o,r,s){n[e]||(n[e]={count:0,inputTokens:0,outputTokens:0,cacheReadInputTokens:0,cacheCreationInputTokens:0}),n[e].count++,n[e].inputTokens+=t,n[e].outputTokens+=o,n[e].cacheReadInputTokens+=r,n[e].cacheCreationInputTokens+=s}function gt(n){let e=mt(),t=An(n);qo.run(yi(t)),ki(e)}function Zo(n){let e=mt(),t=bi(n),o=Number.isFinite(n.page)&&n.page>0?Math.floor(n.page):1,r=Number.isFinite(n.pageSize)&&n.pageSize>0?Math.floor(n.pageSize):50,s=(o-1)*r,a=e.prepare(`SELECT COUNT(*) AS count FROM usage_records ${t.sql}`).get(...t.params),l=e.prepare(`SELECT * FROM usage_records ${t.sql} ORDER BY timestamp DESC LIMIT ? OFFSET ?`).all(...t.params,r,s),c=Ci(xi(e,n));return{records:l.map(_i),summary:c,total:a.count,page:o,pageSize:r}}function ht(n,e,t){let o=mt();return Ci(xi(o,{startTime:n,endTime:e,status:t}))}function er(n){let e=mt();if(!n){e.prepare("DELETE FROM usage_records").run();return}e.prepare("DELETE FROM usage_records WHERE timestamp < ?").run(n)}function lu(){fe&&(fe.pragma("wal_checkpoint(TRUNCATE)"),fe.close(),fe=null,qo=null)}function be(n){if(n==null)return null;if(typeof n=="number")return n;let e=parseFloat(String(n));return isNaN(e)?null:e}function tr(n){let e=ze(Kl(),"claude-code-router"),t=ze(e,`session-${n}.json`);if(Yo(t))try{let o=Xo(t,"utf-8"),r=JSON.parse(o);return{ttft:be(r.timeToFirstToken),tokensPerSecond:be(r.tokensPerSecond)}}catch{}try{let o=Vl(e),r=new RegExp(`^session-${n}-\\d+\\.json$`),s=o.filter(a=>r.test(a));if(s.length>0){let a=s.sort().reverse(),l=ze(e,a[0]);try{let c=Xo(l,"utf-8"),i=JSON.parse(c);return{ttft:be(i.timeToFirstToken),tokensPerSecond:be(i.tokensPerSecond)}}catch{return{ttft:null,tokensPerSecond:null}}}}catch{}return{ttft:null,tokensPerSecond:null}}function uu(n,e,t){return mt().prepare("SELECT MIN(timestamp) AS timestamp FROM usage_records WHERE provider = ? AND timestamp >= ? AND timestamp <= ?").get(n,e,t)?.timestamp??void 0}var Pn,Yl,Ko,ql,Zl,eu,mi,fe,qo,gi,yt=S(()=>{"use strict";Pn=ze(Ql(),".claude-code-router","data"),Yl=ze(Pn,"usage.sqlite"),Ko=ze(Pn,"usage.jsonl"),ql=1,Zl=180,eu=3600*1e3,mi="legacy_usage_jsonl_migrated_at",fe=null,qo=null,gi=0});import{existsSync as du}from"fs";import{homedir as pu}from"os";import{join as fu}from"path";import{writeFile as mu}from"fs/promises";async function vi(){let n=pu(),e=fu(n,".claude.json");if(!du(e)){let o={numStartups:184,autoUpdaterStatus:"enabled",userID:Array.from({length:64},()=>Math.random().toString(16)[2]).join(""),hasCompletedOnboarding:!0,lastOnboardingVersion:"1.0.17",projects:{}};await mu(e,JSON.stringify(o,null,2))}}var Ri=S(()=>{"use strict"});import{existsSync as gu,readFileSync as hu}from"fs";import{join as yu}from"path";import{HOME_DIR as _u,getActiveCodexAccount as Pi,listCodexAccounts as ku,markActiveCodexAccountLimitedAndSwitch as Ai,refreshDueCodexAccounts as bu}from"@wengine-ai/claude-code-router-shared";function xu(n){let e=n.Clients?.codex?.autoSwitchUsageThreshold;return typeof e=="number"&&Number.isFinite(e)?Math.min(100,Math.max(1,e)):95}function Cu(n){try{let e=yu(_u,"codex-accounts",`${n}.auth.json`);if(!gu(e))return{};let t=JSON.parse(hu(e,"utf8"));return{accessToken:t?.tokens?.access_token,chatGptAccountId:t?.tokens?.account_id||n}}catch{return{}}}function Tu(n){let e=n?.rate_limit;if(!e)return null;let t=e.primary_window,o=e.secondary_window;return{used5h:typeof t?.used_percent=="number"?t.used_percent:void 0,used7d:typeof o?.used_percent=="number"?o.used_percent:void 0,resetAfter5h:typeof t?.reset_after_seconds=="number"?t.reset_after_seconds:void 0,resetAfter7d:typeof o?.reset_after_seconds=="number"?o.reset_after_seconds:void 0}}async function vu(n){let{accessToken:e,chatGptAccountId:t}=Cu(n);if(!e)return null;let o={Authorization:`Bearer ${e}`,"ChatGPT-Account-Id":t||n,originator:"codex_cli_rs",Accept:"application/json","Accept-Encoding":"gzip, deflate","User-Agent":"codex_cli_rs/0.0.0"},r=["https://chatgpt.com/backend-api/wham/usage","https://chatgpt.com/backend-api/codex/usage"];for(let s of r)try{let a=await fetch(s,{headers:o,signal:AbortSignal.timeout(15e3)});if(!a.ok)continue;let l=Tu(await a.json());if(l)return l}catch{}return null}function Ru(n,e){let t=typeof n.used7d=="number"&&n.used7d>=e,o=typeof n.used5h=="number"&&n.used5h>=e;return t?{window:"7d",used:n.used7d,retryAfterSeconds:n.resetAfter7d}:o?{window:"5h",used:n.used5h,retryAfterSeconds:n.resetAfter5h}:null}async function wu(){try{let n=await j(),e=Pi(n);return{id:e?.id,email:e?.email}}catch{return{}}}async function Oi(){try{let n=await j();if((n.Clients?.codex||{}).autoSwitchAccounts===!1)return;let t=xu(n),o=Math.max(1,ku(n).accounts.length);for(let r=0;r<o;r+=1){let s=Pi(n);if(!s?.id)return;let a=await vu(s.id);if(!a)return;let l=Ru(a,t);if(!l)return;let c=`Codex ${l.window} usage reached ${Math.round(l.used)}% (auto-switch threshold ${t}%)`,i=Ai(n,c,l.retryAfterSeconds);if(await Z(i.config),!i.switchedAccount){console.warn(`[Codex] ${c}; no available Codex account could be switched to`);return}console.warn(`[Codex] ${c}; switched account to ${i.switchedAccount.email||i.switchedAccount.id}`),n=i.config}}catch(n){console.error("Failed to auto-switch Codex account before usage limit:",n)}}async function On(n){try{let e=await j();if((e.Clients?.codex||{}).autoSwitchAccounts===!1)return;let o=Ai(e,n);await Z(o.config),o.switchedAccount?console.warn(`[Codex] Rate limit detected; switched account to ${o.switchedAccount.email||o.switchedAccount.id}`):console.warn("[Codex] Rate limit detected, but no available Codex account could be switched to")}catch(e){console.error("Failed to auto-switch Codex account after rate limit:",e)}}async function Si(){try{let n=await j();if(n.Clients?.codex?.autoRefreshTokens===!1)return;let e=await bu(n);for(let t of e)t.refreshed?console.log(`[Codex] Refreshed tokens for account ${t.label} (${t.id})`):console.warn(`[Codex] Failed to refresh tokens for account ${t.label} (${t.id}): ${t.error}`)}catch(n){console.error("[Codex] Token refresh cycle failed:",n)}}function Ei(){if(wi)return;wi=!0,setTimeout(()=>void Si(),6e4).unref(),setInterval(()=>void Si(),Su).unref()}function En(n,e){return n===429||!!(e&&/rate[\s_]limit|too many|限流|频率限制|qps_limit|token_limit|quota exhausted|usage limit|limit reached/i.test(e))}async function Ii(){return wu()}var Su,wi,nr=S(()=>{"use strict";ut();Su=1800*1e3,wi=!1});import{existsSync as Pu,readdirSync as Au,statSync as Ou,unlinkSync as Eu}from"fs";import{join as Mi}from"path";import{HOME_DIR as Iu}from"@wengine-ai/claude-code-router-shared";function Ni(n=Mi(Iu,"logs")){try{if(!Pu(n))return;let e=Date.now()-$u;for(let t of Au(n)){if(!/^ccr-.*\.log$/.test(t))continue;let o=Mi(n,t),r=Ou(o);r.isFile()&&r.mtime.getTime()<e&&Eu(o)}}catch(e){console.warn("Failed to prune old server log files:",e)}}function Li(){$i||($i=!0,Ni(),setInterval(Ni,Nu).unref())}var Mu,$u,Nu,$i,Fi=S(()=>{"use strict";Mu=7,$u=Mu*24*60*60*1e3,Nu=1440*60*1e3,$i=!1});async function Ui(n,e){let t=e.plugins||e.Plugins||[];for(let o of t){let{name:r,enabled:s=!1,options:a={}}=o;switch(r){case"token-speed":ot.registerPlugin(_n,{enabled:s,outputHandlers:[{type:"temp-file",enabled:!0,config:{subdirectory:"claude-code-router",extension:"json",includeTimestamp:!0,prefix:"session"}}],...a});break;default:console.warn(`Unknown plugin: ${r}`);break}}await ot.enablePlugins(n)}var Di=S(()=>{"use strict";zo()});import{existsSync as zi,mkdirSync as Lu,readFileSync as Hi,writeFileSync as Fu}from"fs";import{join as sr}from"path";import{HOME_DIR as Ji,listCodexAccounts as Uu}from"@wengine-ai/claude-code-router-shared";function ji(n){if(!(typeof n!="number"||!Number.isFinite(n)))return new Date(n*1e3).toISOString()}function Wi(){if(!zi(rr))return{};try{let n=JSON.parse(Hi(rr,"utf8"));return!n||typeof n!="object"||Array.isArray(n)?{}:n}catch{return{}}}function Gi(n){Lu(Bi,{recursive:!0}),Fu(rr,`${JSON.stringify(n,null,2)}
|
|
388
|
+
`,"utf8")}function zu(n,e){let t=!1,o={};for(let[r,s]of Object.entries(n))e.has(r)?o[r]=s:t=!0;return t&&Gi(o),t?o:n}function Hu(n,e){if(!n?.fetchedAt)return!1;let t=Date.parse(n.fetchedAt),o=e?Du:ju;return Number.isFinite(t)&&Date.now()-t<o}function Ju(n){let e=n?.rate_limit;if(!e)return null;let t=e.primary_window,o=e.secondary_window,r={planType:typeof n.plan_type=="string"?n.plan_type:void 0,rateLimitReachedType:typeof n.rate_limit_reached_type?.type=="string"?n.rate_limit_reached_type.type:null};return typeof t?.used_percent=="number"&&(r.used5h=t.used_percent,r.reset5h=ji(t.reset_at)),typeof o?.used_percent=="number"&&(r.used7d=o.used_percent,r.reset7d=ji(o.reset_at)),r.used5h!==void 0||r.used7d!==void 0?r:null}function Bu(n){let e=sr(Ji,"codex-accounts",`${n}.auth.json`);if(!zi(e))return null;try{return JSON.parse(Hi(e,"utf8"))}catch{return null}}async function Wu(n){let e=Bu(n),t=e?.tokens?.access_token,o=e?.tokens?.account_id||n;if(!t)return null;let r={Authorization:`Bearer ${t}`,"ChatGPT-Account-Id":o,originator:"codex_cli_rs",Accept:"application/json","Accept-Encoding":"gzip, deflate","User-Agent":"codex_cli_rs/0.0.0"},s=["https://chatgpt.com/backend-api/wham/usage","https://chatgpt.com/backend-api/codex/usage"];for(let a of s)try{let l=await fetch(a,{headers:r,signal:AbortSignal.timeout(15e3)});if(!l.ok)continue;let c=await l.json(),i=Ju(c);if(i)return i}catch{}return null}function Gu(n,e){return e?{...n,plan:e.planType||n.plan,limitedWindow:e.rateLimitReachedType?n.limitedWindow||"unknown":n.limitedWindow,usage:{used5h:e.used5h??0,used7d:e.used7d??0,limit5h:e.used5h!==void 0?100:void 0,limit7d:e.used7d!==void 0?100:void 0,reset5h:e.reset5h,reset7d:e.reset7d}}:n}function Vu(n){for(let e of n){if(or.has(e))continue;let t=(async()=>{let o=await Wu(e);if(!o)return;let r=Wi();r[e]={...o,fetchedAt:new Date().toISOString()},Gi(r)})().catch(o=>{console.error(`Failed to refresh Codex usage for ${e}:`,o)}).finally(()=>{or.delete(e)});or.set(e,t)}}async function He(n){let e=Uu(n),t=new Set(e.accounts.map(a=>a.id)),o=zu(Wi(),t),r=e.accounts.filter(a=>!Hu(o[a.id],a.active)).map(a=>a.id);r.length>0&&Vu(r);let s=e.accounts.map(a=>Gu(a,o[a.id]));return{...e,accounts:s}}var Bi,rr,Du,ju,or,Vi=S(()=>{"use strict";Bi=sr(Ji,"data"),rr=sr(Bi,"codex-usage-cache.json"),Du=60*1e3,ju=1800*1e3,or=new Map});import{join as re,isAbsolute as Qu,normalize as Ku,dirname as Xu}from"path";import{fileURLToPath as Yu}from"url";import qu from"@fastify/static";import{readdirSync as Qi,statSync as Zu,readFileSync as Ki,writeFileSync as ed,existsSync as ue,unlinkSync as Xi,rmSync as td}from"fs";import{homedir as ir}from"os";import{getPresetDir as In,readManifestFromDir as ar,manifestToPresetFile as Yi,saveManifest as qi,isPresetInstalled as Zi,extractPreset as nd,HOME_DIR as od,loadConfigFromManifest as rd,downloadPresetToTemp as sd,findMarketPresetByName as id,getMarketPresets as ad,applyClientSelection as cd,activateCodexAccount as ld,deleteCodexAccount as ud,disableClient as dd,enableClient as pd,exportCodexRefreshToken as ea,importCodexAccountFromRefreshToken as fd,importCurrentCodexAccount as md,isClientId as gd,listClientStatuses as ta,restoreClient as hd,listProjectConfigs as yd,readProjectConfigById as cr,readProjectConfig as _d,writeProjectConfig as na,deleteProjectConfig as kd,getClaudeProjectId as bd,getProjectConfigPath as xd,refreshProjectTakeovers as Cd,syncGlobalProjectTakeovers as Td,getProjectTakeoverClients as lr,setProjectTakeover as ur,isProjectTakeoverClient as vd}from"@wengine-ai/claude-code-router-shared";import Rd from"@fastify/multipart";import wd from"adm-zip";function Sd(n){let e=new Date().toISOString(),t=new Date(Date.now()-300*60*1e3).toISOString(),o=new Date(Date.now()-10080*60*1e3).toISOString(),r=ht(t,e),s=ht(o,e),a=[],l=new Set;for(let c of n||[])c&&c.name&&l.add(c.name);for(let c of Object.keys(r.byProvider||{}))l.add(c);for(let c of Object.keys(s.byProvider||{}))l.add(c);for(let c of l){let i=r.byProvider[c]||{inputTokens:0,outputTokens:0},u=s.byProvider[c]||{inputTokens:0,outputTokens:0},d=(i.inputTokens||0)+(i.outputTokens||0),m=(u.inputTokens||0)+(u.outputTokens||0),g,y,p=(n||[]).find(f=>f&&f.name===c);p&&p.quota&&(g=p.quota.limit5h,y=p.quota.limit7d),a.push({provider:c,used5h:d,used7d:m,limit5h:g,limit7d:y})}return a}async function oa(n,e){let t=n.app;Ve(),Qe(),t.register(Rd,{limits:{fileSize:50*1024*1024}}),t.get("/v1/models",async()=>{let l=wn(e);return{object:"list",data:l,first_id:l[0]?.id||null,last_id:l[l.length-1]?.id||null,has_more:!1}}),t.get("/v1/models/:modelId",async(l,c)=>{let i=decodeURIComponent(l.params.modelId),u=wn(e).find(d=>d.id===i);return u||(c.status(404),{type:"error",error:{type:"not_found_error",message:`Model not found: ${i}`}})}),t.post("/v1/messages/count_tokens",async(l,c)=>{let{messages:i,tools:u,system:d,model:m}=l.body,g=t._server.tokenizerService;if(m&&m.includes(",")&&g)try{let[p,f]=m.split(",");l.log?.info(`Looking up tokenizer for provider: ${p}, model: ${f}`);let _=g.getTokenizerConfigForModel(p,f);_?l.log?.info(`Using tokenizer config: ${JSON.stringify(_)}`):l.log?.warn(`No tokenizer config found for ${p},${f}, using default tiktoken`);let k=await g.countTokens({messages:i,system:d,tools:u},_,p);return{input_tokens:k.tokenCount,tokenizer:k.tokenizerUsed}}catch(p){l.log?.error(`Error using configured tokenizer: ${p.message}`),l.log?.error(p.stack)}else m?m.includes(",")?g||l.log?.warn("TokenizerService not available, using default tiktoken"):l.log?.info(`Model "${m}" does not contain comma, using default tiktoken`):l.log?.info("No model specified, using default tiktoken");return{input_tokens:It(i,d,u)}}),t.get("/api/config",async(l,c)=>await Jo()),t.get("/api/transformers",async(l,c)=>{let i=t._server.transformerService.getAllTransformers();return{transformers:Array.from(i.entries()).map(([d,m])=>({name:d,endpoint:m.endPoint||null}))}}),t.post("/api/config",async(l,c)=>{let i=l.body,u=yr(i||{});if(u.length>0)return c.status(400),{success:!1,error:"Invalid proxy URL",message:u.map(g=>`${g.key}: ${g.error}`).join("; "),proxyErrors:u};let d=await xn();d&&console.log(`Backed up existing configuration file to ${d}`),await Z(i);let m;try{m=await Td(i),m.failed.length>0&&t.log?.warn?.({projectTakeoverSync:m},"Config saved but some global project takeovers failed to sync")}catch(g){t.log?.warn?.(`Config saved but global project takeover sync failed: ${g?.message||g}`)}try{let g=t._server;if(g?.configService){g.configService.reload();let y=i?.Providers||i?.providers;if(Array.isArray(y)&&g.configService.set("providers",y),le&&g.transformerService&&(g.providerService=new le(g.configService,g.transformerService,t.log)),dt(i,t.log),Ne&&gn){try{gn()}catch{}let p={enabled:g.configService.get("ACTIVE_PROBE_ENABLED")??!0,quotaProbeIntervalMinutes:g.configService.get("QUOTA_PROBE_INTERVAL_MINUTES")??10,probeTimeoutMs:g.configService.get("PROBE_TIMEOUT_MS")??15e3,initialDelayMs:g.configService.get("PROBE_INITIAL_DELAY_MS")??5e3,excludeProviders:g.configService.get("EXCLUDE_PROBE_PROVIDERS")??[]};g.activeProbeService=Ne(()=>g.providerService.getProviders(),p,f=>ie(g.configService,f),t.log,f=>g.configService.get(f))}}}catch(g){t.log?.warn?.(`Config saved but runtime reload failed: ${g?.message||g}`)}return{success:!0,message:"Config saved successfully",projectTakeoverSync:m}}),t.get("/api/clients",async(l,c)=>{try{let i=await j();return{clients:ta(i)}}catch(i){console.error("Failed to get client integrations:",i),c.status(500).send({error:i.message||"Failed to get client integrations"})}}),t.post("/api/clients/apply",async(l,c)=>{try{let i=l.body,u=Array.isArray(i?.enabled)?i.enabled:[],d=await j(),m=cd(d,u);return await Z(m.config),m}catch(i){console.error("Failed to apply client integrations:",i),c.status(500).send({error:i.message||"Failed to apply client integrations"})}});async function o(l,c,i){try{let{id:u}=l.params;if(!gd(u)){c.status(404).send({error:`Unknown client: ${u}`});return}let d=await j(),m=i==="enable"?pd(d,u):i==="restore"?hd(d,u):dd(d,u);return await Z(d),{success:m.success,result:m,results:[m],clients:ta(d),config:d}}catch(u){console.error(`Failed to ${i} client integration:`,u),c.status(500).send({error:u.message||`Failed to ${i} client integration`})}}t.post("/api/clients/:id/enable",async(l,c)=>o(l,c,"enable")),t.post("/api/clients/:id/disable",async(l,c)=>o(l,c,"disable")),t.post("/api/clients/:id/restore",async(l,c)=>o(l,c,"restore")),t.get("/api/clients/codex/accounts",async(l,c)=>{try{let i=await j();return await He(i)}catch(i){console.error("Failed to get Codex accounts:",i),c.status(500).send({error:i.message||"Failed to get Codex accounts"})}}),t.post("/api/clients/codex/accounts/import-current",async(l,c)=>{try{let i=l.body,u=await j(),d=md(u,i?.label);await Z(d.config);let m=await He(d.config);return{...d,...m}}catch(i){console.error("Failed to import current Codex account:",i),c.status(500).send({error:i.message||"Failed to import current Codex account"})}}),t.post("/api/clients/codex/accounts/import-rt",async(l,c)=>{try{let i=l.body,u=await j(),d=await fd(u,i?.refreshToken||"",i?.label);await Z(d.config);let m=await He(d.config);return{...d,...m}}catch(i){console.error("Failed to import Codex account from refresh token:",i),c.status(500).send({error:i.message||"Failed to import Codex account from refresh token"})}}),t.post("/api/clients/codex/accounts/:accountId/activate",async(l,c)=>{try{let{accountId:i}=l.params,u=await j(),d=ld(u,i);await Z(d.config);let m=await He(d.config);return{...d,...m}}catch(i){console.error("Failed to activate Codex account:",i),c.status(500).send({error:i.message||"Failed to activate Codex account"})}}),t.post("/api/clients/codex/accounts/:accountId/export-rt",async(l,c)=>{try{let{accountId:i}=l.params,u=await j();return ea(u,i)}catch(i){console.error("Failed to export Codex refresh token:",i),c.status(500).send({error:i.message||"Failed to export Codex refresh token"})}}),t.post("/api/clients/codex/accounts/export-rt",async(l,c)=>{try{let i=await j();return ea(i)}catch(i){console.error("Failed to export active Codex refresh token:",i),c.status(500).send({error:i.message||"Failed to export active Codex refresh token"})}}),t.delete("/api/clients/codex/accounts/:accountId",async(l,c)=>{try{let{accountId:i}=l.params,u=await j(),d=ud(u,i);await Z(d.config);let m=await He(d.config);return{...d,...m}}catch(i){console.error("Failed to delete Codex account:",i),c.status(500).send({error:i.message||"Failed to delete Codex account"})}}),t.get("/api/projects",async(l,c)=>{try{let i=await yd();return{projects:await Promise.all(i.map(async d=>{let m=await lr(d.path);return{...d,ccrTakeoverClients:m,ccrTakeover:m.length>0}}))}}catch(i){console.error("Failed to list project configs:",i),c.status(500).send({error:i.message||"Failed to list project configs"})}}),t.post("/api/projects",async(l,c)=>{try{let{path:i}=l.body||{};if(!i||typeof i!="string"||!Qu(i)){c.status(400).send({error:"A valid absolute project path is required"});return}let u=Ku(i).replace(/[\\/]+$/,"")||i;if(await _d(u)){c.status(409).send({error:"Project is already configured"});return}await na(u,{Router:{}});try{let g=await j();await ur(u,["claudeCode"],g)}catch(g){console.error("Failed to auto-enable ccr takeover for new project:",g)}let m=await lr(u);return{id:bd(u),path:u,configPath:xd(u),Router:{},ccrTakeoverClients:m,ccrTakeover:m.length>0}}catch(i){console.error("Failed to add project config:",i),c.status(500).send({error:i.message||"Failed to add project config"})}}),t.put("/api/projects/:id",async(l,c)=>{try{let{id:i}=l.params,{Router:u}=l.body||{};if(!u||typeof u!="object"){c.status(400).send({error:"Router must be an object"});return}let d=await cr(i);if(!d){c.status(404).send({error:"Project config not found"});return}if(await na(d.path,{Router:u}),Object.keys(u).length===0){let y=await j();await Cd(d.path,y)}let g=await lr(d.path);return{id:i,path:d.path,configPath:d.configPath,Router:u,ccrTakeoverClients:g,ccrTakeover:g.length>0}}catch(i){console.error("Failed to update project config:",i),c.status(500).send({error:i.message||"Failed to update project config"})}}),t.put("/api/projects/:id/takeover",async(l,c)=>{try{let{id:i}=l.params,u=l.body||{},d;if(Array.isArray(u.clients))d=u.clients.filter(vd);else if(typeof u.enabled=="boolean")d=u.enabled?["claudeCode"]:[];else{c.status(400).send({error:"clients (array) or enabled (boolean) is required"});return}let m=await cr(i);if(!m){c.status(404).send({error:"Project config not found"});return}let g=await j(),y=await ur(m.path,d,g);return{id:i,path:m.path,ccrTakeoverClients:y,ccrTakeover:y.length>0}}catch(i){console.error("Failed to update ccr takeover status:",i),c.status(500).send({error:i.message||"Failed to update ccr takeover status"})}}),t.delete("/api/projects/:id",async(l,c)=>{try{let{id:i}=l.params,u=await cr(i);if(!u){c.status(404).send({error:"Project config not found"});return}try{let d=await j();await ur(u.path,[],d)}catch(d){console.error("Failed to remove ccr takeover while deleting project:",d)}return await kd(u.path),{success:!0}}catch(i){console.error("Failed to delete project config:",i),c.status(500).send({error:i.message||"Failed to delete project config"})}});let r=typeof __dirname=="string"?__dirname:Xu(Yu(import.meta.url)),s=ue(re(r,"index.html"))?r:ue(re(r,"..","index.html"))?re(r,".."):re(r,"..","dist");t.register(qu,{root:s,prefix:"/ui/",maxAge:"1h"}),t.get("/ui",async(l,c)=>c.redirect("/ui/")),t.get("/api/logs/files",async(l,c)=>{try{let i=re(ir(),".claude-code-router","logs"),u=[];if(ue(i)){let d=Qi(i);for(let m of d)if(m.endsWith(".log")){let g=re(i,m),y=Zu(g);u.push({name:m,path:g,size:y.size,lastModified:y.mtime.toISOString()})}u.sort((m,g)=>new Date(g.lastModified).getTime()-new Date(m.lastModified).getTime())}return u}catch(i){console.error("Failed to get log files:",i),c.status(500).send({error:"Failed to get log files"})}}),t.get("/api/logs",async(l,c)=>{try{let i=l.query.file,u;return i?u=i:u=re(ir(),".claude-code-router","logs","app.log"),ue(u)?Ki(u,"utf8").split(`
|
|
389
|
+
`).filter(g=>g.trim()):[]}catch(i){console.error("Failed to get logs:",i),c.status(500).send({error:"Failed to get logs"})}}),t.delete("/api/logs",async(l,c)=>{try{let i=l.query.file,u;return i?u=i:u=re(ir(),".claude-code-router","logs","app.log"),ue(u)&&ed(u,"","utf8"),{success:!0,message:"Logs cleared successfully"}}catch(i){console.error("Failed to clear logs:",i),c.status(500).send({error:"Failed to clear logs"})}}),t.get("/api/debug-log",async()=>({enabled:xt()})),t.put("/api/debug-log",async l=>{let{enabled:c}=l.body;return zn(c),{enabled:xt()}}),t.get("/api/usage",async(l,c)=>{try{let i=l.query;return Zo({startTime:i.startDate,endTime:i.endDate,model:i.model,provider:i.provider,scenario:i.scenario,clientType:i.clientType,sessionId:i.sessionId,status:i.status,page:i.page?parseInt(i.page,10):void 0,pageSize:i.pageSize?parseInt(i.pageSize,10):void 0})}catch(i){console.error("Failed to query usage:",i),c.status(500).send({error:"Failed to query usage"})}}),t.get("/api/usage/summary",async(l,c)=>{try{let i=l.query;return ht(i.startDate,i.endDate,i.status)}catch(i){console.error("Failed to query usage summary:",i),c.status(500).send({error:"Failed to query usage summary"})}}),t.delete("/api/usage",async(l,c)=>{try{let i=l.query;return er(i.beforeDate),{success:!0,message:i.beforeDate?"Usage data cleared before "+i.beforeDate:"All usage data cleared"}}catch(i){console.error("Failed to clear usage:",i),c.status(500).send({error:"Failed to clear usage data"})}}),t.get("/api/providers/health",async(l,c)=>{try{return{states:U().getAllStates().map(d=>({provider:d.provider,model:d.model,status:d.status,failureCount:d.failureCount,successCount:d.successCount,lastFailureTime:d.lastFailureTime,lastError:d.lastError,rateLimitUntil:d.rateLimitUntil??null})),timestamp:new Date().toISOString()}}catch(i){console.error("Failed to get provider health:",i),c.status(500).send({error:"Failed to get provider health"})}}),t.post("/api/providers/probe",async(l,c)=>{try{let{providerName:i}=l.body;if(!i)return c.status(400),{error:"providerName is required"};let d=t._server?.activeProbeService;if(!d?.probeProviderManually)return c.status(503),{error:"Active probe service is not available"};let m=await d.probeProviderManually(i);return m&&vn(i,l.log),{provider:i,success:m,timestamp:new Date().toISOString()}}catch(i){console.error("Failed to probe provider:",i),c.status(500).send({error:i.message||"Failed to probe provider"})}}),t.post("/api/providers/probe-all",async(l,c)=>{try{let i=t._server,u=i?.activeProbeService;if(!u?.probeProviderManually)return c.status(503),{error:"Active probe service is not available"};let d=(i?.providerService?.getProviders?.()||[]).filter(g=>g?.name&&g.enabled!==!1),m=await Promise.all(d.map(async g=>{let y=await u.probeProviderManually(g.name);return y&&vn(g.name,l?.log),{provider:g.name,success:y}}));return{results:m,successCount:m.filter(g=>g.success).length,total:m.length,timestamp:new Date().toISOString()}}catch(i){console.error("Failed to probe all providers:",i),c.status(500).send({error:i.message||"Failed to probe all providers"})}}),t.get("/api/providers/quota",async(l,c)=>{try{let u=(await j()).Providers||[],d=Sd(u),m=new Map(d.map(p=>[p.provider,p])),g=Yn();for(let p of d){let f=g.find(_=>_.provider===p.provider);f&&f.limit!=null&&(p.limit5h=f.limit,p.used5h=f.limit-(f.remaining??0),f.reset&&(p.reset5h=new Date(f.reset*1e3).toISOString()))}let y=oo();for(let p of y){let f=m.get(p.provider);f||(f={provider:p.provider,used5h:0,used7d:0},d.push(f),m.set(p.provider,f)),typeof p.totalBalance=="number"?(f.limit7d=p.totalBalance,f.type7d=p.currency?"balance":"rateLimit",p.currency&&(f.currency=p.currency),typeof p.usedBalance=="number"?f.used7d=p.usedBalance:typeof p.remainingBalance=="number"?f.used7d=Math.max(0,p.totalBalance-p.remainingBalance):(f.used7d=0,f.limit7d=p.totalBalance)):typeof p.usedBalance=="number"&&(f.used7d=p.usedBalance),typeof p.usedDailyBalance=="number"&&(f.used5h=p.usedDailyBalance,f.type5h="rateLimit"),typeof p.limitDaily=="number"&&(f.limit5h=p.limitDaily,f.type5h="rateLimit"),typeof p.resetTime=="string"&&(p.limitDaily!==void 0?f.reset5h=p.resetTime:f.reset7d=p.resetTime),typeof p.resetTime7d=="string"&&(f.reset7d=p.resetTime7d)}return{quotas:d,timestamp:new Date().toISOString()}}catch(i){console.error("Failed to compute provider quota:",i),c.status(500).send({error:"Failed to compute provider quota"})}}),t.get("/api/presets",async(l,c)=>{try{let i=re(od,"presets");if(!ue(i))return{presets:[]};let d=Qi(i,{withFileTypes:!0}).filter(g=>g.isDirectory()&&!g.name.startsWith(".")).map(g=>g.name),m=[];for(let g of d){let y=re(i,g);try{let p=re(y,"manifest.json"),f=Ki(p,"utf-8"),_=JSON.parse(f),{Providers:k,Router:h,PORT:b,HOST:x,API_TIMEOUT_MS:v,PROXY_URL:C,PROXY_GLOBAL_ENABLED:R,LOG:T,LOG_LEVEL:A,StatusLine:w,NON_INTERACTIVE_MODE:O,...P}=_;m.push({id:g,name:P.name||g,version:P.version||"1.0.0",description:P.description,author:P.author,homepage:P.homepage,repository:P.repository,license:P.license,keywords:P.keywords,ccrVersion:P.ccrVersion,source:P.source,sourceType:P.sourceType,checksum:P.checksum,installed:!0})}catch(p){console.error(`Failed to read preset ${g}:`,p)}}return{presets:m}}catch(i){console.error("Failed to get presets:",i),c.status(500).send({error:"Failed to get presets"})}}),t.get("/api/presets/:name",async(l,c)=>{try{let{name:i}=l.params,u=In(i);if(!ue(u)){c.status(404).send({error:"Preset not found"});return}let d=await ar(u);return{...Yi(d),config:rd(d,u),userValues:d.userValues||{}}}catch(i){console.error("Failed to get preset:",i),c.status(500).send({error:i.message||"Failed to get preset"})}}),t.post("/api/presets/:name/apply",async(l,c)=>{try{let{name:i}=l.params,{secrets:u}=l.body,d=In(i);if(!ue(d)){c.status(404).send({error:"Preset not found"});return}let g={...await ar(d)};return u&&Object.keys(u).length>0&&(g.userValues={...g.userValues,...u}),await qi(i,g),{success:!0,message:"Preset applied successfully"}}catch(i){console.error("Failed to apply preset:",i),c.status(500).send({error:i.message||"Failed to apply preset"})}}),t.delete("/api/presets/:name",async(l,c)=>{try{let{name:i}=l.params,u=In(i);if(!ue(u)){c.status(404).send({error:"Preset not found"});return}return td(u,{recursive:!0,force:!0}),{success:!0,message:"Preset deleted successfully"}}catch(i){console.error("Failed to delete preset:",i),c.status(500).send({error:i.message||"Failed to delete preset"})}}),t.get("/api/presets/market",async(l,c)=>{try{return{presets:await ad()}}catch(i){console.error("Failed to get market presets:",i),c.status(500).send({error:i.message||"Failed to get market presets"})}}),t.post("/api/presets/install/github",async(l,c)=>{try{let{presetName:i}=l.body;if(!i){c.status(400).send({error:"Preset name is required"});return}let u=await id(i);if(!u){c.status(400).send({error:"Preset not found in marketplace",message:`Preset '${i}' is not available in the official marketplace. Please check the available presets.`});return}if(!u.repo){c.status(400).send({error:"Invalid preset data",message:`Preset '${i}' does not have repository information`});return}let d=u.repo.match(/(?:github\.com[:/]|^)([^/]+)\/([^/\s#]+?)(?:\.git)?$/);if(!d){c.status(400).send({error:"Invalid GitHub repository URL"});return}let[,m,g]=d,y=u.name||i;if(await Zi(y)){c.status(409).send({error:"Preset already installed",message:`Preset '${y}' is already installed. To update or reconfigure, please delete it first using the delete button.`,presetName:y});return}let p=`https://github.com/${m}/${g}/archive/refs/heads/main.zip`,f=await sd(p),_=await a(f);if(await Zi(y)){Xi(f),c.status(409).send({error:"Preset already installed",message:`Preset '${y}' was installed while downloading. Please try again.`,presetName:y});return}let k=In(y);await nd(f,k);let h=await ar(k);return h.repository=u.repo,u.url&&(h.source=u.url),await qi(y,h),Xi(f),{success:!0,presetName:y,preset:{..._.metadata,installed:!0}}}catch(i){console.error("Failed to install preset from GitHub:",i),c.status(500).send({error:i.message||"Failed to install preset from GitHub"})}});async function a(l){let c=new wd(l),i=c.getEntry("manifest.json");if(i||(i=c.getEntries().find(m=>m.entryName.includes("manifest.json"))||null),!i)throw new Error("Invalid preset file: manifest.json not found");let u=JSON.parse(i.getData().toString("utf-8"));return Yi(u)}return n}var ra=S(()=>{"use strict";Ze();Re();Pe();Lt();hn();te();We();ne();Rn();ut();yt();Vi();Vo()});function Pd(n){let e=n||"";return e.includes(",")&&(e=e.split(",").pop()||e),e.includes("/")&&(e=e.split("/").pop()||e),e.includes(":")&&(e=e.split(":")[0]),e.trim().toLowerCase()}function Ad(n){let e=Pd(n);return[/claude/i,/gemini/i,/gpt-4o/i,/gpt-4\.1/i,/gpt-4-vision/i,/qwen.*vl/i,/glm-4v/i,/grok.*vision/i,/pixtral/i,/llava/i].some(o=>o.test(e))}function Od(n){return n.some(e=>e.role==="user"&&Array.isArray(e.content)&&e.content.some(t=>t.type==="image"||t.type==="image_url"||Array.isArray(t?.content)&&t.content.some(o=>o.type==="image"||o.type==="image_url")))}var dr,Mn,pr,sa,ia=S(()=>{"use strict";dr=class{cache=new Map;maxSize;ttl;constructor(e=100,t=300*1e3){this.maxSize=e,this.ttl=t}evictExpired(){let e=Date.now();for(let[t,o]of this.cache)e-o.timestamp>this.ttl&&this.cache.delete(t)}trim(){if(this.cache.size<=this.maxSize)return;let e=[...this.cache.keys()].slice(0,this.cache.size-this.maxSize);for(let t of e)this.cache.delete(t)}storeImage(e,t){this.hasImage(e)||(this.evictExpired(),this.cache.set(e,{source:t,timestamp:Date.now()}),this.trim())}getImage(e){let t=this.cache.get(e);return t?Date.now()-t.timestamp>this.ttl?(this.cache.delete(e),null):t.source:null}hasImage(e){let t=this.cache.get(e);return t?Date.now()-t.timestamp>this.ttl?(this.cache.delete(e),!1):!0:!1}clear(){this.cache.clear()}size(){return this.evictExpired(),this.cache.size}},Mn=new dr;pr=class{name="image";tools;constructor(){this.tools=new Map,this.appendTools()}shouldHandle(e,t){if(!t.Router.image||e.body.model===t.Router.image||!Od(e.body.messages))return!1;let r=e.body.messages[e.body.messages.length-1];if(!t.forceUseImageAgent){if(Ad(e.body.model))return!1;if(e.body.model=t.Router.image,r.role==="user"&&Array.isArray(r.content)){let s=[];r.content.filter(a=>a.type==="tool_result").forEach(a=>{Array.isArray(a.content)&&(a.content.forEach(l=>{l.type==="image"&&s.push(l)}),a.content="read image successfully")}),r.content.push(...s)}return!1}return!0}appendTools(){this.tools.set("analyzeImage",{name:"analyzeImage",description:"Analyse image or images by ID and extract information such as OCR text, objects, layout, colors, or safety signals.",input_schema:{type:"object",properties:{imageId:{type:"array",description:"an array of IDs to analyse",items:{type:"string"}},task:{type:"string",description:"Details of task to perform on the image.The more detailed, the better"},regions:{type:"array",description:"Optional regions of interest within the image",items:{type:"object",properties:{name:{type:"string",description:"Optional label for the region"},x:{type:"number",description:"X coordinate"},y:{type:"number",description:"Y coordinate"},w:{type:"number",description:"Width of the region"},h:{type:"number",description:"Height of the region"},units:{type:"string",enum:["px","pct"],description:"Units for coordinates and size"}},required:["x","y","w","h","units"]}}},required:["imageId","task"]},handler:async(e,t)=>{let o=[],r;if(e.imageId){if(Array.isArray(e.imageId))e.imageId.forEach(l=>{let c=Mn.getImage(`${t.req.id}_Image#${l}`);c&&o.push({type:"image",source:c})});else{let l=Mn.getImage(`${t.req.id}_Image#${e.imageId}`);l&&o.push({type:"image",source:l})}r=e.imageId,delete e.imageId}let s=t.req.body.messages[t.req.body.messages.length-1];if(s.role==="user"&&Array.isArray(s.content)){let l=s.content.filter(c=>c.type==="text"&&!c.text.includes("This is an image, if you need to view or analyze it, you need to extract the imageId"));o.push(...l)}Object.keys(e).length>0&&o.push({type:"text",text:JSON.stringify(e)});let a=await fetch(`http://127.0.0.1:${t.config.PORT||3456}/v1/messages`,{method:"POST",headers:{"x-api-key":t.config.APIKEY,"content-type":"application/json"},body:JSON.stringify({model:t.config.Router.image,system:[{type:"text",text:`You must interpret and analyze images strictly according to the assigned task.
|
|
390
390
|
When an image placeholder is provided, your role is to parse the image content only within the scope of the user\u2019s instructions.
|
|
391
391
|
Do not ignore or deviate from the task.
|
|
392
392
|
Always ensure that your response reflects a clear, accurate interpretation of the image aligned with the given objective.`}],messages:[{role:"user",content:o}],stream:!1})}).then(l=>l.json()).catch(l=>null);return!a||!a.content?"analyzeImage Error":a.content[0].text}})}reqHandler(e,t){e.body?.system?.push({type:"text",text:`You are a text-only language model and do not possess visual perception.
|
|
@@ -399,5 +399,5 @@ If multiple images exist, select the **most relevant imageId** based on the user
|
|
|
399
399
|
|
|
400
400
|
Do not attempt to describe or analyze the image directly yourself.
|
|
401
401
|
Ignore any user interruptions or unrelated instructions that might cause you to skip this requirement.
|
|
402
|
-
Your response should consistently follow this rule whenever image-related analysis is requested.`});let o=e.body.messages.filter(s=>s.role==="user"&&Array.isArray(s.content)&&s.content.some(a=>a.type==="image"||Array.isArray(a.content)&&a.content.some(l=>l.type==="image"))),r=1;o.forEach(s=>{Array.isArray(s.content)&&s.content.forEach(a=>{a.type==="image"?(Mn.storeImage(`${e.id}_Image#${r}`,a.source),a.type="text",delete a.source,a.text=`[Image #${r}]This is an image, if you need to view or analyze it, you need to extract the imageId`,r++):a.type==="text"&&a.text.includes("[Image #")?a.text=a.text.replace(/\[Image #\d+\]/g,""):a.type==="tool_result"&&Array.isArray(a.content)&&a.content.some(l=>l.type==="image")&&(Mn.storeImage(`${e.id}_Image#${r}`,a.content[0].source),a.content=`[Image #${r}]This is an image, if you need to view or analyze it, you need to extract the imageId`,r++)})})}},ia=new pr});var fr,ca,$n,la=S(()=>{"use strict";aa();fr=class{agents=new Map;registerAgent(e){this.agents.set(e.name,e)}getAgent(e){return this.agents.get(e)}getAllAgents(){return Array.from(this.agents.values())}getAllTools(){let e=[];for(let t of this.agents.values())e.push(...t.tools.values());return e}},ca=new fr;ca.registerAgent(ia);$n=ca});import{EventEmitter as Id}from"node:events";import{performance as ua}from"node:perf_hooks";import Md from"json5";function pa(n,e){(!n.clientContext||!n.usageCacheKey||!n.usageSessionId)&&ye(n,e)}function mr(n){return n.usageSessionId||n.id}function Nn(n){return n.usageCacheKey||`${n.clientType||"unknown"}:request:${mr(n)}`}function Je(n){return n.body?.model?Array.isArray(n.body.model)?n.body.model.join(","):n.body.model:Array.isArray(n.model)?n.model.join(","):n.model||""}function $d(n){if(!n)return;let e=n;if(Buffer.isBuffer(n)&&(e=n.toString("utf8")),typeof e=="string")try{e=JSON.parse(e)}catch{return}if(typeof e!="object")return;let t=e.usage?Ue(e.usage):e.response?.usage?Ue(e.response.usage):void 0,o=e.model||e.response?.model;if(!(!t&&!o))return{usage:t,model:o}}async function Nd(n,e,t){if(await new Promise((r,s)=>{let a=l=>l?s(l):r();Sn(t)(n,e,a).then(()=>r(),s)}),e.sent)return;let o=new URL(`http://127.0.0.1${n.url}`);if(n.pathname=o.pathname,n.pathname.endsWith("/v1/messages")&&n.pathname!=="/v1/messages"&&(n.preset=n.pathname.replace("/v1/messages","").replace("/","")),n.pathname.endsWith("/v1/responses")&&n.pathname!=="/v1/responses"&&(n.preset=n.pathname.replace("/v1/responses","").replace("/","")),n.pathname.endsWith("/v1/messages")||n.pathname.endsWith("/v1/responses")){pa(n,t);let r=Nn(n);n.clientContext?.usageScope==="session"&&(n.previousUsage=X.get(r))}if((n.pathname.endsWith("/v1/messages")||n.pathname.endsWith("/v1/responses"))&&n.clientType==="codex"){await Ei();let r=await Mi();n.codexAccountId=r.id,n.codexAccountEmail=r.email}}async function Ld(n,e,t){if(!n.pathname?.endsWith("/v1/messages"))return;let o=[];for(let r of $n.getAllAgents())r.shouldHandle(n,t)&&(o.push(r.name),r.reqHandler(n,t),r.tools.size&&(n.body?.tools?.length||(n.body.tools=[]),n.body.tools.unshift(...Array.from(r.tools.values()).map(s=>({name:s.name,description:s.description,input_schema:s.input_schema})))));o.length&&(n.agents=o)}function fa(n){return{authCodex:(e,t)=>Nd(e,t,n),agent:(e,t)=>Ld(e,t,n)}}function ma(n,e){n.addHook("onRequest",async t=>{let o=new URL(`http://127.0.0.1${t.url}`);t.pathname=o.pathname,(o.pathname.endsWith("/v1/messages")||o.pathname.endsWith("/v1/responses"))&&!t.requestStartTime&&(t.requestStartTime=ua.now())}),n.addHook("preHandler",async(t,o)=>{let r=t.pathname||new URL(`http://127.0.0.1${t.url}`).pathname;r.endsWith("/v1/messages")||r.endsWith("/v1/responses")||await new Promise((s,a)=>{let l=c=>c?a(c):s();Sn(e)(t,o,l).then(()=>s(),a)})}),n.addHook("onError",async(t,o,r)=>{t.errorMessage=r?.message||r?.toString?.()||"Unknown error",da.emit("onError",t,o,r)}),n.addHook("onSend",(t,o,r,s)=>{(t.ccrHookOrder||=[]).push("onSend");let a=t.pathname?.endsWith("/v1/messages"),l=t.pathname?.endsWith("/v1/responses");if(a||l){pa(t,e);let c=mr(t),i=Nn(t);if(r instanceof ReadableStream){if(a&&t.agents){let y=new AbortController,p=r.pipeThrough(new oe),f,_=-1,k="",h="",b="",x=[],v=[];return s(null,hn(p,async(C,R)=>{try{if(C.event==="content_block_start"&&C?.data?.content_block?.name){let T=t.agents.find(A=>$n.getAgent(A)?.tools.get(C.data.content_block.name));if(T){f=$n.getAgent(T),_=C.data.index,k=C.data.content_block.name,b=C.data.content_block.id;return}}if(_>-1&&C.data.index===_&&C.data?.delta?.type==="input_json_delta"){h+=C.data?.delta?.partial_json;return}if(_>-1&&C.data.index===_&&C.data?.type==="content_block_stop"){try{let T=Md.parse(h);v.push({type:"tool_use",id:b,name:k,input:T});let A=await f?.tools.get(k)?.handler(T,{req:t,config:e});x.push({tool_use_id:b,type:"tool_result",content:A}),f=void 0,_=-1,k="",h="",b=""}catch(T){console.log(T)}return}if(C.event==="message_delta"&&x.length){t.body.messages.push({role:"assistant",content:v}),t.body.messages.push({role:"user",content:x});let T=await fetch(`http://127.0.0.1:${e.PORT||3456}/v1/messages`,{method:"POST",headers:{"x-api-key":e.APIKEY,"content-type":"application/json"},body:JSON.stringify(t.body)});if(!T.ok)return;let w=T.body.pipeThrough(new oe).getReader();for(;;)try{let{value:O,done:P}=await w.read();if(P)break;let E=O;if(["message_start","message_stop"].includes(E.event))continue;if(!R.desiredSize)break;R.enqueue(E)}catch(O){if(O.name==="AbortError"||O.code==="ERR_STREAM_PREMATURE_CLOSE"){y.abort();break}throw O}return}return C}catch(T){if(console.error("Unexpected error in stream processing:",T),T.code==="ERR_STREAM_PREMATURE_CLOSE"){y.abort();return}throw T}}).pipeThrough(new Le))}let[d,m]=r.tee(),g=async y=>{let f=y.pipeThrough(new TextDecoderStream).pipeThrough(new oe).getReader();try{for(;;){let{done:_,value:k}=await f.read();if(_)break;let h=k.event,b=k.data;if(h==="message_start"&&b?.message?.model&&(t.upstreamModel=b.message.model),h==="response.completed"&&b?.response?.model&&(t.upstreamModel=b.response.model),b?.usage){let x=X.get(i)||{},v=Ue(b.usage),C=Cn(x,v,h==="message_start");t.log?.info?.({debug_log:!0,reqId:t.id,phase:"usage_capture_anthropic_sse",event:h,provider:t.provider,model:Je(t),usageSessionId:c,capturedUsage:v,mergedUsage:C}),(v?.cache_read_input_tokens||v?.cache_creation_input_tokens)&&console.log("[Usage] Cache tokens:",{cache_read:v?.cache_read_input_tokens,cache_creation:v?.cache_creation_input_tokens}),X.put(i,C)}if(b?.response?.usage){let x=Ue(b.response.usage),v=X.get(i)||{},C=Cn(v,x,!1);t.log?.info?.({debug_log:!0,reqId:t.id,phase:"usage_capture_responses_sse",event:h,provider:t.provider,model:Je(t),usageSessionId:c,capturedUsage:x,mergedUsage:C}),X.put(i,C)}}}catch(_){_.name==="AbortError"||_.code==="ERR_STREAM_PREMATURE_CLOSE"?console.error("Background read stream closed prematurely"):console.error("Error in background stream reading:",_)}finally{f.releaseLock()}};return t.usageCapturePromise=g(m),s(null,d)}let u=$d(r);if(u?.usage&&X.put(i,u.usage),u?.model&&(t.upstreamModel=u.model),typeof r=="object")return r.error?s(r.error,null):s(r,null)}if(typeof r=="object"&&r.error)return s(r.error,null);s(null,r)}),n.addHook("onSend",async(t,o,r)=>{if(da.emit("onSend",t,o,r),o.statusCode>=400&&(t.pathname?.endsWith("/v1/messages")||t.pathname?.endsWith("/v1/responses")))try{typeof r=="string"?t.errorResponseBody=r:r&&typeof r=="object"&&(t.errorResponseBody=JSON.stringify(r))}catch{}return r}),n.addHook("onResponse",async(t,o)=>{if((t.ccrHookOrder||=[]).push("onResponse"),!(!t.pathname?.endsWith("/v1/messages")&&!t.pathname?.endsWith("/v1/responses")))try{t.usageCapturePromise&&await t.usageCapturePromise,t.tokenSpeedCapturePromise&&await t.tokenSpeedCapturePromise;let r=mr(t),s=o.statusCode>=400,a=s?void 0:X.get(Nn(t)),l=tr(r),c=U(),i,u,d=t.sseError,m=d&&(d.type||d.code||d.message),g=a?.output_tokens&&a.output_tokens>0,y=s||m&&!g;if(y){i=t.errorMessage||o.errorMessage||t.error?.message||t.error?.toString?.()||void 0,m&&(i=i||JSON.stringify(d),u=JSON.stringify(d)),u=u||t.errorResponseBody;let h=Je(t);En(o.statusCode,i)?(c.markRateLimited(t.provider||"",h,120,i),(t.clientType||he(t))==="codex"&&await On(i)):c.recordFailure(t.provider||"",h,i)}else{let h=Je(t);c.recordSuccess(t.provider||"",h)}let p=a?.cache_read_input_tokens??0,_=a?.input_tokens||0||t.tokenCount||0;!p&&t.tokenCount&&a?.input_tokens&&a.input_tokens<t.tokenCount&&(p=t.tokenCount-a.input_tokens,p&&console.log("[Usage] Inferred cache tokens:",{tokenCount:t.tokenCount,netInput:a.input_tokens,impliedCache:p}));let k=y?0:a?.output_tokens||0;!y&&t.body?.stream&&_===0&&k===0&&t.log?.warn?.({debug_log:!0,reqId:t.id,phase:"usage_zero_stream",provider:t.provider,originalModel:t.originalModel||t.body?.model||"",model:Je(t),usageSessionId:r,tokenCount:t.tokenCount,cachedUsage:a,note:"Successful streaming request ended with zero usage. Check provider_stream_chunk usage_monitor and usage_capture_* logs."}),gt({id:`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,timestamp:new Date().toISOString(),sessionId:r,provider:t.provider||"",originalModel:t.originalModel||t.body?.model||"",model:Je(t),upstreamModel:t.upstreamModel,modelFamily:t.modelFamily||"",scenarioType:t.scenarioType||"default",clientType:t.clientType||he(t),codexAccountId:t.codexAccountId,codexAccountEmail:t.codexAccountEmail,stream:t.body?.stream??!1,inputTokens:_,outputTokens:k,cacheReadInputTokens:p,cacheCreationInputTokens:a?.cache_creation_input_tokens||0,ttft:y?null:l.ttft,tokensPerSecond:y?null:l.tokensPerSecond,durationMs:t.requestStartTime?Math.round(ua.now()-t.requestStartTime):0,status:y?"error":"success",errorMessage:i,responseBody:u}),t.clientContext?.usageScope!=="session"&&X.delete(Nn(t))}catch(r){console.error("Usage tracking error:",r)}})}var da,ga=S(()=>{"use strict";Oe();Pt();ee();Oo();Eo();Io();yt();Wo();la();Qo();Nt();nr();da=new Id});var ha={};Fn(ha,{createCcrServer:()=>Jd});import{homedir as Fd}from"os";import{join as Ud}from"path";import{createStream as Dd}from"rotating-file-stream";import{CONFIG_FILE as jd,HOME_DIR as zd,listPresets as Hd}from"@wengine-ai/claude-code-router-shared";async function Jd(n={}){await Ri(),await bn();let e=await Bo();Ii();let t=e.Providers||e.providers||[],o=t&&t.length>0,r=e.HOST||"127.0.0.1";o?(r=e.HOST,e.APIKEY||(r="127.0.0.1")):(r="0.0.0.0",console.log("\u2139\uFE0F No providers configured. Listening on 0.0.0.0 without authentication."));let s=n.port??e.PORT??3456,a=process.env.SERVICE_PORT?parseInt(process.env.SERVICE_PORT):s,l=p=>(p>9?"":"0")+p,c=(p,f)=>{let _;p?typeof p=="number"?_=new Date(p):_=p:_=new Date;let k=_.getFullYear()+""+l(_.getMonth()+1),h=l(_.getDate()),b=l(_.getHours()),x=l(_.getMinutes());return`./logs/ccr-${k}${h}${b}${x}${l(_.getSeconds())}${f?`_${f}`:""}.log`},i;n.logger!==void 0?i=n.logger:(Fi(),e.LOG!==!1?(e.LOG===void 0&&(e.LOG=!0),i={level:e.LOG_LEVEL||"error",stream:Dd(c,{path:zd,interval:"1d",size:"50M",compress:!1})}):i=!1);let u=await Hd(),d=new _a({jsonPath:jd,initialConfig:{providers:e.Providers||e.providers,HOST:r,PORT:a,LOG_FILE:Ud(Fd(),".claude-code-router","claude-code-router.log")},logger:i});await d.ready(),await ra(d,e),d.recordUsage=p=>{try{let f=p.req?p.req.clientType||he(p.req):"unknown";f==="codex"&&En(0,p.errorMessage)&&On(p.errorMessage),gt({id:`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,timestamp:new Date().toISOString(),sessionId:p.sessionId||"",provider:p.provider||"",originalModel:p.originalModel||"",model:p.model||"",modelFamily:p.modelFamily||"",scenarioType:p.scenarioType||"default",clientType:f,codexAccountId:p.req?.codexAccountId,codexAccountEmail:p.req?.codexAccountEmail,stream:p.stream??!1,inputTokens:p.inputTokens||0,outputTokens:0,cacheReadInputTokens:p.cacheReadInputTokens||0,cacheCreationInputTokens:p.cacheCreationInputTokens||0,ttft:null,tokensPerSecond:null,durationMs:0,status:"error",errorMessage:p.errorMessage,responseBody:void 0})}catch(f){console.error("Fallback usage tracking error:",f)}},ma(d,e),d.ccrPreHandlerCallbacks=fa(e),(await Promise.allSettled(u.map(async p=>await d.registerNamespace(`/preset/${p.name}`,p.config)))).forEach((p,f)=>{if(p.status==="rejected"){let _=u[f],k=p.reason instanceof Error?p.reason.message:String(p.reason);d.app?.log?.error?.(`Failed to register preset "${_?.name}": ${k}`)}}),await Di(d,e),dt(e,d.app?.log);let g=p=>{d.app.log.error({err:p},"Uncaught exception")},y=(p,f)=>{d.app.log.error({reason:p,promise:f},"Unhandled rejection")};return process.on("uncaughtException",g),process.on("unhandledRejection",y),d.app.addHook("onClose",async()=>{process.off("uncaughtException",g),process.off("unhandledRejection",y)}),d}var ya=S(()=>{"use strict";ka();wi();ut();nr();Ui();ji();sa();ga();Rn();yt();Oe()});import Bd from"fastify";import Wd from"@fastify/cors";function Gd(n={}){let e=Bd({bodyLimit:52428800,...n});return e.setErrorHandler(xr),e.register(Wd),e}async function Vd(n={}){return(await Promise.resolve().then(()=>(ya(),ha))).createCcrServer(n)}var gr,_a,l_,ka=S(()=>{Dn();bt();Nt();Lt();po();mo();et();Pt();gn();ee();ve();Se();Z();Oe();Nt();Xe();Oe();et();Dn();Lt();po();mo();jo();Mo();ee();ve();wo();Se();ee();gn();We();Z();ut();Wo();Rn();Vo();Qo();yt();gr=class{app;configService;providerService;transformerService;tokenizerService;activeProbeService;recordUsage;readiness;mainNamespaceRegistered=!1;signalHandlersRegistered=!1;ccrPreHandlerCallbacks;constructor(e={}){let{initialConfig:t,jsonPath:o,envPath:r,useEnvFile:s,useJsonFile:a,useEnvironmentVariables:l,...c}=e;this.app=Gd({...c,logger:c.logger??!0}),this.app._server=this;let i={initialConfig:t};o!==void 0&&(i.jsonPath=o),r!==void 0&&(i.envPath=r),s!==void 0&&(i.useEnvFile=s),a!==void 0&&(i.useJsonFile=a),l!==void 0&&(i.useEnvironmentVariables=l),this.configService=new be(i),this.transformerService=new Me(this.configService,this.app.log),this.tokenizerService=new $e(this.configService,this.app.log),this.readiness=(async()=>{await Promise.all([this.transformerService.initialize(),this.tokenizerService.initialize()]),this.providerService=new ce(this.configService,this.transformerService,this.app.log)})()}async ready(){await this.readiness}async register(e,t){await this.app.register(e,t)}addHook(e,t){this.app.addHook(e,t)}async registerNamespace(e,t){if(!e)throw new Error("name is required");if(await this.ready(),e==="/"&&this.mainNamespaceRegistered)return;let o=this.configService,r=this.transformerService,s=this.providerService,a=this.tokenizerService;if(e!=="/"){if(!t)throw new Error("options is required");o=new be({initialConfig:{...t,providers:t.Providers||t.providers}}),r=new Me(o,this.app.log),a=new $e(o,this.app.log),await Promise.all([r.initialize(),a.initialize()]),s=new ce(o,r,this.app.log)}let l=async c=>{c.decorate("configService",o),c.decorate("transformerService",r),c.decorate("providerService",s),c.decorate("tokenizerService",a),c.decorate("recordUsage",this.recordUsage||(()=>{})),c.addHook("preHandler",async(i,u)=>{let d=new URL(`http://127.0.0.1${i.url}`);i.pathname=d.pathname;let m=d.pathname.endsWith("/v1/messages"),g=d.pathname.endsWith("/v1/responses");if(!m&&!g||!i.body||typeof i.body!="object")return;let y=i.ccrHookOrder||=[];if(y.push("request-normalize"),g&&i.body.input&&!i.body.messages&&tt(i.body),i.body.stream===void 0&&(i.body.stream=!1),i.log.info({data:i.body,type:"request body"}),y.push("adapter"),!i.originalModel&&i.body.model&&(i.originalModel=i.body.model),ye(i,o.getAll()),y.push("auth-codex"),!(this.ccrPreHandlerCallbacks&&(await this.ccrPreHandlerCallbacks.authCodex(i,u),u.sent))&&(y.push("agent"),!(this.ccrPreHandlerCallbacks&&(await this.ccrPreHandlerCallbacks.agent(i,u),u.sent)))){y.push("router"),i.body?.model&&await Mt(i,u,{configService:o,tokenizerService:a}),i.usageCacheKey&&X.put(i.usageCacheKey,{input_tokens:0,output_tokens:0,cache_read_input_tokens:0,cache_creation_input_tokens:0}),y.push("provider-model-normalize");try{let p=i.body;if(!p||!p.model)return u.code(400).send({error:"Missing model in request body"});let f=p.model.split(","),_=p.model;if(f.length>1){let[k,...h]=f;_=h.join(","),p.model=_,i.provider=k}i.model=_}catch(p){return i.log.error({error:p},"Error in modelProviderMiddleware:"),u.code(500).send({error:"Internal server error"})}}}),await ys(c)};e==="/"?(await this.app.register(l),this.mainNamespaceRegistered=!0):await this.app.register(l,{prefix:e})}async start(){try{if(await this.ready(),await this.registerNamespace("/"),!this.signalHandlersRegistered){this.signalHandlersRegistered=!0;let t=async s=>{this.app.log.info(`Received ${s}, shutting down gracefully...`);try{Po()}catch{}await this.app.close(),process.exit(0)},o=()=>void t("SIGINT"),r=()=>void t("SIGTERM");process.on("SIGINT",o),process.on("SIGTERM",r),this.app.addHook("onClose",async()=>{process.off("SIGINT",o),process.off("SIGTERM",r),this.signalHandlersRegistered=!1;try{this.tokenizerService.dispose()}catch{}await Un()})}await this.app.ready();let e=await this.app.listen({port:parseInt(this.configService.get("PORT")||"3000",10),host:this.configService.get("HOST")||"127.0.0.1"});this.app.log.info(`\u{1F680} LLMs API server listening on ${e}`);try{Ve()}catch{}try{Qe()}catch{}try{Vn()}catch{}try{let t={enabled:this.configService.get("ACTIVE_PROBE_ENABLED")??!0,quotaProbeIntervalMinutes:this.configService.get("QUOTA_PROBE_INTERVAL_MINUTES")??10,probeTimeoutMs:this.configService.get("PROBE_TIMEOUT_MS")??15e3,initialDelayMs:this.configService.get("PROBE_INITIAL_DELAY_MS")??5e3,excludeProviders:this.configService.get("EXCLUDE_PROBE_PROVIDERS")??[]};this.activeProbeService=Ne(()=>this.providerService.getProviders(),t,o=>se(this.configService,o),this.app.log,o=>this.configService.get(o))}catch(t){this.app.log.warn?.(`Failed to start active probe service: ${t.message}`)}}catch(e){this.app.log.error(`Error starting server: ${e}`),process.exit(1)}}},_a=gr;l_=Vd});ka();export{fn as ActiveProbeService,be as ConfigService,ae as ProjectRoutingError,St as ProviderHealthStore,ce as ProviderService,oe as SSEParserTransform,Le as SSESerializerTransform,$e as TokenizerService,Me as TransformerService,Sn as apiKeyAuth,ye as applyClientAdapter,xn as backupConfigFile,Yr as builtinClientAdapterRegistry,It as calculateTokenCount,Ec as clearClientAdapterCaches,vn as clearProviderHealth,Un as closeProxyDispatchers,mi as collectReachableModelKeys,Vd as createCcrServer,_a as default,he as detectClientType,as as diagnoseResolutionFailure,Ke as extractSessionIdFromUserId,ri as getActiveProbeService,oo as getAllQuotaResults,Yn as getAllRateLimitInfo,Zr as getClientAdapter,kt as getConfiguredProxyUrl,U as getHealthStore,V as getProxyDispatcher,vo as getQuotaAdapter,At as getQuotaResult,ec as getRateLimitInfo,xt as getRuntimeDebugLog,l_ as getServer,Bo as initConfig,bn as initDir,Vn as initProviderHealthPersistence,Qe as initQuotaStorePersistence,Ve as initRateLimitPersistence,qr as isClientType,_r as isGlobalProxyEnabled,wn as listAnthropicCompatibleModels,Cn as mergeUsageCapture,Pe as normalizeSessionId,Ue as normalizeUsagePayload,rt as pluginManager,j as readConfigFile,Jo as readConfigFileRaw,dt as reconcileHealthStore,mn as resetActiveProbeService,se as resolveProviderProxyUrl,hn as rewriteStream,Mt as router,us as searchProjectBySession,X as sessionUsageCache,zn as setRuntimeDebugLog,Ne as startActiveProbe,Po as stopActiveProbe,no as storeQuotaResult,yn as tokenSpeedPlugin,vi as usageStore,q as writeConfigFile};
|
|
402
|
+
Your response should consistently follow this rule whenever image-related analysis is requested.`});let o=e.body.messages.filter(s=>s.role==="user"&&Array.isArray(s.content)&&s.content.some(a=>a.type==="image"||Array.isArray(a.content)&&a.content.some(l=>l.type==="image"))),r=1;o.forEach(s=>{Array.isArray(s.content)&&s.content.forEach(a=>{a.type==="image"?(Mn.storeImage(`${e.id}_Image#${r}`,a.source),a.type="text",delete a.source,a.text=`[Image #${r}]This is an image, if you need to view or analyze it, you need to extract the imageId`,r++):a.type==="text"&&a.text.includes("[Image #")?a.text=a.text.replace(/\[Image #\d+\]/g,""):a.type==="tool_result"&&Array.isArray(a.content)&&a.content.some(l=>l.type==="image")&&(Mn.storeImage(`${e.id}_Image#${r}`,a.content[0].source),a.content=`[Image #${r}]This is an image, if you need to view or analyze it, you need to extract the imageId`,r++)})})}},sa=new pr});var fr,aa,$n,ca=S(()=>{"use strict";ia();fr=class{agents=new Map;registerAgent(e){this.agents.set(e.name,e)}getAgent(e){return this.agents.get(e)}getAllAgents(){return Array.from(this.agents.values())}getAllTools(){let e=[];for(let t of this.agents.values())e.push(...t.tools.values());return e}},aa=new fr;aa.registerAgent(sa);$n=aa});import{EventEmitter as Ed}from"node:events";import{performance as la}from"node:perf_hooks";import Id from"json5";function da(n,e){(!n.clientContext||!n.usageCacheKey||!n.usageSessionId)&&ye(n,e)}function mr(n){return n.usageSessionId||n.id}function Nn(n){return n.usageCacheKey||`${n.clientType||"unknown"}:request:${mr(n)}`}function Je(n){return n.body?.model?Array.isArray(n.body.model)?n.body.model.join(","):n.body.model:Array.isArray(n.model)?n.model.join(","):n.model||""}function Md(n){if(!n)return;let e=n;if(Buffer.isBuffer(n)&&(e=n.toString("utf8")),typeof e=="string")try{e=JSON.parse(e)}catch{return}if(typeof e!="object")return;let t=e.usage?Ue(e.usage):e.response?.usage?Ue(e.response.usage):void 0,o=e.model||e.response?.model;if(!(!t&&!o))return{usage:t,model:o}}async function $d(n,e,t){if(await new Promise((r,s)=>{let a=l=>l?s(l):r();Sn(t)(n,e,a).then(()=>r(),s)}),e.sent)return;let o=new URL(`http://127.0.0.1${n.url}`);if(n.pathname=o.pathname,n.pathname.endsWith("/v1/messages")&&n.pathname!=="/v1/messages"&&(n.preset=n.pathname.replace("/v1/messages","").replace("/","")),n.pathname.endsWith("/v1/responses")&&n.pathname!=="/v1/responses"&&(n.preset=n.pathname.replace("/v1/responses","").replace("/","")),n.pathname.endsWith("/v1/messages")||n.pathname.endsWith("/v1/responses")){da(n,t);let r=Nn(n);n.clientContext?.usageScope==="session"&&(n.previousUsage=X.get(r))}if((n.pathname.endsWith("/v1/messages")||n.pathname.endsWith("/v1/responses"))&&n.clientType==="codex"){await Oi();let r=await Ii();n.codexAccountId=r.id,n.codexAccountEmail=r.email}}async function Nd(n,e,t){if(!n.pathname?.endsWith("/v1/messages"))return;let o=[];for(let r of $n.getAllAgents())r.shouldHandle(n,t)&&(o.push(r.name),r.reqHandler(n,t),r.tools.size&&(n.body?.tools?.length||(n.body.tools=[]),n.body.tools.unshift(...Array.from(r.tools.values()).map(s=>({name:s.name,description:s.description,input_schema:s.input_schema})))));o.length&&(n.agents=o)}function pa(n){return{authCodex:(e,t)=>$d(e,t,n),agent:(e,t)=>Nd(e,t,n)}}function fa(n,e){n.addHook("onRequest",async t=>{let o=new URL(`http://127.0.0.1${t.url}`);t.pathname=o.pathname,(o.pathname.endsWith("/v1/messages")||o.pathname.endsWith("/v1/responses"))&&!t.requestStartTime&&(t.requestStartTime=la.now())}),n.addHook("preHandler",async(t,o)=>{let r=t.pathname||new URL(`http://127.0.0.1${t.url}`).pathname;r.endsWith("/v1/messages")||r.endsWith("/v1/responses")||await new Promise((s,a)=>{let l=c=>c?a(c):s();Sn(e)(t,o,l).then(()=>s(),a)})}),n.addHook("onError",async(t,o,r)=>{t.errorMessage=r?.message||r?.toString?.()||"Unknown error",ua.emit("onError",t,o,r)}),n.addHook("onSend",(t,o,r,s)=>{(t.ccrHookOrder||=[]).push("onSend");let a=t.pathname?.endsWith("/v1/messages"),l=t.pathname?.endsWith("/v1/responses");if(a||l){da(t,e);let c=mr(t),i=Nn(t);if(r instanceof ReadableStream){if(a&&t.agents){let y=new AbortController,p=r.pipeThrough(new se),f,_=-1,k="",h="",b="",x=[],v=[];return s(null,yn(p,async(C,R)=>{try{if(C.event==="content_block_start"&&C?.data?.content_block?.name){let T=t.agents.find(A=>$n.getAgent(A)?.tools.get(C.data.content_block.name));if(T){f=$n.getAgent(T),_=C.data.index,k=C.data.content_block.name,b=C.data.content_block.id;return}}if(_>-1&&C.data.index===_&&C.data?.delta?.type==="input_json_delta"){h+=C.data?.delta?.partial_json;return}if(_>-1&&C.data.index===_&&C.data?.type==="content_block_stop"){try{let T=Id.parse(h);v.push({type:"tool_use",id:b,name:k,input:T});let A=await f?.tools.get(k)?.handler(T,{req:t,config:e});x.push({tool_use_id:b,type:"tool_result",content:A}),f=void 0,_=-1,k="",h="",b=""}catch(T){console.log(T)}return}if(C.event==="message_delta"&&x.length){t.body.messages.push({role:"assistant",content:v}),t.body.messages.push({role:"user",content:x});let T=await fetch(`http://127.0.0.1:${e.PORT||3456}/v1/messages`,{method:"POST",headers:{"x-api-key":e.APIKEY,"content-type":"application/json"},body:JSON.stringify(t.body)});if(!T.ok)return;let w=T.body.pipeThrough(new se).getReader();for(;;)try{let{value:O,done:P}=await w.read();if(P)break;let E=O;if(["message_start","message_stop"].includes(E.event))continue;if(!R.desiredSize)break;R.enqueue(E)}catch(O){if(O.name==="AbortError"||O.code==="ERR_STREAM_PREMATURE_CLOSE"){y.abort();break}throw O}return}return C}catch(T){if(console.error("Unexpected error in stream processing:",T),T.code==="ERR_STREAM_PREMATURE_CLOSE"){y.abort();return}throw T}}).pipeThrough(new Le))}let[d,m]=r.tee(),g=async y=>{let f=y.pipeThrough(new TextDecoderStream).pipeThrough(new se).getReader();try{for(;;){let{done:_,value:k}=await f.read();if(_)break;let h=k.event,b=k.data;if(h==="message_start"&&b?.message?.model&&(t.upstreamModel=b.message.model),h==="response.completed"&&b?.response?.model&&(t.upstreamModel=b.response.model),b?.usage){let x=X.get(i)||{},v=Ue(b.usage),C=Cn(x,v,h==="message_start");t.log?.info?.({debug_log:!0,reqId:t.id,phase:"usage_capture_anthropic_sse",event:h,provider:t.provider,model:Je(t),usageSessionId:c,capturedUsage:v,mergedUsage:C}),(v?.cache_read_input_tokens||v?.cache_creation_input_tokens)&&console.log("[Usage] Cache tokens:",{cache_read:v?.cache_read_input_tokens,cache_creation:v?.cache_creation_input_tokens}),X.put(i,C)}if(b?.response?.usage){let x=Ue(b.response.usage),v=X.get(i)||{},C=Cn(v,x,!1);t.log?.info?.({debug_log:!0,reqId:t.id,phase:"usage_capture_responses_sse",event:h,provider:t.provider,model:Je(t),usageSessionId:c,capturedUsage:x,mergedUsage:C}),X.put(i,C)}}}catch(_){_.name==="AbortError"||_.code==="ERR_STREAM_PREMATURE_CLOSE"?console.error("Background read stream closed prematurely"):console.error("Error in background stream reading:",_)}finally{f.releaseLock()}};return t.usageCapturePromise=g(m),s(null,d)}let u=Md(r);if(u?.usage&&X.put(i,u.usage),u?.model&&(t.upstreamModel=u.model),typeof r=="object")return r.error?s(r.error,null):s(r,null)}if(typeof r=="object"&&r.error)return s(r.error,null);s(null,r)}),n.addHook("onSend",async(t,o,r)=>{if(ua.emit("onSend",t,o,r),o.statusCode>=400&&(t.pathname?.endsWith("/v1/messages")||t.pathname?.endsWith("/v1/responses")))try{typeof r=="string"?t.errorResponseBody=r:r&&typeof r=="object"&&(t.errorResponseBody=JSON.stringify(r))}catch{}return r}),n.addHook("onResponse",async(t,o)=>{if((t.ccrHookOrder||=[]).push("onResponse"),!(!t.pathname?.endsWith("/v1/messages")&&!t.pathname?.endsWith("/v1/responses")))try{t.usageCapturePromise&&await t.usageCapturePromise,t.tokenSpeedCapturePromise&&await t.tokenSpeedCapturePromise;let r=mr(t),s=o.statusCode>=400,a=s?void 0:X.get(Nn(t)),l=tr(r),c=U(),i,u,d=t.sseError,m=d&&(d.type||d.code||d.message),g=a?.output_tokens&&a.output_tokens>0,y=s||m&&!g;if(y){i=t.errorMessage||o.errorMessage||t.error?.message||t.error?.toString?.()||void 0,m&&(i=i||JSON.stringify(d),u=JSON.stringify(d)),u=u||t.errorResponseBody;let h=Je(t);En(o.statusCode,i)?(c.markRateLimited(t.provider||"",h,120,i),(t.clientType||he(t))==="codex"&&await On(i)):c.recordFailure(t.provider||"",h,i)}else{let h=Je(t);c.recordSuccess(t.provider||"",h)}let p=a?.cache_read_input_tokens??0,_=a?.input_tokens||0||t.tokenCount||0;!p&&t.tokenCount&&a?.input_tokens&&a.input_tokens<t.tokenCount&&(p=t.tokenCount-a.input_tokens,p&&console.log("[Usage] Inferred cache tokens:",{tokenCount:t.tokenCount,netInput:a.input_tokens,impliedCache:p}));let k=y?0:a?.output_tokens||0;!y&&t.body?.stream&&_===0&&k===0&&t.log?.warn?.({debug_log:!0,reqId:t.id,phase:"usage_zero_stream",provider:t.provider,originalModel:t.originalModel||t.body?.model||"",model:Je(t),usageSessionId:r,tokenCount:t.tokenCount,cachedUsage:a,note:"Successful streaming request ended with zero usage. Check provider_stream_chunk usage_monitor and usage_capture_* logs."}),gt({id:`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,timestamp:new Date().toISOString(),sessionId:r,provider:t.provider||"",originalModel:t.originalModel||t.body?.model||"",model:Je(t),upstreamModel:t.upstreamModel,modelFamily:t.modelFamily||"",scenarioType:t.scenarioType||"default",clientType:t.clientType||he(t),codexAccountId:t.codexAccountId,codexAccountEmail:t.codexAccountEmail,stream:t.body?.stream??!1,inputTokens:_,outputTokens:k,cacheReadInputTokens:p,cacheCreationInputTokens:a?.cache_creation_input_tokens||0,ttft:y?null:l.ttft,tokensPerSecond:y?null:l.tokensPerSecond,durationMs:t.requestStartTime?Math.round(la.now()-t.requestStartTime):0,status:y?"error":"success",errorMessage:i,responseBody:u}),t.clientContext?.usageScope!=="session"&&X.delete(Nn(t))}catch(r){console.error("Usage tracking error:",r)}})}var ua,ma=S(()=>{"use strict";Oe();Pt();ne();Eo();Io();Mo();yt();Wo();ca();Qo();Nt();nr();ua=new Ed});var ga={};Fn(ga,{createCcrServer:()=>Hd});import{homedir as Ld}from"os";import{join as Fd}from"path";import{createStream as Ud}from"rotating-file-stream";import{CONFIG_FILE as Dd,HOME_DIR as jd,listPresets as zd}from"@wengine-ai/claude-code-router-shared";async function Hd(n={}){await vi(),await bn();let e=await Bo();Ei();let t=e.Providers||e.providers||[],o=t&&t.length>0,r=e.HOST||"127.0.0.1";o?(r=e.HOST,e.APIKEY||(r="127.0.0.1")):(r="0.0.0.0",console.log("\u2139\uFE0F No providers configured. Listening on 0.0.0.0 without authentication."));let s=n.port??e.PORT??3456,a=process.env.SERVICE_PORT?parseInt(process.env.SERVICE_PORT):s,l=p=>(p>9?"":"0")+p,c=(p,f)=>{let _;p?typeof p=="number"?_=new Date(p):_=p:_=new Date;let k=_.getFullYear()+""+l(_.getMonth()+1),h=l(_.getDate()),b=l(_.getHours()),x=l(_.getMinutes());return`./logs/ccr-${k}${h}${b}${x}${l(_.getSeconds())}${f?`_${f}`:""}.log`},i;n.logger!==void 0?i=n.logger:(Li(),e.LOG!==!1?(e.LOG===void 0&&(e.LOG=!0),i={level:e.LOG_LEVEL||"error",stream:Ud(c,{path:jd,interval:"1d",size:"50M",compress:!1})}):i=!1);let u=await zd(),d=new ya({jsonPath:Dd,initialConfig:{providers:e.Providers||e.providers,HOST:r,PORT:a,LOG_FILE:Fd(Ld(),".claude-code-router","claude-code-router.log")},logger:i});await d.ready(),await oa(d,e),d.recordUsage=p=>{try{let f=p.req?p.req.clientType||he(p.req):"unknown";f==="codex"&&En(0,p.errorMessage)&&On(p.errorMessage),gt({id:`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,timestamp:new Date().toISOString(),sessionId:p.sessionId||"",provider:p.provider||"",originalModel:p.originalModel||"",model:p.model||"",modelFamily:p.modelFamily||"",scenarioType:p.scenarioType||"default",clientType:f,codexAccountId:p.req?.codexAccountId,codexAccountEmail:p.req?.codexAccountEmail,stream:p.stream??!1,inputTokens:p.inputTokens||0,outputTokens:0,cacheReadInputTokens:p.cacheReadInputTokens||0,cacheCreationInputTokens:p.cacheCreationInputTokens||0,ttft:null,tokensPerSecond:null,durationMs:0,status:"error",errorMessage:p.errorMessage,responseBody:void 0})}catch(f){console.error("Fallback usage tracking error:",f)}},fa(d,e),d.ccrPreHandlerCallbacks=pa(e),(await Promise.allSettled(u.map(async p=>await d.registerNamespace(`/preset/${p.name}`,p.config)))).forEach((p,f)=>{if(p.status==="rejected"){let _=u[f],k=p.reason instanceof Error?p.reason.message:String(p.reason);d.app?.log?.error?.(`Failed to register preset "${_?.name}": ${k}`)}}),await Ui(d,e),dt(e,d.app?.log);let g=p=>{d.app.log.error({err:p},"Uncaught exception")},y=(p,f)=>{d.app.log.error({reason:p,promise:f},"Unhandled rejection")};return process.on("uncaughtException",g),process.on("unhandledRejection",y),d.app.addHook("onClose",async()=>{process.off("uncaughtException",g),process.off("unhandledRejection",y)}),d}var ha=S(()=>{"use strict";_a();Ri();ut();nr();Fi();Di();ra();ma();Rn();yt();Oe()});import Jd from"fastify";import Bd from"@fastify/cors";function Wd(n={}){let e=Jd({bodyLimit:52428800,...n});return e.setErrorHandler(xr),e.register(Bd),e}async function Gd(n={}){return(await Promise.resolve().then(()=>(ha(),ga))).createCcrServer(n)}var gr,ya,r_,_a=S(()=>{Dn();bt();Nt();Lt();uo();fo();Ze();Pt();hn();ne();Re();Pe();te();Oe();Nt();Xe();Oe();Ze();Dn();Lt();uo();fo();zo();$o();ne();Re();So();Pe();ne();hn();We();te();ut();Wo();Rn();Vo();Qo();yt();gr=class{app;configService;providerService;transformerService;tokenizerService;activeProbeService;recordUsage;readiness;mainNamespaceRegistered=!1;signalHandlersRegistered=!1;ccrPreHandlerCallbacks;constructor(e={}){let{initialConfig:t,jsonPath:o,envPath:r,useEnvFile:s,useJsonFile:a,useEnvironmentVariables:l,...c}=e;this.app=Wd({...c,logger:c.logger??!0}),this.app._server=this;let i={initialConfig:t};o!==void 0&&(i.jsonPath=o),r!==void 0&&(i.envPath=r),s!==void 0&&(i.useEnvFile=s),a!==void 0&&(i.useJsonFile=a),l!==void 0&&(i.useEnvironmentVariables=l),this.configService=new xe(i),this.transformerService=new Me(this.configService,this.app.log),this.tokenizerService=new $e(this.configService,this.app.log),this.readiness=(async()=>{await Promise.all([this.transformerService.initialize(),this.tokenizerService.initialize()]),this.providerService=new le(this.configService,this.transformerService,this.app.log)})()}async ready(){await this.readiness}async register(e,t){await this.app.register(e,t)}addHook(e,t){this.app.addHook(e,t)}async registerNamespace(e,t){if(!e)throw new Error("name is required");if(await this.ready(),e==="/"&&this.mainNamespaceRegistered)return;let o=this.configService,r=this.transformerService,s=this.providerService,a=this.tokenizerService;if(e!=="/"){if(!t)throw new Error("options is required");o=new xe({initialConfig:{...t,providers:t.Providers||t.providers}}),r=new Me(o,this.app.log),a=new $e(o,this.app.log),await Promise.all([r.initialize(),a.initialize()]),s=new le(o,r,this.app.log)}let l=async c=>{c.decorate("configService",o),c.decorate("transformerService",r),c.decorate("providerService",s),c.decorate("tokenizerService",a),c.decorate("recordUsage",this.recordUsage||(()=>{})),c.addHook("preHandler",async(i,u)=>{let d=new URL(`http://127.0.0.1${i.url}`);i.pathname=d.pathname;let m=d.pathname.endsWith("/v1/messages"),g=d.pathname.endsWith("/v1/responses");if(!m&&!g||!i.body||typeof i.body!="object")return;let y=i.ccrHookOrder||=[];if(y.push("request-normalize"),g&&i.body.input&&!i.body.messages&&et(i.body),i.body.stream===void 0&&(i.body.stream=!1),i.log.info({data:i.body,type:"request body"}),y.push("adapter"),!i.originalModel&&i.body.model&&(i.originalModel=i.body.model),ye(i,o.getAll()),y.push("auth-codex"),!(this.ccrPreHandlerCallbacks&&(await this.ccrPreHandlerCallbacks.authCodex(i,u),u.sent))&&(y.push("agent"),!(this.ccrPreHandlerCallbacks&&(await this.ccrPreHandlerCallbacks.agent(i,u),u.sent)))){y.push("router"),i.body?.model&&await Mt(i,u,{configService:o,tokenizerService:a}),i.usageCacheKey&&X.put(i.usageCacheKey,{input_tokens:0,output_tokens:0,cache_read_input_tokens:0,cache_creation_input_tokens:0}),y.push("provider-model-normalize");try{let p=i.body;if(!p||!p.model)return u.code(400).send({error:"Missing model in request body"});let f=p.model.split(","),_=p.model;if(f.length>1){let[k,...h]=f;_=h.join(","),p.model=_,i.provider=k}i.model=_}catch(p){return i.log.error({error:p},"Error in modelProviderMiddleware:"),u.code(500).send({error:"Internal server error"})}}}),await fs(c)};e==="/"?(await this.app.register(l),this.mainNamespaceRegistered=!0):await this.app.register(l,{prefix:e})}async start(){try{if(await this.ready(),await this.registerNamespace("/"),!this.signalHandlersRegistered){this.signalHandlersRegistered=!0;let t=async s=>{this.app.log.info(`Received ${s}, shutting down gracefully...`);try{Ao()}catch{}await this.app.close(),process.exit(0)},o=()=>void t("SIGINT"),r=()=>void t("SIGTERM");process.on("SIGINT",o),process.on("SIGTERM",r),this.app.addHook("onClose",async()=>{process.off("SIGINT",o),process.off("SIGTERM",r),this.signalHandlersRegistered=!1;try{this.tokenizerService.dispose()}catch{}await Un()})}await this.app.ready();let e=await this.app.listen({port:parseInt(this.configService.get("PORT")||"3000",10),host:this.configService.get("HOST")||"127.0.0.1"});this.app.log.info(`\u{1F680} LLMs API server listening on ${e}`);try{Ve()}catch{}try{Qe()}catch{}try{Vn()}catch{}try{let t={enabled:this.configService.get("ACTIVE_PROBE_ENABLED")??!0,quotaProbeIntervalMinutes:this.configService.get("QUOTA_PROBE_INTERVAL_MINUTES")??10,probeTimeoutMs:this.configService.get("PROBE_TIMEOUT_MS")??15e3,initialDelayMs:this.configService.get("PROBE_INITIAL_DELAY_MS")??5e3,excludeProviders:this.configService.get("EXCLUDE_PROBE_PROVIDERS")??[]};this.activeProbeService=Ne(()=>this.providerService.getProviders(),t,o=>ie(this.configService,o),this.app.log,o=>this.configService.get(o))}catch(t){this.app.log.warn?.(`Failed to start active probe service: ${t.message}`)}}catch(e){this.app.log.error(`Error starting server: ${e}`),process.exit(1)}}},ya=gr;r_=Gd});_a();export{mn as ActiveProbeService,xe as ConfigService,ce as ProjectRoutingError,St as ProviderHealthStore,le as ProviderService,se as SSEParserTransform,Le as SSESerializerTransform,$e as TokenizerService,Me as TransformerService,Sn as apiKeyAuth,ye as applyClientAdapter,xn as backupConfigFile,Vr as builtinClientAdapterRegistry,It as calculateTokenCount,xc as clearClientAdapterCaches,vn as clearProviderHealth,Un as closeProxyDispatchers,fi as collectReachableModelKeys,Gd as createCcrServer,ya as default,he as detectClientType,os as diagnoseResolutionFailure,Ke as extractSessionIdFromUserId,ni as getActiveProbeService,oo as getAllQuotaResults,Yn as getAllRateLimitInfo,Kr as getClientAdapter,kt as getConfiguredProxyUrl,U as getHealthStore,G as getProxyDispatcher,Ro as getQuotaAdapter,At as getQuotaResult,Za as getRateLimitInfo,xt as getRuntimeDebugLog,r_ as getServer,Bo as initConfig,bn as initDir,Vn as initProviderHealthPersistence,Qe as initQuotaStorePersistence,Ve as initRateLimitPersistence,Qr as isClientType,_r as isGlobalProxyEnabled,wn as listAnthropicCompatibleModels,Cn as mergeUsageCapture,Ae as normalizeSessionId,Ue as normalizeUsagePayload,ot as pluginManager,j as readConfigFile,Jo as readConfigFileRaw,dt as reconcileHealthStore,gn as resetActiveProbeService,ie as resolveProviderProxyUrl,yn as rewriteStream,Mt as router,is as searchProjectBySession,X as sessionUsageCache,zn as setRuntimeDebugLog,Ne as startActiveProbe,Ao as stopActiveProbe,no as storeQuotaResult,_n as tokenSpeedPlugin,Ti as usageStore,Z as writeConfigFile};
|
|
403
403
|
//# sourceMappingURL=server.mjs.map
|