@wengine-ai/llms 2.3.2395 → 2.3.2397
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 +3 -2
- package/dist/cjs/server.cjs +145 -145
- package/dist/cjs/server.cjs.map +4 -4
- package/dist/esm/server.mjs +146 -146
- package/dist/esm/server.mjs.map +4 -4
- package/dist/index.html +21 -21
- package/dist/transformer/opencode.transformer.d.ts +2 -0
- package/dist/transformer/response-body.d.ts +27 -0
- package/package.json +2 -2
package/dist/esm/server.mjs
CHANGED
|
@@ -1,51 +1,51 @@
|
|
|
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
|
|
2
|
+
var Ln=Object.defineProperty;var ea=Object.getOwnPropertyDescriptor;var ta=Object.getOwnPropertyNames;var na=Object.prototype.hasOwnProperty;var We=(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 w=(n,e)=>()=>(n&&(e=n(n=0)),e);var Dn=(n,e)=>{for(var t in e)Ln(n,t,{get:e[t],enumerable:!0})},oa=(n,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of ta(e))!na.call(n,r)&&r!==t&&Ln(n,r,{get:()=>e[r],enumerable:!(o=ea(e,r))||o.enumerable});return n};var ra=n=>oa(Ln({},"__esModule",{value:!0}),n);import{ProxyAgent as sa}from"undici";function aa(n){if(n==null)return{ok:!0};let e=String(n).trim();if(!e)return{ok:!0};if(ia.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 mr(n){let e=[];for(let t of fr){let o=n[t];if(o==null)continue;let r=aa(o);r.ok||e.push({key:t,error:r.error})}return e}function kt(n){for(let e of fr){let t=n.get(e);if(t==null)continue;let o=String(t).trim();if(o)return o}}function gr(n){if(n==null||n==="")return!0;if(typeof n=="string"){let e=n.trim().toLowerCase();return e==="false"||e==="0"?!1:e==="true"||e==="1"?!0:!!e}return n===!1||n===0?!1:n===!0||n===1?!0:!!n}function ae(n,e){let t=kt(n);if(t)return gr(n.get("PROXY_GLOBAL_ENABLED"))||e?.proxyEnabled===!0||e?.proxy_enabled===!0?t:void 0}function G(n){let e=ca(n),t=_t.get(e);if(t)return t;let o=new sa(e);return _t.set(e,o),o}async function Fn(){let n=Array.from(_t.values());_t.clear(),await Promise.allSettled(n.map(e=>e.close()))}function ca(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 fr,ia,_t,te=w(()=>{"use strict";fr=["HTTPS_PROXY","https_proxy","httpsProxy","PROXY_URL"],ia=/\$\{[^}]+\}|\$[A-Z_][A-Z0-9_]*/;_t=new Map});import{readFileSync as la,existsSync as hr}from"fs";import{join as yr}from"path";import{config as ua}from"dotenv";import da from"json5";var Te,Un=w(()=>{"use strict";te();Te=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:yr(process.cwd(),this.options.jsonPath);if(hr(e))try{let t=la(e,"utf-8"),o=da.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:yr(process.cwd(),this.options.envPath);if(hr(e))try{let t=ua({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 _r(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=w(()=>{"use strict"});function Hn(n){jn=n}function Tt(){return jn}function Ct(n){return jn||n.get("DEBUG_LOG")===!0}function Tr(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 vt(n){let e={};for(let[t,o]of Object.entries(n))pa.has(t.toLowerCase())?e[t]="***MASKED***":e[t]=o;return e}function xt(n,e){return n.length<=e?n:n.slice(0,e)+`...[truncated, total ${n.length} bytes]`}function Cr(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:vt(t.headers),body:xt(o,Ce.maxBodyLength)})}function vr(n,e,t){n.info({debug_log:!0,reqId:e,phase:"provider_response",status:t.status,headers:vt(t.headers),...t.body!==void 0?{body:xt(t.body,Ce.maxBodyLength)}:{}})}function kr(n,e,t,o){let r=fa(o);n.info({debug_log:!0,reqId:e,phase:"provider_stream_chunk",chunkIndex:t,...r?{usage_monitor:r}:{},data:xt(o,Ce.maxBodyLength)})}function fa(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:xt(o,512)})}}if(e.length)return e.length===1?e[0]:e}function br(n,e,t){n.info({debug_log:!0,reqId:e,phase:"provider_stream_end",totalChunks:t})}function xr(n,e,t,o){(async()=>{let r=n.pipeThrough(new TextDecoderStream).getReader(),s=0;try{let i="";for(;;){let{done:l,value:a}=await r.read();if(l)break;i+=a;let c=i.split(`
|
|
3
3
|
|
|
4
|
-
`);i=c.pop()||"";for(let u of c)u.trim()&&(s<o.maxStreamChunks?yr(e,t,s,u):s===o.maxStreamChunks&&e.info({debug_log:!0,reqId:t,phase:"provider_stream_chunk_omitted",message:`[chunks after #${s} omitted, maxStreamChunks=${o.maxStreamChunks}]`}),s++)}i.trim()&&(s<o.maxStreamChunks&&yr(e,t,s,i.trim()),s++),_r(e,t,s)}catch(i){console.error(`[debug_log] Error reading debug stream for reqId=${t}:`,i),_r(e,t,s)}finally{r.releaseLock()}})()}var la,be,Fn,Je=w(()=>{"use strict";la=new Set(["authorization","x-api-key","x-goog-api-key","cookie","set-cookie"]),be={maxBodyLength:4096,maxStreamChunks:100},Fn=!1});function vr(n,e,t,o,r){let s=new Headers({"Content-Type":"application/json"});t.headers&&Object.entries(t.headers).forEach(([c,u])=>{u&&s.set(c,u)});let i,l=AbortSignal.timeout(t.TIMEOUT??60*1e3*60);if(t.signal){let c=new AbortController,u=()=>c.abort();t.signal.addEventListener("abort",u),l.addEventListener("abort",u),i=c.signal}else i=l;let a={method:"POST",headers:s,body:JSON.stringify(e),signal:i};return t.httpsProxy&&(a.dispatcher=W(t.httpsProxy)),r?.debug({reqId:o.req.id,method:"POST",headers:Tt(Object.fromEntries(s.entries())),requestUrl:typeof n=="string"?n:n.toString(),useProxy:da(t.httpsProxy)},"final request"),fetch(typeof n=="string"?n:n.toString(),a)}function da(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 xr=w(()=>{Z();Je()});var vt,jn=w(()=>{vt="2.3.2395"});var Sr={};Nn(Sr,{getFallbackPromotionStore:()=>Te,resetFallbackPromotionStore:()=>ma});function Te(n){return me||(me=new Hn,n&&me.configure(n)),me}function ma(){me&&(me.clearAll(),me=null)}var fa,Hn,me,xt=w(()=>{"use strict";ee();fa=600*1e3,Hn=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,i){if(!this.enabled)return;let l=this.getKey(e,t,o),a=`${r},${s}`;this.promotions.set(l,{promotedModel:a,timestamp:Date.now(),ttlMs:i??this.ttlMs})}getPromotion(e,t,o,r){if(!this.enabled)return null;let s=this.getKey(e,t,o),i=this.promotions.get(s);if(!i)return null;if(Date.now()-i.timestamp>=i.ttlMs)return this.promotions.delete(s),null;let[a,...c]=i.promotedModel.split(","),u=c.join(",");if(!F().isAvailable(a,u))return this.promotions.delete(s),null;let g=r.find(y=>y.name.toLowerCase()===a.toLowerCase()),m=g?.models?.find(y=>String(y).toLowerCase()===u.toLowerCase());return!g||!m||g.enabled===!1?(this.promotions.delete(s),null):`${g.name},${m}`}clear(e,t,o){let r=this.getKey(e,t,o);this.promotions.delete(r)}clearByPrimary(e,t){let o=`${e},${t}:`,r=0;for(let s of this.promotions.keys())s.startsWith(o)&&(this.promotions.delete(s),r++);return r}clearAll(){this.promotions.clear()}clearExpired(){let e=Date.now();for(let[t,o]of this.promotions)e-o.timestamp>=o.ttlMs&&this.promotions.delete(t)}getAllPromotions(){let e=Date.now(),t=[];for(let[o,r]of this.promotions){let s=r.ttlMs-(e-r.timestamp);s>0&&t.push({key:o,promotedModel:r.promotedModel,remainingMs:s})}return t}},me=null});import{existsSync as Pr,mkdirSync as ga,readFileSync as ha,writeFileSync as ya}from"fs";import{join as Er}from"path";import{HOME_DIR as _a}from"@wengine-ai/claude-code-router-shared";function Ca(n){try{if(!Pr(Jn))return;let e=JSON.parse(ha(Jn,"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 wr(n){try{let e=n.getAllStates();if(e.length===0)return;Pr(Bn)||ga(Bn,{recursive:!0});let t=e.map(o=>({...o,updatedAt:Date.now()}));ya(Jn,JSON.stringify(t,null,2),"utf-8")}catch{}}function Wn(){if(Rr)return;Rr=!0;let n=F();Ca(n),Ta=setInterval(()=>wr(n),6e4),process.on("exit",()=>wr(n))}function F(n){return zn||(zn=new St(n)),zn}var ka,ba,St,Bn,Jn,Rr,Ta,zn,ee=w(()=>{"use strict";ka=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}=(xt(),ta(Sr));o().clearByPrimary(e,t)}catch{}}recordFailure(e,t,o){if(!this.config.enabled)return;let r=this.getKey(e,t);if(!r)return;let s=this.states.get(r);s||(s={provider:e,model:t,status:"closed",failureCount:0,successCount:0,lastFailureTime:0,lastProbeTime:0},this.states.set(r,s)),s.failureCount++,s.lastFailureTime=Date.now(),s.lastError=o,s.status==="half-open"?(s.status="open",s.successCount=0,s.lastProbeTime=0):s.status==="closed"&&s.failureCount>=this.config.failureThreshold&&(s.status="open",s.lastProbeTime=0)}getState(e,t){let o=this.getKey(e,t);if(o)return this.states.get(o)}isAvailable(e,t){if(!this.config.enabled)return!0;if(!this.getKey(e,t))return!1;let r=this.getState(e,t);return r?r.status==="open"&&r.rateLimitUntil?!(Date.now()<r.rateLimitUntil):r.status!=="open":!0}getPriority(e,t){if(!this.config.enabled)return 0;if(!this.getKey(e,t))return 2;let r=this.getState(e,t);if(!r)return 0;switch(r.status){case"closed":return 0;case"half-open":return 1;case"open":return 2}}getHealthyModels(){return[]}getFailPoolModels(){let e=[];for(let[t,o]of this.states)o.status==="open"&&e.push(t);return e}getHalfOpenModels(){let e=[];for(let[t,o]of this.states)o.status==="half-open"&&e.push(t);return e}forceOpen(e,t,o){if(!this.config.enabled)return;let r=this.getKey(e,t);if(!r)return;let s=this.states.get(r);s?(s.status="open",s.failureCount=Math.max(s.failureCount,this.config.failureThreshold),s.lastFailureTime=Date.now(),s.lastError=o,s.lastProbeTime=0):(s={provider:e,model:t,status:"open",failureCount:this.config.failureThreshold,successCount:0,lastFailureTime:Date.now(),lastProbeTime:0,lastError:o},this.states.set(r,s))}markRateLimited(e,t,o,r){if(!this.config.enabled)return;let s=this.getKey(e,t);if(!s)return;let i=this.states.get(s);i?(i.status="open",i.lastFailureTime=Date.now(),i.lastError=r||"rate-limited",i.lastProbeTime=0):(i={provider:e,model:t,status:"open",failureCount:0,successCount:0,lastFailureTime:Date.now(),lastProbeTime:0,lastError:r||"rate-limited"},this.states.set(s,i));let l=(o??ka)*1e3;i.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)}},Bn=Er(_a,"runtime"),Jn=Er(Bn,"provider-health.json"),Rr=!1,Ta=null;zn=null});import{existsSync as $r,mkdirSync as va,readFileSync as xa,writeFileSync as Sa}from"fs";import{join as Nr}from"path";import{HOME_DIR as Ra}from"@wengine-ai/claude-code-router-shared";function We(n,e,t){let o=l=>{if(t instanceof Headers)return t.get(l);let a=Object.keys(t).find(c=>c.toLowerCase()===l);return a?t[a]:null},r=Gn(o,wa),s=Gn(o,Pa),i=Gn(o,Ea);(r||s||i)&&Ce.set(n,{provider:n,remaining:Ir(r),limit:Ir(s),reset:Aa(i),capturedAt:Date.now()})}function Oa(n){return Ce.get(n)}function Vn(){return Array.from(Ce.values())}function Gn(n,e){for(let t of e){let o=n(t);if(o)return o}return null}function Ir(n){if(!n)return null;let e=Number(n.trim().replace(/,/g,""));return Number.isFinite(e)?e:null}function Aa(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=Ia(e);return r===null?null:Math.floor((Date.now()+r)/1e3)}function Ia(n){let e=/(\d+(?:\.\d+)?)(ms|s|m|h|d)/gi,t=0,o=!1;for(let r of n.matchAll(e)){o=!0;let s=Number(r[1]),i=r[2].toLowerCase();if(Number.isFinite(s))switch(i){case"ms":t+=s;break;case"s":t+=s*1e3;break;case"m":t+=s*60*1e3;break;case"h":t+=s*60*60*1e3;break;case"d":t+=s*24*60*60*1e3;break}}return o?t:null}function Ma(){try{if(!$r(Qn))return;let n=JSON.parse(xa(Qn,"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;Ce.set(t.provider,t)}}catch{}}function Mr(){try{if(Ce.size===0)return;$r(Kn)||va(Kn,{recursive:!0}),Sa(Qn,JSON.stringify(Array.from(Ce.values()),null,2),"utf-8")}catch{}}function Ge(){Or||(Or=!0,Ma(),Ar=setInterval(Mr,6e4),Ar.unref?.(),process.on("exit",Mr))}var Kn,Qn,Ce,Or,Ar,wa,Pa,Ea,ve=w(()=>{"use strict";Kn=Nr(Ra,"runtime"),Qn=Nr(Kn,"rate-limit.json"),Ce=new Map,Or=!1,Ar=null,wa=["x-ratelimit-remaining-tokens","x-ratelimit-remaining-requests","x-ratelimit-remaining"],Pa=["x-ratelimit-limit-tokens","x-ratelimit-limit-requests","x-ratelimit-limit"],Ea=["x-ratelimit-reset-tokens","x-ratelimit-reset-requests","x-ratelimit-reset"]});var xe,Yn=w(()=>{"use strict";xe=class{name="openai-responses";endPoint="/v1/responses";getCacheReadInputTokens(e){return e?.cache_read_input_tokens??e?.input_tokens_details?.cached_tokens??e?.prompt_tokens_details?.cached_tokens??0}getCacheCreationInputTokens(e){return e?.cache_creation_input_tokens??e?.input_tokens_details?.cache_creation_tokens??e?.input_tokens_details?.cache_write_tokens??e?.prompt_tokens_details?.cache_creation_tokens??e?.prompt_tokens_details?.cache_write_tokens??0}buildResponsesUsage(e){let t=e?.input_tokens??e?.prompt_tokens??0,o=e?.output_tokens??e?.completion_tokens??0,r=this.getCacheReadInputTokens(e),s=this.getCacheCreationInputTokens(e);return{input_tokens:t,output_tokens:o,total_tokens:e?.total_tokens??t+o,input_tokens_details:{cached_tokens:r,cache_creation_tokens:s},output_tokens_details:{reasoning_tokens:e?.output_tokens_details?.reasoning_tokens??0},cache_read_input_tokens:r,cache_creation_input_tokens:s}}async transformRequestIn(e){delete e.temperature,delete e.max_tokens,e.reasoning&&(e.reasoning={effort:e.reasoning.effort,summary:e.reasoning.summary||"auto"});let t=[],o=e.messages.filter(r=>r.role==="system");if(o.length>0){let r=o[0];Array.isArray(r.content)?r.content.forEach(s=>{let i="";typeof s=="string"?i=s:s&&typeof s=="object"&&"text"in s&&(i=s.text),t.push({role:"system",content:i})}):e.instructions=r.content}if(e.messages.forEach(r=>{if(r.role!=="system"){if(Array.isArray(r.content)){let s=r.content.map(i=>this.normalizeRequestContent(i,r.role)).filter(i=>i!==null);s.length>0?r.content=s:delete r.content}if(r.role==="tool"){let s={...r};s.type="function_call_output",s.call_id=r.tool_call_id,s.output=r.content,delete s.cache_control,delete s.role,delete s.tool_call_id,delete s.content,t.push(s);return}if(r.role==="assistant"&&Array.isArray(r.tool_calls)){r.tool_calls.forEach(s=>{t.push({type:"function_call",arguments:s.function.arguments,name:s.function.name,call_id:s.id})});return}t.push(r)}}),e.input=t,delete e.messages,Array.isArray(e.tools)){let r=e.tools.find(s=>s.function.name==="web_search");e.tools=e.tools.filter(s=>s.function.name!=="web_search").map(s=>(s.function.name==="WebSearch"&&delete s.function.parameters.properties.allowed_domains,s.function.name==="Edit"?{type:s.type,name:s.function.name,description:s.function.description,parameters:{...s.function.parameters,required:["file_path","old_string","new_string","replace_all"]},strict:!0}:{type:s.type,name:s.function.name,description:s.function.description,parameters:s.function.parameters})),r&&e.tools.push({type:"web_search"})}return e.parallel_tool_calls=!1,e}async transformResponseOut(e){let t=e.headers.get("Content-Type")||"";if(t.includes("application/json")){let o=await 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(),i="";try{let{value:f,done:_}=await s.read();!_&&f&&(i=new TextDecoder().decode(f))}finally{s.releaseLock()}if(o.cancel().catch(()=>{}),i.includes("message_start")||i.includes("content_block_start")){let f=this.prependToStream(i,r);return new Response(f,{status:e.status,statusText:e.statusText,headers:e.headers})}if(i.includes("response.created")||i.includes("response.output_text.delta")||i.includes("response.in_progress")||i.includes("response.output_item.added")){let f=this.prependToStream(i,r);return new Response(f,{status:e.status,statusText:e.statusText,headers:e.headers})}let c=this.prependToStream(i,r),u=new TextDecoder,d=new TextEncoder,g="",m=!1,y=this,p=new ReadableStream({async start(f){let _=c.getReader(),k=-1,h="",b=T=>(T!==h&&(k++,h=T),k);try{for(;;){let{done:T,value:x}=await _.read();if(T){m||f.enqueue(d.encode(`data: [DONE]
|
|
4
|
+
`);i=c.pop()||"";for(let u of c)u.trim()&&(s<o.maxStreamChunks?kr(e,t,s,u):s===o.maxStreamChunks&&e.info({debug_log:!0,reqId:t,phase:"provider_stream_chunk_omitted",message:`[chunks after #${s} omitted, maxStreamChunks=${o.maxStreamChunks}]`}),s++)}i.trim()&&(s<o.maxStreamChunks&&kr(e,t,s,i.trim()),s++),br(e,t,s)}catch(i){console.error(`[debug_log] Error reading debug stream for reqId=${t}:`,i),br(e,t,s)}finally{r.releaseLock()}})()}var pa,Ce,jn,Ge=w(()=>{"use strict";pa=new Set(["authorization","x-api-key","x-goog-api-key","cookie","set-cookie"]),Ce={maxBodyLength:4096,maxStreamChunks:100},jn=!1});function Sr(n,e,t,o,r){let s=new Headers({"Content-Type":"application/json"});t.headers&&Object.entries(t.headers).forEach(([c,u])=>{u&&s.set(c,u)});let i,l=AbortSignal.timeout(t.TIMEOUT??60*1e3*60);if(t.signal){let c=new AbortController,u=()=>c.abort();t.signal.addEventListener("abort",u),l.addEventListener("abort",u),i=c.signal}else i=l;let a={method:"POST",headers:s,body:JSON.stringify(e),signal:i};return t.httpsProxy&&(a.dispatcher=G(t.httpsProxy)),r?.debug({reqId:o.req.id,method:"POST",headers:vt(Object.fromEntries(s.entries())),requestUrl:typeof n=="string"?n:n.toString(),useProxy:ma(t.httpsProxy)},"final request"),fetch(typeof n=="string"?n:n.toString(),a)}function ma(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 Rr=w(()=>{te();Ge()});var St,zn=w(()=>{St="2.3.2397"});var wr={};Dn(wr,{getFallbackPromotionStore:()=>ve,resetFallbackPromotionStore:()=>ya});function ve(n){return he||(he=new Jn,n&&he.configure(n)),he}function ya(){he&&(he.clearAll(),he=null)}var ha,Jn,he,Rt=w(()=>{"use strict";ne();ha=600*1e3,Jn=class{promotions=new Map;enabled=!0;ttlMs=ha;configure(e){e?.enabled!==void 0&&(this.enabled=e.enabled),e?.ttlMinutes!==void 0&&(this.ttlMs=e.ttlMinutes*60*1e3)}getKey(e,t,o){return`${e},${t}:${o}`}promote(e,t,o,r,s,i){if(!this.enabled)return;let l=this.getKey(e,t,o),a=`${r},${s}`;this.promotions.set(l,{promotedModel:a,timestamp:Date.now(),ttlMs:i??this.ttlMs})}getPromotion(e,t,o,r){if(!this.enabled)return null;let s=this.getKey(e,t,o),i=this.promotions.get(s);if(!i)return null;if(Date.now()-i.timestamp>=i.ttlMs)return this.promotions.delete(s),null;let[a,...c]=i.promotedModel.split(","),u=c.join(",");if(!U().isAvailable(a,u))return this.promotions.delete(s),null;let g=r.find(y=>y.name.toLowerCase()===a.toLowerCase()),f=g?.models?.find(y=>String(y).toLowerCase()===u.toLowerCase());return!g||!f||g.enabled===!1?(this.promotions.delete(s),null):`${g.name},${f}`}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}},he=null});import{existsSync as Or,mkdirSync as _a,readFileSync as ka,writeFileSync as ba}from"fs";import{join as Ar}from"path";import{HOME_DIR as Ta}from"@wengine-ai/claude-code-router-shared";function Sa(n){try{if(!Or(Gn))return;let e=JSON.parse(ka(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 Er(n){try{let e=n.getAllStates();if(e.length===0)return;Or(Wn)||_a(Wn,{recursive:!0});let t=e.map(o=>({...o,updatedAt:Date.now()}));ba(Gn,JSON.stringify(t,null,2),"utf-8")}catch{}}function Kn(){if(Pr)return;Pr=!0;let n=U();Sa(n),xa=setInterval(()=>Er(n),6e4),process.on("exit",()=>Er(n))}function U(n){return Bn||(Bn=new wt(n)),Bn}var Ca,va,wt,Wn,Gn,Pr,xa,Bn,ne=w(()=>{"use strict";Ca=120,va={enabled:!0,failureThreshold:3,probeIntervalMinutes:5,halfOpenSuccessThreshold:2},wt=class{states=new Map;config;probeTimer;constructor(e){this.config={...va,...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}=(Rt(),ra(wr));o().clearByPrimary(e,t)}catch{}}recordFailure(e,t,o){if(!this.config.enabled)return;let r=this.getKey(e,t);if(!r)return;let s=this.states.get(r);s||(s={provider:e,model:t,status:"closed",failureCount:0,successCount:0,lastFailureTime:0,lastProbeTime:0},this.states.set(r,s)),s.failureCount++,s.lastFailureTime=Date.now(),s.lastError=o,s.status==="half-open"?(s.status="open",s.successCount=0,s.lastProbeTime=0):s.status==="closed"&&s.failureCount>=this.config.failureThreshold&&(s.status="open",s.lastProbeTime=0)}getState(e,t){let o=this.getKey(e,t);if(o)return this.states.get(o)}isAvailable(e,t){if(!this.config.enabled)return!0;if(!this.getKey(e,t))return!1;let r=this.getState(e,t);return r?r.status==="open"&&r.rateLimitUntil?!(Date.now()<r.rateLimitUntil):r.status!=="open":!0}getPriority(e,t){if(!this.config.enabled)return 0;if(!this.getKey(e,t))return 2;let r=this.getState(e,t);if(!r)return 0;switch(r.status){case"closed":return 0;case"half-open":return 1;case"open":return 2}}getHealthyModels(){return[]}getFailPoolModels(){let e=[];for(let[t,o]of this.states)o.status==="open"&&e.push(t);return e}getHalfOpenModels(){let e=[];for(let[t,o]of this.states)o.status==="half-open"&&e.push(t);return e}forceOpen(e,t,o){if(!this.config.enabled)return;let r=this.getKey(e,t);if(!r)return;let s=this.states.get(r);s?(s.status="open",s.failureCount=Math.max(s.failureCount,this.config.failureThreshold),s.lastFailureTime=Date.now(),s.lastError=o,s.lastProbeTime=0):(s={provider:e,model:t,status:"open",failureCount:this.config.failureThreshold,successCount:0,lastFailureTime:Date.now(),lastProbeTime:0,lastError:o},this.states.set(r,s))}markRateLimited(e,t,o,r){if(!this.config.enabled)return;let s=this.getKey(e,t);if(!s)return;let i=this.states.get(s);i?(i.status="open",i.lastFailureTime=Date.now(),i.lastError=r||"rate-limited",i.lastProbeTime=0):(i={provider:e,model:t,status:"open",failureCount:0,successCount:0,lastFailureTime:Date.now(),lastProbeTime:0,lastError:r||"rate-limited"},this.states.set(s,i));let l=(o??Ca)*1e3;i.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=Ar(Ta,"runtime"),Gn=Ar(Wn,"provider-health.json"),Pr=!1,xa=null;Bn=null});import{existsSync as Lr,mkdirSync as Ra,readFileSync as wa,writeFileSync as Pa}from"fs";import{join as Dr}from"path";import{HOME_DIR as Ea}from"@wengine-ai/claude-code-router-shared";function Ke(n,e,t){let o=l=>{if(t instanceof Headers)return t.get(l);let a=Object.keys(t).find(c=>c.toLowerCase()===l);return a?t[a]:null},r=Qn(o,Oa),s=Qn(o,Aa),i=Qn(o,Ia);(r||s||i)&&xe.set(n,{provider:n,remaining:$r(r),limit:$r(s),reset:$a(i),capturedAt:Date.now()})}function Ma(n){return xe.get(n)}function Xn(){return Array.from(xe.values())}function Qn(n,e){for(let t of e){let o=n(t);if(o)return o}return null}function $r(n){if(!n)return null;let e=Number(n.trim().replace(/,/g,""));return Number.isFinite(e)?e:null}function $a(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=Na(e);return r===null?null:Math.floor((Date.now()+r)/1e3)}function Na(n){let e=/(\d+(?:\.\d+)?)(ms|s|m|h|d)/gi,t=0,o=!1;for(let r of n.matchAll(e)){o=!0;let s=Number(r[1]),i=r[2].toLowerCase();if(Number.isFinite(s))switch(i){case"ms":t+=s;break;case"s":t+=s*1e3;break;case"m":t+=s*60*1e3;break;case"h":t+=s*60*60*1e3;break;case"d":t+=s*24*60*60*1e3;break}}return o?t:null}function La(){try{if(!Lr(Yn))return;let n=JSON.parse(wa(Yn,"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;xe.set(t.provider,t)}}catch{}}function Nr(){try{if(xe.size===0)return;Lr(Vn)||Ra(Vn,{recursive:!0}),Pa(Yn,JSON.stringify(Array.from(xe.values()),null,2),"utf-8")}catch{}}function Qe(){Ir||(Ir=!0,La(),Mr=setInterval(Nr,6e4),Mr.unref?.(),process.on("exit",Nr))}var Vn,Yn,xe,Ir,Mr,Oa,Aa,Ia,Se=w(()=>{"use strict";Vn=Dr(Ea,"runtime"),Yn=Dr(Vn,"rate-limit.json"),xe=new Map,Ir=!1,Mr=null,Oa=["x-ratelimit-remaining-tokens","x-ratelimit-remaining-requests","x-ratelimit-remaining"],Aa=["x-ratelimit-limit-tokens","x-ratelimit-limit-requests","x-ratelimit-limit"],Ia=["x-ratelimit-reset-tokens","x-ratelimit-reset-requests","x-ratelimit-reset"]});async function F(n){let e=await n.text();return Da(e,n.status)}function Da(n,e){let t=n.replace(/^/,"").trim();try{return JSON.parse(t)}catch{let o=t.length>200?`${t.slice(0,200)}...`:t,r=e!==void 0?` (HTTP ${e})`:"";throw new Error(`Upstream returned a non-JSON response${r}: ${o||"(empty body)"}`)}}function Fr(n){return(n.headers.get("Content-Type")||"").includes("text/event-stream")}var Q=w(()=>{"use strict"});var Re,qn=w(()=>{"use strict";Q();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 i="";typeof s=="string"?i=s:s&&typeof s=="object"&&"text"in s&&(i=s.text),t.push({role:"system",content:i})}):e.instructions=r.content}if(e.messages.forEach(r=>{if(r.role!=="system"){if(Array.isArray(r.content)){let s=r.content.map(i=>this.normalizeRequestContent(i,r.role)).filter(i=>i!==null);s.length>0?r.content=s:delete r.content}if(r.role==="tool"){let s={...r};s.type="function_call_output",s.call_id=r.tool_call_id,s.output=r.content,delete s.cache_control,delete s.role,delete s.tool_call_id,delete s.content,t.push(s);return}if(r.role==="assistant"&&Array.isArray(r.tool_calls)){r.tool_calls.forEach(s=>{t.push({type:"function_call",arguments:s.function.arguments,name:s.function.name,call_id:s.id})});return}t.push(r)}}),e.input=t,delete e.messages,Array.isArray(e.tools)){let r=e.tools.find(s=>s.function.name==="web_search");e.tools=e.tools.filter(s=>s.function.name!=="web_search").map(s=>(s.function.name==="WebSearch"&&delete s.function.parameters.properties.allowed_domains,s.function.name==="Edit"?{type:s.type,name:s.function.name,description:s.function.description,parameters:{...s.function.parameters,required:["file_path","old_string","new_string","replace_all"]},strict:!0}:{type:s.type,name:s.function.name,description:s.function.description,parameters:s.function.parameters})),r&&e.tools.push({type:"web_search"})}return e.parallel_tool_calls=!1,e}async transformResponseOut(e){let t=e.headers.get("Content-Type")||"";if(t.includes("application/json")){let o=await F(e);if(o.object==="response"&&o.output){let r=this.convertResponseToChat(o);return new Response(JSON.stringify(r),{status:e.status,statusText:e.statusText,headers:e.headers})}return o.type==="message"&&Array.isArray(o.content)?new Response(JSON.stringify(o),{status:e.status,statusText:e.statusText,headers:e.headers}):new Response(JSON.stringify(o),{status:e.status,statusText:e.statusText,headers:e.headers})}else if(t.includes("text/event-stream")){if(!e.body)return e;let[o,r]=e.body.tee(),s=o.getReader(),i="";try{let{value:m,done:_}=await s.read();!_&&m&&(i=new TextDecoder().decode(m))}finally{s.releaseLock()}if(o.cancel().catch(()=>{}),i.includes("message_start")||i.includes("content_block_start")){let m=this.prependToStream(i,r);return new Response(m,{status:e.status,statusText:e.statusText,headers:e.headers})}if(i.includes("response.created")||i.includes("response.output_text.delta")||i.includes("response.in_progress")||i.includes("response.output_item.added")){let m=this.prependToStream(i,r);return new Response(m,{status:e.status,statusText:e.statusText,headers:e.headers})}let c=this.prependToStream(i,r),u=new TextDecoder,d=new TextEncoder,g="",f=!1,y=this,p=new ReadableStream({async start(m){let _=c.getReader(),k=-1,h="",b=T=>(T!==h&&(k++,h=T),k);try{for(;;){let{done:T,value:x}=await _.read();if(T){f||m.enqueue(d.encode(`data: [DONE]
|
|
5
5
|
|
|
6
|
-
`));break}let v=u.decode(x,{stream:!0});g+=v;let S=g.split(/\r?\n/);g=S.pop()||"";for(let C of S)if(C.trim())try{if(C.startsWith("event: "))continue;if(C.startsWith("data: ")){let P=C.slice(5).trim();if(P==="[DONE]"){
|
|
6
|
+
`));break}let v=u.decode(x,{stream:!0});g+=v;let S=g.split(/\r?\n/);g=S.pop()||"";for(let C of S)if(C.trim())try{if(C.startsWith("event: "))continue;if(C.startsWith("data: ")){let P=C.slice(5).trim();if(P==="[DONE]"){f=!0,m.enqueue(d.encode(`data: [DONE]
|
|
7
7
|
|
|
8
|
-
`));continue}try{let R=JSON.parse(P);if(R.type==="response.output_text.delta"){let O={id:R.item_id||"chatcmpl-"+Date.now(),object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:R.response?.model,choices:[{index:b(R.type),delta:{content:R.delta||""},finish_reason:null}]};
|
|
8
|
+
`));continue}try{let R=JSON.parse(P);if(R.type==="response.output_text.delta"){let O={id:R.item_id||"chatcmpl-"+Date.now(),object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:R.response?.model,choices:[{index:b(R.type),delta:{content:R.delta||""},finish_reason:null}]};m.enqueue(d.encode(`data: ${JSON.stringify(O)}
|
|
9
9
|
|
|
10
|
-
`))}else if(R.type==="response.output_item.added"&&R.item?.type==="function_call"){let O={id:R.item.call_id||R.item.id||"chatcmpl-"+Date.now(),object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:R.response?.model||"gpt-5-codex-",choices:[{index:b(R.type),delta:{role:"assistant",tool_calls:[{index:0,id:R.item.call_id||R.item.id,function:{name:R.item.name||"",arguments:""},type:"function"}]},finish_reason:null}]};
|
|
10
|
+
`))}else if(R.type==="response.output_item.added"&&R.item?.type==="function_call"){let O={id:R.item.call_id||R.item.id||"chatcmpl-"+Date.now(),object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:R.response?.model||"gpt-5-codex-",choices:[{index:b(R.type),delta:{role:"assistant",tool_calls:[{index:0,id:R.item.call_id||R.item.id,function:{name:R.item.name||"",arguments:""},type:"function"}]},finish_reason:null}]};m.enqueue(d.encode(`data: ${JSON.stringify(O)}
|
|
11
11
|
|
|
12
|
-
`))}else if(R.type==="response.output_item.added"&&R.item?.type==="message"){let O=[];(R.item.content||[]).forEach(A=>{A.type==="output_text"&&O.push({type:"text",text:A.text||""})});let E={role:"assistant"};if(O.length===1&&O[0].type==="text"?E.content=O[0].text:O.length>0&&(E.content=O),E.content){let A={id:R.item.id||"chatcmpl-"+Date.now(),object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:R.response?.model,choices:[{index:b(R.type),delta:E,finish_reason:null}]};
|
|
12
|
+
`))}else if(R.type==="response.output_item.added"&&R.item?.type==="message"){let O=[];(R.item.content||[]).forEach(A=>{A.type==="output_text"&&O.push({type:"text",text:A.text||""})});let E={role:"assistant"};if(O.length===1&&O[0].type==="text"?E.content=O[0].text:O.length>0&&(E.content=O),E.content){let A={id:R.item.id||"chatcmpl-"+Date.now(),object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:R.response?.model,choices:[{index:b(R.type),delta:E,finish_reason:null}]};m.enqueue(d.encode(`data: ${JSON.stringify(A)}
|
|
13
13
|
|
|
14
|
-
`))}}else if(R.type==="response.output_text.annotation.added"){let O={id:R.item_id||"chatcmpl-"+Date.now(),object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:R.response?.model||"gpt-5-codex",choices:[{index:b(R.type),delta:{annotations:[{type:"url_citation",url_citation:{url:R.annotation?.url||"",title:R.annotation?.title||"",content:"",start_index:R.annotation?.start_index||0,end_index:R.annotation?.end_index||0}}]},finish_reason:null}]};
|
|
14
|
+
`))}}else if(R.type==="response.output_text.annotation.added"){let O={id:R.item_id||"chatcmpl-"+Date.now(),object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:R.response?.model||"gpt-5-codex",choices:[{index:b(R.type),delta:{annotations:[{type:"url_citation",url_citation:{url:R.annotation?.url||"",title:R.annotation?.title||"",content:"",start_index:R.annotation?.start_index||0,end_index:R.annotation?.end_index||0}}]},finish_reason:null}]};m.enqueue(d.encode(`data: ${JSON.stringify(O)}
|
|
15
15
|
|
|
16
|
-
`))}else if(R.type==="response.function_call_arguments.delta"){let O={id:R.item_id||"chatcmpl-"+Date.now(),object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:R.response?.model||"gpt-5-codex-",choices:[{index:b(R.type),delta:{tool_calls:[{index:0,function:{arguments:R.delta||""}}]},finish_reason:null}]};
|
|
16
|
+
`))}else if(R.type==="response.function_call_arguments.delta"){let O={id:R.item_id||"chatcmpl-"+Date.now(),object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:R.response?.model||"gpt-5-codex-",choices:[{index:b(R.type),delta:{tool_calls:[{index:0,function:{arguments:R.delta||""}}]},finish_reason:null}]};m.enqueue(d.encode(`data: ${JSON.stringify(O)}
|
|
17
17
|
|
|
18
|
-
`))}else if(R.type==="response.completed"){let O=R.response?.output?.some(A=>A.type==="function_call")?"tool_calls":"stop",E={id:R.response?.id||"chatcmpl-"+Date.now(),object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:R.response?.model||"gpt-5-codex-",choices:[{index:0,delta:{},finish_reason:O}]};
|
|
18
|
+
`))}else if(R.type==="response.completed"){let O=R.response?.output?.some(A=>A.type==="function_call")?"tool_calls":"stop",E={id:R.response?.id||"chatcmpl-"+Date.now(),object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:R.response?.model||"gpt-5-codex-",choices:[{index:0,delta:{},finish_reason:O}]};m.enqueue(d.encode(`data: ${JSON.stringify(E)}
|
|
19
19
|
|
|
20
|
-
`)),
|
|
20
|
+
`)),f=!0}else if(R.type==="response.reasoning_summary_text.delta"){let O={id:R.item_id||"chatcmpl-"+Date.now(),object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:R.response?.model,choices:[{index:b(R.type),delta:{thinking:{content:R.delta||""}},finish_reason:null}]};m.enqueue(d.encode(`data: ${JSON.stringify(O)}
|
|
21
21
|
|
|
22
|
-
`))}else if(R.type==="response.reasoning_summary_part.done"&&R.part){let O={id:R.item_id||"chatcmpl-"+Date.now(),object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:R.response?.model,choices:[{index:k,delta:{thinking:{signature:R.item_id}},finish_reason:null}]};
|
|
22
|
+
`))}else if(R.type==="response.reasoning_summary_part.done"&&R.part){let O={id:R.item_id||"chatcmpl-"+Date.now(),object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:R.response?.model,choices:[{index:k,delta:{thinking:{signature:R.item_id}},finish_reason:null}]};m.enqueue(d.encode(`data: ${JSON.stringify(O)}
|
|
23
23
|
|
|
24
|
-
`))}}catch{
|
|
25
|
-
`))}}else
|
|
26
|
-
`))}catch(P){console.error("Error processing line:",C,P),
|
|
27
|
-
`))}}g.trim()&&
|
|
28
|
-
`)),m
|
|
24
|
+
`))}}catch{m.enqueue(d.encode(C+`
|
|
25
|
+
`))}}else m.enqueue(d.encode(C+`
|
|
26
|
+
`))}catch(P){console.error("Error processing line:",C,P),m.enqueue(d.encode(C+`
|
|
27
|
+
`))}}g.trim()&&m.enqueue(d.encode(g+`
|
|
28
|
+
`)),f||m.enqueue(d.encode(`data: [DONE]
|
|
29
29
|
|
|
30
|
-
`))}catch(T){console.error("Stream error:",T),
|
|
31
|
-
data: ${JSON.stringify(
|
|
30
|
+
`))}catch(T){console.error("Stream error:",T),m.error(T)}finally{try{_.releaseLock()}catch(T){console.error("Error releasing reader lock:",T)}m.close()}}});return new Response(p,{status:e.status,statusText:e.statusText,headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","Access-Control-Allow-Origin":"*"}})}return e}normalizeRequestContent(e,t){let o={...e};if(delete o.cache_control,e.type==="text")return{type:t==="assistant"?"output_text":"input_text",text:e.text};if(e.type==="image_url"){console.log(e);let r={type:t==="assistant"?"output_image":"input_image"};return typeof e.image_url?.url=="string"&&(r.image_url=e.image_url.url),r}return null}async transformResponseIn(e,t){if(e.headers.get("Content-Type")?.includes("text/event-stream")&&e.body){let[r,s]=e.body.tee(),i=r.getReader(),l="";try{let{value:g,done:f}=await i.read();!f&&g&&(l=new TextDecoder().decode(g))}finally{i.releaseLock()}r.cancel().catch(()=>{});let a=l.includes("message_start")||l.includes("content_block_start"),c=l.includes("chat.completion.chunk");if(l.includes("response.created")||l.includes("response.output_text.delta")||l.includes("response.in_progress")||l.includes("response.output_item.added"))return new Response(s,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}});if(c&&!a){let g=this.convertOpenAIChatStreamToResponsesAPI(s,t);return new Response(g,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}let d=this.convertAnthropicStreamToResponsesAPI(s,t);return new Response(d,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}try{let r=await F(e);return new Response(JSON.stringify(this.wrapChatInResponses(r)),{headers:{"Content-Type":"application/json"}})}catch{return e}}prependToStream(e,t){let r=new TextEncoder().encode(e),s=t.getReader(),i=!1;return new ReadableStream({async pull(l){i||(i=!0,l.enqueue(r));try{let{done:a,value:c}=await s.read();a?l.close():l.enqueue(c)}catch(a){l.error(a)}},cancel(){s.cancel().catch(()=>{})}})}convertOpenAIChatStreamToResponsesAPI(e,t){let o=new TextDecoder,r=new TextEncoder,s=t?.provider?.models?.[0]||"gpt-5.4",i=`resp_${Date.now()}`,l=0,a=!1,c=!1,u="",d=-1,g=[],f=(p,m)=>r.encode(`event: ${p}
|
|
31
|
+
data: ${JSON.stringify(m)}
|
|
32
32
|
|
|
33
|
-
`),y=(p,
|
|
33
|
+
`),y=(p,m=[])=>({id:i,object:"response",created_at:Math.floor(Date.now()/1e3),status:p,model:s,output:m,usage:this.buildResponsesUsage()});return new ReadableStream({async start(p){try{let m=e.getReader(),_="",k=!1,h=b=>{if(!k){k=!0;for(let T of g)if(T.type==="function_call"){let x=g.indexOf(T);p.enqueue(f("response.function_call_arguments.done",{type:"response.function_call_arguments.done",item_id:T.call_id||T.id,output_index:x,arguments:T.arguments||""})),T.status="completed",p.enqueue(f("response.output_item.done",{type:"response.output_item.done",output_index:x,item:T}))}for(let T of g)if(T.type==="message"){let x=g.indexOf(T);T.status="completed",p.enqueue(f("response.output_item.done",{type:"response.output_item.done",output_index:x,item:T}))}p.enqueue(f("response.completed",{type:"response.completed",response:{id:i,object:"response",created_at:Math.floor(Date.now()/1e3),status:"completed",model:b?.model||s,output:g.slice(),usage:b?.usage?{...this.buildResponsesUsage(b.usage)}:this.buildResponsesUsage()}}))}};for(;;){let{done:b,value:T}=await m.read();if(b)break;_+=o.decode(T,{stream:!0});let x=_.split(`
|
|
34
34
|
`);_=x.pop()||"";for(let v of x){let S=v.trim();if(!S||S.startsWith("event:")||!S.startsWith("data:"))continue;let C=S.slice(5).trim();if(C==="[DONE]"){h({}),p.enqueue(r.encode(`data: [DONE]
|
|
35
35
|
|
|
36
|
-
`));continue}let P;try{P=JSON.parse(C)}catch{continue}a||(a=!0,p.enqueue(
|
|
36
|
+
`));continue}let P;try{P=JSON.parse(C)}catch{continue}a||(a=!0,p.enqueue(f("response.created",{type:"response.created",response:y("in_progress")})),p.enqueue(f("response.in_progress",{type:"response.in_progress",response:y("in_progress")})));let R=P.choices?.[0];if(!R)continue;let O=R.delta;if(O?.content){if(!c){c=!0;let E=l++,A={id:`${i}_msg`,type:"message",status:"in_progress",role:"assistant",content:[]};g.push(A),p.enqueue(f("response.output_item.added",{type:"response.output_item.added",output_index:E,item:A}))}p.enqueue(f("response.output_text.delta",{type:"response.output_text.delta",item_id:`${i}_msg`,output_index:l-1,content_index:0,delta:O.content}))}if(Array.isArray(O?.tool_calls))for(let E of O.tool_calls){if(E.id){u=E.id,d=l++;let A={id:E.id,type:"function_call",status:"in_progress",call_id:E.id,name:E.function?.name||"",arguments:""};g.push(A),p.enqueue(f("response.output_item.added",{type:"response.output_item.added",output_index:d,item:A}))}if(E.function?.arguments){p.enqueue(f("response.function_call_arguments.delta",{type:"response.function_call_arguments.delta",item_id:u,output_index:d,delta:E.function.arguments}));let A=g.find(N=>N.call_id===u);A&&(A.arguments+=E.function.arguments)}}R.finish_reason&&h(P)}}k||h({}),p.close()}catch(m){p.error(m)}}})}convertAnthropicStreamToResponsesAPI(e,t){let o=new TextDecoder,r=new TextEncoder,s=t?.provider?.models?.[0]||"gpt-5.4",i=`resp_${Date.now()}`,l="",a="",c=-1,u="",d="",g="",f=-1,y="",p="",m=-1,_=0,k=!1,h=!1,b=!1,T=!1,x=null,v=[],S=(A,N)=>r.encode(`event: ${A}
|
|
37
37
|
data: ${JSON.stringify(N)}
|
|
38
38
|
|
|
39
|
-
`),C=(A,N=[])=>({id:i,object:"response",created_at:Math.floor(Date.now()/1e3),status:A,model:s,output:N,usage:this.buildResponsesUsage()}),P=()=>{k||(k=!0,E.enqueue(S("response.created",{type:"response.created",response:C("in_progress")})),E.enqueue(S("response.in_progress",{type:"response.in_progress",response:C("in_progress")})))},R=(A,N)=>{E.enqueue(S("response.output_item.done",{type:"response.output_item.done",output_index:A,item:{...N,status:"completed"}}))},O=A=>{if(!T){if(T=!0,h){let N=v.find(D=>D.type==="message");N&&(N.content=[{type:"output_text",text:l}],N.status="completed")}for(let N of v)N.type==="function_call"&&(N.status="completed");return S("response.completed",{type:"response.completed",response:{id:i,object:"response",created_at:Math.floor(Date.now()/1e3),status:"completed",model:s,output:v,usage:A?{...this.buildResponsesUsage(A)}:this.buildResponsesUsage()}})}},E;return new ReadableStream({async start(A){E=A;try{let N=e.getReader(),D="";for(;;){let{done:$,value:L}=await N.read();if($)break;D+=o.decode(L,{stream:!0});let
|
|
40
|
-
`);D=
|
|
39
|
+
`),C=(A,N=[])=>({id:i,object:"response",created_at:Math.floor(Date.now()/1e3),status:A,model:s,output:N,usage:this.buildResponsesUsage()}),P=()=>{k||(k=!0,E.enqueue(S("response.created",{type:"response.created",response:C("in_progress")})),E.enqueue(S("response.in_progress",{type:"response.in_progress",response:C("in_progress")})))},R=(A,N)=>{E.enqueue(S("response.output_item.done",{type:"response.output_item.done",output_index:A,item:{...N,status:"completed"}}))},O=A=>{if(!T){if(T=!0,h){let N=v.find(D=>D.type==="message");N&&(N.content=[{type:"output_text",text:l}],N.status="completed")}for(let N of v)N.type==="function_call"&&(N.status="completed");return S("response.completed",{type:"response.completed",response:{id:i,object:"response",created_at:Math.floor(Date.now()/1e3),status:"completed",model:s,output:v,usage:A?{...this.buildResponsesUsage(A)}:this.buildResponsesUsage()}})}},E;return new ReadableStream({async start(A){E=A;try{let N=e.getReader(),D="";for(;;){let{done:$,value:L}=await N.read();if($)break;D+=o.decode(L,{stream:!0});let W=D.split(`
|
|
40
|
+
`);D=W.pop()||"";for(let ge of W){let j=ge.trim();if(!j||j.startsWith("event:")||!j.startsWith("data:"))continue;let Y=j.slice(5).trim();if(Y==="[DONE]")continue;let z;try{z=JSON.parse(Y)}catch{continue}if(z.type==="message_start"&&(i=z.message?.id||i,P()),z.type==="content_block_start"){let I=z.content_block;if(x=I?.type||null,I?.type==="tool_use"){u=I.id||"",d=I.name||"",g="",f=_++;let J={id:u,type:"function_call",status:"in_progress",call_id:u,name:d,arguments:""};v.push(J),E.enqueue(S("response.output_item.added",{type:"response.output_item.added",output_index:f,item:J}))}if(I?.type==="thinking"&&(y=I.thinking||"",!b)){b=!0,m=_++,p=`rs_${i}`;let J={id:p,type:"reasoning",status:"in_progress",summary:[]};v.push(J),E.enqueue(S("response.output_item.added",{type:"response.output_item.added",output_index:m,item:J}))}if(I?.type==="text"&&(l=I?.text||"",!h)){h=!0,c=_++,a=`${i}_msg`;let J={id:a,type:"message",status:"in_progress",role:"assistant",content:[]};v.push(J),E.enqueue(S("response.output_item.added",{type:"response.output_item.added",output_index:c,item:J}))}}if(z.type==="content_block_delta"){let I=z.delta;if(I?.type==="text_delta"){if(!h){h=!0,c=_++,a=`${i}_msg`;let J={id:a,type:"message",status:"in_progress",role:"assistant",content:[]};v.push(J),E.enqueue(S("response.output_item.added",{type:"response.output_item.added",output_index:c,item:J}))}l+=I.text||"",E.enqueue(S("response.output_text.delta",{type:"response.output_text.delta",item_id:a,output_index:c,content_index:0,delta:I.text||""}))}I?.type==="thinking_delta"&&(y+=I.thinking||"",E.enqueue(S("response.reasoning_summary_text.delta",{type:"response.reasoning_summary_text.delta",item_id:p||`rs_${i}`,output_index:m>=0?m:0,summary_index:0,delta:I.thinking||""}))),I?.type==="input_json_delta"&&(g+=I.partial_json||"",E.enqueue(S("response.function_call_arguments.delta",{type:"response.function_call_arguments.delta",item_id:u||"call_0",output_index:f>=0?f:0,delta:I.partial_json||""})))}if(z.type==="content_block_stop"){if(x==="tool_use"&&u){E.enqueue(S("response.function_call_arguments.done",{type:"response.function_call_arguments.done",item_id:u,output_index:f,arguments:g}));let I=v.find(J=>J.call_id===u);I&&(I.arguments=g,I.status="completed"),I&&R(f,I)}if(x==="text"&&h){E.enqueue(S("response.output_text.done",{type:"response.output_text.done",item_id:a,output_index:c,content_index:0,text:l}));let I=v.find(J=>J.type==="message");I&&(I.content=[{type:"output_text",text:l}],R(c,I))}if(x==="thinking"&&b){let I=v.find(J=>J.type==="reasoning");I&&(I.summary=[{type:"summary_text",text:y}],R(m,I))}x=null}if(z.type==="message_delta"){let I=O(z.usage);I&&E.enqueue(I)}if(z.type==="message_stop"){let I=O();I&&E.enqueue(I),E.enqueue(r.encode(`data: [DONE]
|
|
41
41
|
|
|
42
|
-
`))}}}P();let j=O();j&&E.enqueue(j),D="",E.close()}catch(N){E.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(c=>c.type==="message"),o=e.output?.find(c=>c.type==="function_call"),r;t?.content?.length&&t?.content[0].annotations&&(r=t.content[0].annotations.map(c=>({type:"url_citation",url_citation:{url:c.url||"",title:c.title||"",content:"",start_index:c.start_index||0,end_index:c.end_index||0}}))),this.logger.debug({data:r,type:"url_citation"});let s=null,i=null,l=null;if(t&&t.reasoning&&(l={content:t.reasoning}),t&&t.content){let c=[],u=[];if(t.content.forEach(d=>{if(d.type==="output_text")c.push(d.text||"");else if(d.type==="output_image"){let g=this.buildImageContent({url:d.image_url,mime_type:d.mime_type});g&&u.push(g)}else if(d.type==="output_image_base64"){let g=this.buildImageContent({b64_json:d.image_base64,mime_type:d.mime_type});g&&u.push(g)}}),u.length>0){let d=[];c.length>0&&d.push({type:"text",text:c.join("")}),d.push(...u),s=d}else s=c.join("")}return o&&(i=[{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:i,thinking:l,annotations:r},logprobs:null,finish_reason:i?"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 Xn,V,Rt=w(()=>{"use strict";Xn=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)}},V=new Xn(100)});import{existsSync as Ur,mkdirSync as $a,readFileSync as Na,writeFileSync as La}from"fs";import{join as jr}from"path";import{HOME_DIR as Da}from"@wengine-ai/claude-code-router-shared";function eo(n,e){n&&Se.set(n,{...e,provider:n,capturedAt:Date.now()})}function wt(n){let e=Se.get(n);return e?{...e}:void 0}function to(){return Array.from(Se.values()).map(n=>({...n}))}function Fa(){try{if(!Ur(Zn))return;let n=JSON.parse(Na(Zn,"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 Fr(){try{if(Se.size===0)return;Ur(qn)||$a(qn,{recursive:!0}),La(Zn,JSON.stringify(Array.from(Se.values()),null,2),"utf-8")}catch{}}function Ke(){Lr||(Lr=!0,Fa(),Dr=setInterval(Fr,6e4),Dr.unref?.(),process.on("exit",Fr))}var qn,Zn,Se,Lr,Dr,Re=w(()=>{"use strict";qn=jr(Da,"runtime"),Zn=jr(qn,"quota-store.json"),Se=new Map,Lr=!1,Dr=null});function we(n){if(typeof n!="string")return;let e=n.trim();if(!(!e||!Ua.test(e)))return e}function Qe(n){if(!n)return;if(typeof n=="object")return we(n.session_id??n.sessionId);if(typeof n!="string")return;let e=n.trim();if(!e)return;try{let r=JSON.parse(e),s=we(r?.session_id??r?.sessionId);if(s)return s}catch{}let t="_session_",o=e.lastIndexOf(t);if(o!==-1)return we(e.slice(o+t.length))}var Ua,Ve=w(()=>{"use strict";Ua=/^[A-Za-z0-9_-]+$/});import{randomUUID as ja}from"node:crypto";function za(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 Ba(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 Hr(n,e,t=!0){let o=Qe(n?.body?.metadata?.user_id);return{clientType:e,usageScope:o?"session":"request",stableSessionId:o,supportsExplicitExtendedContext:t}}function Br(n){return typeof n=="string"&&Ha.includes(n)}function Pe(n){if(Br(n?.clientType))return n.clientType;let e=Ba(n),t=n?.headers||{},o=typeof t["user-agent"]=="string"?t["user-agent"]:"",r=n?.body||{},s=za(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 i=t["x-anthropic-billing-header"];if(typeof i=="string"&&i.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 Jr(n){return zr[n]}function Xa(n){if(typeof n?.__ccrRequestScopeId=="string"&&n.__ccrRequestScopeId)return n.__ccrRequestScopeId;let e=typeof n?.id=="string"&&n.id||ja();return n.__ccrRequestScopeId=e,e}function ge(n,e={}){let t=Pe(n),o=Jr(t).createContext(n,e),r=o.stableSessionId||Xa(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 qa(){}var Ha,Ja,Wa,Ga,Ka,Qa,Va,Ya,zr,Ee=w(()=>{"use strict";Ve();Ha=["claude-code","pi","qwen-code","opencode","codex","api","unknown"];Ja={type:"claude-code",createContext(n){return Hr(n,"claude-code")}},Wa={type:"pi",createContext(){return Ye("pi",!1)}},Ga={type:"qwen-code",createContext(n){return Hr(n,"qwen-code")}},Ka={type:"opencode",createContext(){return Ye("opencode")}},Qa={type:"codex",createContext(){return Ye("codex")}},Va={type:"api",createContext(){return Ye("api")}},Ya={type:"unknown",createContext(){return Ye("unknown")}},zr={"claude-code":Ja,pi:Wa,"qwen-code":Ga,opencode:Ka,codex:Qa,api:Va,unknown:Ya}});import{get_encoding as Za}from"tiktoken";import{readFile as no}from"fs/promises";import{opendir as ec,stat as tc}from"fs/promises";import{join as oo}from"path";import{CLAUDE_PROJECTS_DIR as Wr,HOME_DIR as Gr}from"@wengine-ai/claude-code-router-shared";function Y(n,e,t,o){let r=Xr(e,t);if(r.code==="model_unhealthy"){let l=G(e,t,!0);if(l)return n.log.warn(`Strict project target ${e} is in the health fail-pool; retrying it anyway (no fallback available). scenario=${o}`),l}let s=n.sessionId||n.clientContext?.stableSessionId,i=Yr[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:i})}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 qe(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 oc(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}=qe(n);if(o&&e[o])return e[o];for(let[r,s]of Object.entries(e)){let i=Et(r);if(i&&t.includes(i))return s}return null}function rc(n){return n?(n.input_tokens||0)+(n.cache_read_input_tokens||0)+(n.cache_creation_input_tokens||0):0}function Pt(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 Xe(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 Xr(n,e){let t=Pt(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(c=>c.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 i=s.models?.find(c=>String(c).toLowerCase()===r.toLowerCase());if(!i)return{reason:`model "${r}" not found in provider "${o}"`,code:"model_not_found"};if(!F().isAvailable(s.name,String(i)))return{reason:`model "${r}" in provider "${o}" is temporarily unavailable (health fail-pool)`,code:"model_unhealthy"};let a=wt(s.name);if(a){let c=a.limitDaily!==void 0&&a.usedDailyBalance!==void 0&&a.usedDailyBalance>=a.limitDaily,u=a.totalBalance!==void 0&&a.usedBalance!==void 0&&a.usedBalance>=a.totalBalance;if(c||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,i){let l=Pt(n);if(!l)return i?null:n;let{providerName:a,routeModel:c}=l,u=Xe(e,a,c);if(!u){if(r===!0&&o&&!t&&s!==!1){let g=Te(),m=g.getPromotion(a,c,o,e);if(m){let y=Pt(m);if(y){let p=Xe(e,y.providerName,y.routeModel);if(p)return`${p.provider.name},${p.model}`}g.clear(a,c,o)}}return null}if(r===!0&&o&&!t&&s!==!1){let g=Te(),m=g.getPromotion(a,c,o,e);if(m){let y=Pt(m);if(y){let p=Xe(e,y.providerName,y.routeModel);if(p)return`${p.provider.name},${p.model}`}g.clear(a,c,o)}}if(!t&&!F().isAvailable(u.provider.name,u.model))return null;let d=wt(u.provider.name);if(d){let g=d.limitDaily!==void 0&&d.usedDailyBalance!==void 0&&d.usedDailyBalance>=d.limitDaily,m=d.totalBalance!==void 0&&d.usedBalance!==void 0&&d.usedBalance>=d.totalBalance;if(g||m)return null}return`${u.provider.name},${u.model}`}function K(n,e,t,o,r,s){let i=F(),l=[t?.[n],o?.[n]];for(let a of l)if(!(!Array.isArray(a)||a.length===0))for(let c of a){let u=G(c,e,!1,n,void 0,void 0,s);if(u)return u}return null}function sc(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 ro(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 qr(n,e,t){return t?.usageScope!=="session"?n:Math.max(n,rc(e))}function Zr(n,e,t){return n?.extendedContextThreshold??e?.extendedContextThreshold??t??2e5}function ic(n,e,t,o,r,s,i,l,a,c,u,d){let g=n.clientContext,m=g?.longContextThreshold??t.longContextThreshold??a??6e4,y=qr(e,r,g),p=n.modelFamily,f=Zr(g,t,c),_=g?.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 T=l?K("extendedContext",o,t.fallback,i,p,u):null;if(T)return n.log.info(`Family: using extended context fallback model (1M+), tokens: ${y}, estimated: ${e}, explicit: ${_}, threshold: ${f}`),{model:T,scenarioType:"extendedContext",isFallback:!0};if(u){let x=Y(n,t.extendedContext,o,"extendedContext");if(x)return{model:x,scenarioType:"extendedContext",isFallback:!1}}n.log.warn("Family: extendedContext model unavailable (fail pool), skipping")}if(y>m&&(t.longContext||t.fallback?.longContext?.length||i?.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 T=l?K("longContext",o,t.fallback,i,p,u):null;if(T)return n.log.info(`Family: using long context fallback model, tokens: ${y}, estimated: ${e}`),{model:T,scenarioType:"longContext",isFallback:!0};if(u&&t.longContext){let x=Y(n,t.longContext,o,"longContext");if(x)return{model:x,scenarioType:"longContext",isFallback:!1}}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 T=l?K("webSearch",o,t.fallback,i,p,u):null;if(T)return n.log.info("Family: using webSearch fallback model"),{model:T,scenarioType:"webSearch",isFallback:!0};if(u){let x=Y(n,t.webSearch,o,"webSearch");if(x)return{model:x,scenarioType:"webSearch",isFallback:!1}}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 T=l?K("think",o,t.fallback,i,p,u):null;if(T)return n.log.info("Family: using think fallback model"),{model:T,scenarioType:"think",isFallback:!0};if(u){let x=Y(n,t.think,o,"think");if(x)return{model:x,scenarioType:"think",isFallback:!1}}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 T=l?K("default",o,t.fallback,i,p,u):null;if(T)return n.log.info("Family: using default fallback model"),{model:T,scenarioType:"default",isFallback:!0};if(u){let x=Y(n,t.default,o,"default");if(x)return{model:x,scenarioType:"default",isFallback:!1}}n.log.warn("Family: default model unavailable (fail pool), skipping")}return null}function dc(){if(he.size<=Kr)return;let n=[...he.keys()].slice(0,he.size-Kr);for(let e of n)he.delete(e)}function pc(){if(Oe.size<=Qr)return;let n=[...Oe].slice(0,Oe.size-Qr);for(let e of n)Oe.delete(e)}var Yr,ae,ie,Ot,nc,ac,At,he,Kr,Oe,Qr,cc,lc,uc,Vr,es,Ae=w(()=>{"use strict";Rt();ee();Re();xt();Ve();Ee();Yr={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||Yr[t?.code||""]||502,this.code=t?.code||"project_routing_error",this.type="api_error",this.sessionId=t?.sessionId,this.configuredTarget=t?.configuredTarget}};ie=Za("cl100k_base"),Ot=(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 es(n.sessionId);if(t){let o=oo(Gr,t,"config.json"),r=oo(Gr,t,`${n.sessionId}.json`);try{let s=JSON.parse(await no(r,"utf8"));if(s&&s.Router&&Object.keys(s.Router).length>0)return s.Router}catch{}try{let s=JSON.parse(await no(o,"utf8"));if(s&&s.Router&&Object.keys(s.Router).length>0)return s.Router}catch(s){if(s&&s.code!=="ENOENT"){let i=n.sessionId||n.clientContext?.stableSessionId;throw new ae(`Project routing error: project config.json is malformed or unreadable in project "${t}". ${s.message}. Session: "${i||"unknown"}".`,{sessionId:i,configuredTarget:o,code:"project_config_error",statusCode:500})}}}}};ac=async(n,e,t,o,r,s)=>{let i=t.get("providers")||[],l=r||t.get("Router"),a=l?.enableFallback===!0,c=a?l?.fallback:void 0,u=a&&!s?c||t.get("fallback"):c,d=!s,g=null;if(n.body?.system?.length>1&&n.body?.system[1]?.text?.includes("<CCR-SUBAGENT-MODEL>")){let v=n.body?.system[1].text.match(/<CCR-SUBAGENT-MODEL>(.*?)<\/CCR-SUBAGENT-MODEL>/s);v&&(n.body.system[1].text=n.body.system[1].text.replace(`<CCR-SUBAGENT-MODEL>${v[1]}</CCR-SUBAGENT-MODEL>`,""),g=v[1])}let{family:m,extended:y,isCcrAlias:p}=qe(n.body.model),f=l?.families?.[m||""];if(f&&l?.enableFamilyRouting){n.log.info(`Using model family routing for: ${m}${y?" (1M)":""}`),n.modelFamily=m,n.familyFallback=f.fallback;let v=ic(n,e,f,i,o,y,u,a,l?.longContextThreshold,l?.extendedContextThreshold,s,d);if(v)return{model:v.model,scenarioType:v.scenarioType}}if(n.body.model.includes(",")&&!s){let v=G(n.body.model,i,!1,"default",a,d,s);if(v)return{model:v,scenarioType:"default"};n.log.warn(`Explicit model ${n.body.model} unavailable (fail pool), trying fallback`);let S=a?K("default",i,void 0,u,void 0,s):null;if(S)return n.log.info(`Using fallback for explicit model: ${S}`),{model:S,scenarioType:"default"};n.log.warn(`No fallback available for explicit model ${n.body.model}, continuing through routing logic`)}let _=p&&!l?.enableFamilyRouting?null:oc(n.body.model,l?.models);if(_){let v=G(_,i,!1,"modelMapping",a,d,s);if(v)return n.log.info(`Using mapped model for ${n.body.model}: ${_}`),{model:v,scenarioType:"modelMapping"};let S=a?K("modelMapping",i,void 0,u,void 0,s):null;if(S)return{model:S,scenarioType:"modelMapping"};if(s){let C=Y(n,_,i,"modelMapping");if(C)return{model:C,scenarioType:"modelMapping"}}n.log.warn(`Mapped model ${_} unavailable (fail pool), skipping`)}let k=n.clientContext,h=qr(e,o,k),b=Zr(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 v=G(l.extendedContext,i,!1,"extendedContext",a,d,s);if(v)return{model:v,scenarioType:"extendedContext"};n.log.warn(`Extended context model ${l.extendedContext} unavailable (fail pool), trying fallback`);let S=a?K("extendedContext",i,void 0,u,void 0,s):null;if(S)return{model:S,scenarioType:"extendedContext"};if(s){let C=Y(n,l.extendedContext,i,"extendedContext");if(C)return{model:C,scenarioType:"extendedContext"}}}let T=k?.longContextThreshold??l?.longContextThreshold??6e4;if(h>T&&l?.longContext){n.log.info(`Using long context model due to token count: ${h}, estimated: ${e}, threshold: ${T}`);let v=G(l.longContext,i,!1,"longContext",a,d,s);if(v)return{model:v,scenarioType:"longContext"};n.log.warn(`Long context model ${l.longContext} unavailable (fail pool), trying fallback`);let S=a?K("longContext",i,void 0,u,void 0,s):null;if(S)return{model:S,scenarioType:"longContext"};if(s){let C=Y(n,l.longContext,i,"longContext");if(C)return{model:C,scenarioType:"longContext"}}}if(!s&&g)return{model:g,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 v=G(l.background,i,!1,"background",a,d,s);if(v)return{model:v,scenarioType:"background"};let S=a?K("background",i,void 0,u,void 0,s):null;if(S)return{model:S,scenarioType:"background"};if(s){let C=Y(n,l.background,i,"background");if(C)return{model:C,scenarioType:"background"}}n.log.warn(`Background model ${l.background} unavailable (fail pool), falling through`)}if(Array.isArray(n.body.tools)&&n.body.tools.some(v=>v.type?.startsWith("web_search"))&&l?.webSearch){let v=G(l.webSearch,i,!1,"webSearch",a,d,s);if(v)return{model:v,scenarioType:"webSearch"};n.log.warn(`WebSearch model ${l.webSearch} unavailable (fail pool), trying fallback`);let S=a?K("webSearch",i,void 0,u,void 0,s):null;if(S)return{model:S,scenarioType:"webSearch"};if(s){let C=Y(n,l.webSearch,i,"webSearch");if(C)return{model:C,scenarioType:"webSearch"}}}if(n.body.thinking?.type==="enabled"&&l?.think){n.log.info(`Using think model for ${n.body.thinking}`);let v=G(l.think,i,!1,"think",a,d,s);if(v)return{model:v,scenarioType:"think"};n.log.warn(`Think model ${l.think} unavailable (fail pool), trying fallback`);let S=a?K("think",i,void 0,u,void 0,s):null;if(S)return{model:S,scenarioType:"think"};if(s){let C=Y(n,l.think,i,"think");if(C)return{model:C,scenarioType:"think"}}}if(l?.default){let v=G(l.default,i,!1,"default",a,d,s);if(v)return{model:v,scenarioType:"default"};n.log.warn(`Default model ${l.default} unavailable (fail pool), trying fallback`);let S=a?K("default",i,void 0,u,void 0,s):null;if(S)return{model:S,scenarioType:"default"};let C=G(l.default,i,!0,"default",a,d,s);if(C)return n.log.warn(`No fallback available; retrying default model ${l.default} despite fail-pool state (strict=${s})`),{model:C,scenarioType:"default"}}if(s){let v=Y(n,l?.default||n.body.model,i,"default");if(v)return{model:v,scenarioType:"default"}}return{model:void 0,scenarioType:"default"}},At=async(n,e,t)=>{let{configService:o,event:r}=t;!n.originalModel&&n.body.model&&(n.originalModel=n.body.model),ge(n,o.getAll());let s=await nc(n,o),i=s||o.get("Router"),l=i?.enableFallback===!0,a=o.get("providers")||[],c=!!s;n.enableFallback=l,n.strictProjectRouting=c,n.fallbackConfig=c?i?.fallback:i?.fallback||o.get("fallback");let u=n.clientContext?.usageScope==="session"?n.previousUsage??V.get(n.usageCacheKey):void 0,{messages:d,system:g=[],tools:m}=n.body,y=o.get("REWRITE_SYSTEM_PROMPT");if(y&&g.length>1&&g[1]?.text?.includes("<env>")){let p=await no(y,"utf-8");g[1].text=`${p}<env>${g[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:g,tools:m},_,p)).tokenCount:k=Ot(d,g,m),n.tokenCount=k;let h,b=c?void 0:o.get("CUSTOM_ROUTER_PATH");if(b)try{h=await Be(b)(n,o.getAll(),{event:r})}catch(S){n.log.error(`failed to load custom router: ${S.message}`)}if(h)n.scenarioType="default";else{let S=await ac(n,k,o,u,s,!!s);h=S.model,n.scenarioType=S.scenarioType}let{family:T}=qe(n.originalModel||n.body.model),x=i?.enableFamilyRouting&&T?i.families?.[T]:void 0,v=[x?.image,i?.image].filter((S,C,P)=>!!S&&P.indexOf(S)===C);if(v.length>0&&sc(n)&&!ro(h))if(v.includes(h))n.scenarioType="image";else{let S=v.map(C=>G(C,a,!1,"image",l,!c,c)).find(C=>!!C);if(S)n.log.info(`Using image model fallback for ${h}`),h=S,n.scenarioType="image";else{let C=l?K("image",a,x?.fallback,n.fallbackConfig,T||void 0,c):null;if(C)n.log.info(`Using image fallback model: ${C}`),h=C,n.scenarioType="image";else if(c){let P=Y(n,v[0],a,"image");P&&(h=P,n.scenarioType="image")}else n.log.warn(`Image models ${v.join(", ")} 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}`),c){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:i?.default,code:"project_router_failure",statusCode:502})}n.body.model=i?.default,n.scenarioType="default"}},he=new Map,Kr=1e3,Oe=new Set,Qr=1e3,cc=3,lc=50,uc=n=>new Promise(e=>setTimeout(e,n));Vr=async n=>{let e=await ec(Wr),t=[];for await(let s of e)s.isDirectory()&&t.push(s.name);let o=t.map(async s=>{let i=oo(Wr,s,`${n}.jsonl`);try{return(await tc(i)).isFile()?s:null}catch{return null}}),r=await Promise.all(o);for(let s of r)if(s)return s;return null},es=async n=>{let e=we(n);if(!e)return null;if(he.has(e))return he.get(e)||null;try{let t=await Vr(e);if(!t&&!Oe.has(e)){Oe.add(e),pc();for(let o=0;o<cc&&!t;o++)await uc(lc),t=await Vr(e)}return t?(he.set(e,t),dc(),t):null}catch(t){return console.error("Error searching for project by session:",t),null}}});function Ze(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
|
+
`))}}}P();let H=O();H&&E.enqueue(H),D="",E.close()}catch(N){E.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(c=>c.type==="message"),o=e.output?.find(c=>c.type==="function_call"),r;t?.content?.length&&t?.content[0].annotations&&(r=t.content[0].annotations.map(c=>({type:"url_citation",url_citation:{url:c.url||"",title:c.title||"",content:"",start_index:c.start_index||0,end_index:c.end_index||0}}))),this.logger.debug({data:r,type:"url_citation"});let s=null,i=null,l=null;if(t&&t.reasoning&&(l={content:t.reasoning}),t&&t.content){let c=[],u=[];if(t.content.forEach(d=>{if(d.type==="output_text")c.push(d.text||"");else if(d.type==="output_image"){let g=this.buildImageContent({url:d.image_url,mime_type:d.mime_type});g&&u.push(g)}else if(d.type==="output_image_base64"){let g=this.buildImageContent({b64_json:d.image_base64,mime_type:d.mime_type});g&&u.push(g)}}),u.length>0){let d=[];c.length>0&&d.push({type:"text",text:c.join("")}),d.push(...u),s=d}else s=c.join("")}return o&&(i=[{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:i,thinking:l,annotations:r},logprobs:null,finish_reason:i?"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=w(()=>{"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 zr,mkdirSync as Fa,readFileSync as Ua,writeFileSync as ja}from"fs";import{join as Jr}from"path";import{HOME_DIR as Ha}from"@wengine-ai/claude-code-router-shared";function no(n,e){n&&we.set(n,{...e,provider:n,capturedAt:Date.now()})}function Et(n){let e=we.get(n);return e?{...e}:void 0}function oo(){return Array.from(we.values()).map(n=>({...n}))}function za(){try{if(!zr(to))return;let n=JSON.parse(Ua(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 Hr(){try{if(we.size===0)return;zr(eo)||Fa(eo,{recursive:!0}),ja(to,JSON.stringify(Array.from(we.values()),null,2),"utf-8")}catch{}}function Ve(){Ur||(Ur=!0,za(),jr=setInterval(Hr,6e4),jr.unref?.(),process.on("exit",Hr))}var eo,to,we,Ur,jr,Pe=w(()=>{"use strict";eo=Jr(Ha,"runtime"),to=Jr(eo,"quota-store.json"),we=new Map,Ur=!1,jr=null});function Ee(n){if(typeof n!="string")return;let e=n.trim();if(!(!e||!Ja.test(e)))return e}function Ye(n){if(!n)return;if(typeof n=="object")return Ee(n.session_id??n.sessionId);if(typeof n!="string")return;let e=n.trim();if(!e)return;try{let r=JSON.parse(e),s=Ee(r?.session_id??r?.sessionId);if(s)return s}catch{}let t="_session_",o=e.lastIndexOf(t);if(o!==-1)return Ee(e.slice(o+t.length))}var Ja,Xe=w(()=>{"use strict";Ja=/^[A-Za-z0-9_-]+$/});import{randomUUID as Ba}from"node:crypto";function Ga(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 Ka(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 qe(n,e=!0){return{clientType:n,usageScope:"request",supportsExplicitExtendedContext:e}}function Br(n,e,t=!0){let o=Ye(n?.body?.metadata?.user_id);return{clientType:e,usageScope:o?"session":"request",stableSessionId:o,supportsExplicitExtendedContext:t}}function Gr(n){return typeof n=="string"&&Wa.includes(n)}function Oe(n){if(Gr(n?.clientType))return n.clientType;let e=Ka(n),t=n?.headers||{},o=typeof t["user-agent"]=="string"?t["user-agent"]:"",r=n?.body||{},s=Ga(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 i=t["x-anthropic-billing-header"];if(typeof i=="string"&&i.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 Wr[n]}function tc(n){if(typeof n?.__ccrRequestScopeId=="string"&&n.__ccrRequestScopeId)return n.__ccrRequestScopeId;let e=typeof n?.id=="string"&&n.id||Ba();return n.__ccrRequestScopeId=e,e}function ye(n,e={}){let t=Oe(n),o=Kr(t).createContext(n,e),r=o.stableSessionId||tc(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 nc(){}var Wa,Qa,Va,Ya,Xa,qa,Za,ec,Wr,Ae=w(()=>{"use strict";Xe();Wa=["claude-code","pi","qwen-code","opencode","codex","api","unknown"];Qa={type:"claude-code",createContext(n){return Br(n,"claude-code")}},Va={type:"pi",createContext(){return qe("pi",!1)}},Ya={type:"qwen-code",createContext(n){return Br(n,"qwen-code")}},Xa={type:"opencode",createContext(){return qe("opencode")}},qa={type:"codex",createContext(){return qe("codex")}},Za={type:"api",createContext(){return qe("api")}},ec={type:"unknown",createContext(){return qe("unknown")}},Wr={"claude-code":Qa,pi:Va,"qwen-code":Ya,opencode:Xa,codex:qa,api:Za,unknown:ec}});import{get_encoding as oc}from"tiktoken";import{readFile as ro}from"fs/promises";import{opendir as rc,stat as sc}from"fs/promises";import{join as so}from"path";import{CLAUDE_PROJECTS_DIR as Qr,HOME_DIR as Vr}from"@wengine-ai/claude-code-router-shared";function q(n,e,t,o){let r=es(e,t);if(r.code==="model_unhealthy"){let l=K(e,t,!0);if(l)return n.log.warn(`Strict project target ${e} is in the health fail-pool; retrying it anyway (no fallback available). scenario=${o}`),l}let s=n.sessionId||n.clientContext?.stableSessionId,i=Zr[r.code]||502;throw new le(`Project routing error (${o}): ${r.reason}. Project-level Router target: "${e}". Session: "${s||"unknown"}".`,{sessionId:s,configuredTarget:e,code:r.code,statusCode:i})}function At(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 et(n){let e=At(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 ac(n,e){if(!e||!n)return null;let t=At(n);if(e[n])return e[n];if(e[t])return e[t];let{family:o}=et(n);if(o&&e[o])return e[o];for(let[r,s]of Object.entries(e)){let i=At(r);if(i&&t.includes(i))return s}return null}function cc(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 es(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(c=>c.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 i=s.models?.find(c=>String(c).toLowerCase()===r.toLowerCase());if(!i)return{reason:`model "${r}" not found in provider "${o}"`,code:"model_not_found"};if(!U().isAvailable(s.name,String(i)))return{reason:`model "${r}" in provider "${o}" is temporarily unavailable (health fail-pool)`,code:"model_unhealthy"};let a=Et(s.name);if(a){let c=a.limitDaily!==void 0&&a.usedDailyBalance!==void 0&&a.usedDailyBalance>=a.limitDaily,u=a.totalBalance!==void 0&&a.usedBalance!==void 0&&a.usedBalance>=a.totalBalance;if(c||u)return{reason:`provider "${o}" quota is exhausted`,code:"quota_exhausted"}}return{reason:`unable to resolve model "${n}"`,code:"resolution_failed"}}function K(n,e,t,o,r,s,i){let l=Ot(n);if(!l)return i?null:n;let{providerName:a,routeModel:c}=l,u=Ze(e,a,c);if(!u){if(r===!0&&o&&!t&&s!==!1){let g=ve(),f=g.getPromotion(a,c,o,e);if(f){let y=Ot(f);if(y){let p=Ze(e,y.providerName,y.routeModel);if(p)return`${p.provider.name},${p.model}`}g.clear(a,c,o)}}return null}if(r===!0&&o&&!t&&s!==!1){let g=ve(),f=g.getPromotion(a,c,o,e);if(f){let y=Ot(f);if(y){let p=Ze(e,y.providerName,y.routeModel);if(p)return`${p.provider.name},${p.model}`}g.clear(a,c,o)}}if(!t&&!U().isAvailable(u.provider.name,u.model))return null;let d=Et(u.provider.name);if(d){let g=d.limitDaily!==void 0&&d.usedDailyBalance!==void 0&&d.usedDailyBalance>=d.limitDaily,f=d.totalBalance!==void 0&&d.usedBalance!==void 0&&d.usedBalance>=d.totalBalance;if(g||f)return null}return`${u.provider.name},${u.model}`}function V(n,e,t,o,r,s){let i=U(),l=[t?.[n],o?.[n]];for(let a of l)if(!(!Array.isArray(a)||a.length===0))for(let c of a){let u=K(c,e,!1,n,void 0,void 0,s);if(u)return u}return null}function lc(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 io(n){let e=At(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 ts(n,e,t){return t?.usageScope!=="session"?n:Math.max(n,cc(e))}function ns(n,e,t){return n?.extendedContextThreshold??e?.extendedContextThreshold??t??2e5}function uc(n,e,t,o,r,s,i,l,a,c,u,d){let g=n.clientContext,f=g?.longContextThreshold??t.longContextThreshold??a??6e4,y=ts(e,r,g),p=n.modelFamily,m=ns(g,t,c),_=g?.supportsExplicitExtendedContext!==!1&&s===!0;if((_||y>m)&&t.extendedContext){let b=K(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: ${m}`),{model:b,scenarioType:"extendedContext",isFallback:!1};let T=l?V("extendedContext",o,t.fallback,i,p,u):null;if(T)return n.log.info(`Family: using extended context fallback model (1M+), tokens: ${y}, estimated: ${e}, explicit: ${_}, threshold: ${m}`),{model:T,scenarioType:"extendedContext",isFallback:!0};if(u){let x=q(n,t.extendedContext,o,"extendedContext");if(x)return{model:x,scenarioType:"extendedContext",isFallback:!1}}n.log.warn("Family: extendedContext model unavailable (fail pool), skipping")}if(y>f&&(t.longContext||t.fallback?.longContext?.length||i?.longContext?.length)){let b=t.longContext?K(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 T=l?V("longContext",o,t.fallback,i,p,u):null;if(T)return n.log.info(`Family: using long context fallback model, tokens: ${y}, estimated: ${e}`),{model:T,scenarioType:"longContext",isFallback:!0};if(u&&t.longContext){let x=q(n,t.longContext,o,"longContext");if(x)return{model:x,scenarioType:"longContext",isFallback:!1}}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=K(t.webSearch,o,!1,"webSearch",l,d,u);if(b)return{model:b,scenarioType:"webSearch",isFallback:!1};let T=l?V("webSearch",o,t.fallback,i,p,u):null;if(T)return n.log.info("Family: using webSearch fallback model"),{model:T,scenarioType:"webSearch",isFallback:!0};if(u){let x=q(n,t.webSearch,o,"webSearch");if(x)return{model:x,scenarioType:"webSearch",isFallback:!1}}n.log.warn("Family: webSearch model unavailable (fail pool), skipping")}if(n.body.thinking?.type==="enabled"&&t.think){let b=K(t.think,o,!1,"think",l,d,u);if(b)return{model:b,scenarioType:"think",isFallback:!1};let T=l?V("think",o,t.fallback,i,p,u):null;if(T)return n.log.info("Family: using think fallback model"),{model:T,scenarioType:"think",isFallback:!0};if(u){let x=q(n,t.think,o,"think");if(x)return{model:x,scenarioType:"think",isFallback:!1}}n.log.warn("Family: think model unavailable (fail pool), skipping")}if(t.default){let b=K(t.default,o,!1,"default",l,d,u);if(b)return{model:b,scenarioType:"default",isFallback:!1};let T=l?V("default",o,t.fallback,i,p,u):null;if(T)return n.log.info("Family: using default fallback model"),{model:T,scenarioType:"default",isFallback:!0};if(u){let x=q(n,t.default,o,"default");if(x)return{model:x,scenarioType:"default",isFallback:!1}}n.log.warn("Family: default model unavailable (fail pool), skipping")}return null}function gc(){if(_e.size<=Yr)return;let n=[..._e.keys()].slice(0,_e.size-Yr);for(let e of n)_e.delete(e)}function hc(){if(Ie.size<=Xr)return;let n=[...Ie].slice(0,Ie.size-Xr);for(let e of n)Ie.delete(e)}var Zr,le,ce,It,ic,dc,Mt,_e,Yr,Ie,Xr,pc,fc,mc,qr,os,Me=w(()=>{"use strict";Pt();ne();Pe();Rt();Xe();Ae();Zr={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},le=class extends Error{statusCode;code;type;sessionId;configuredTarget;constructor(e,t){super(e),this.name="ProjectRoutingError",this.statusCode=t?.statusCode||Zr[t?.code||""]||502,this.code=t?.code||"project_routing_error",this.type="api_error",this.sessionId=t?.sessionId,this.configuredTarget=t?.configuredTarget}};ce=oc("cl100k_base"),It=(n,e,t)=>{let o=0;return Array.isArray(n)&&n.forEach(r=>{typeof r.content=="string"?o+=ce.encode(r.content).length:Array.isArray(r.content)&&r.content.forEach(s=>{s.type==="text"?o+=ce.encode(s.text).length:s.type==="tool_use"?o+=ce.encode(JSON.stringify(s.input)).length:s.type==="tool_result"&&(o+=ce.encode(typeof s.content=="string"?s.content:JSON.stringify(s.content)).length)})}),typeof e=="string"?o+=ce.encode(e).length:Array.isArray(e)&&e.forEach(r=>{r.type==="text"&&(typeof r.text=="string"?o+=ce.encode(r.text).length:Array.isArray(r.text)&&r.text.forEach(s=>{o+=ce.encode(s||"").length}))}),t&&t.forEach(r=>{r.description&&(o+=ce.encode(r.name+r.description).length),r.input_schema&&(o+=ce.encode(JSON.stringify(r.input_schema)).length)}),o},ic=async(n,e)=>{if(n.sessionId){let t=await os(n.sessionId);if(t){let o=so(Vr,t,"config.json"),r=so(Vr,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 i=n.sessionId||n.clientContext?.stableSessionId;throw new le(`Project routing error: project config.json is malformed or unreadable in project "${t}". ${s.message}. Session: "${i||"unknown"}".`,{sessionId:i,configuredTarget:o,code:"project_config_error",statusCode:500})}}}}};dc=async(n,e,t,o,r,s)=>{let i=t.get("providers")||[],l=r||t.get("Router"),a=l?.enableFallback===!0,c=a?l?.fallback:void 0,u=a&&!s?c||t.get("fallback"):c,d=!s,g=null;if(n.body?.system?.length>1&&n.body?.system[1]?.text?.includes("<CCR-SUBAGENT-MODEL>")){let v=n.body?.system[1].text.match(/<CCR-SUBAGENT-MODEL>(.*?)<\/CCR-SUBAGENT-MODEL>/s);v&&(n.body.system[1].text=n.body.system[1].text.replace(`<CCR-SUBAGENT-MODEL>${v[1]}</CCR-SUBAGENT-MODEL>`,""),g=v[1])}let{family:f,extended:y,isCcrAlias:p}=et(n.body.model),m=l?.families?.[f||""];if(m&&l?.enableFamilyRouting){n.log.info(`Using model family routing for: ${f}${y?" (1M)":""}`),n.modelFamily=f,n.familyFallback=m.fallback;let v=uc(n,e,m,i,o,y,u,a,l?.longContextThreshold,l?.extendedContextThreshold,s,d);if(v)return{model:v.model,scenarioType:v.scenarioType}}if(n.body.model.includes(",")&&!s){let v=K(n.body.model,i,!1,"default",a,d,s);if(v)return{model:v,scenarioType:"default"};n.log.warn(`Explicit model ${n.body.model} unavailable (fail pool), trying fallback`);let S=a?V("default",i,void 0,u,void 0,s):null;if(S)return n.log.info(`Using fallback for explicit model: ${S}`),{model:S,scenarioType:"default"};n.log.warn(`No fallback available for explicit model ${n.body.model}, continuing through routing logic`)}let _=p&&!l?.enableFamilyRouting?null:ac(n.body.model,l?.models);if(_){let v=K(_,i,!1,"modelMapping",a,d,s);if(v)return n.log.info(`Using mapped model for ${n.body.model}: ${_}`),{model:v,scenarioType:"modelMapping"};let S=a?V("modelMapping",i,void 0,u,void 0,s):null;if(S)return{model:S,scenarioType:"modelMapping"};if(s){let C=q(n,_,i,"modelMapping");if(C)return{model:C,scenarioType:"modelMapping"}}n.log.warn(`Mapped model ${_} unavailable (fail pool), skipping`)}let k=n.clientContext,h=ts(e,o,k),b=ns(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 v=K(l.extendedContext,i,!1,"extendedContext",a,d,s);if(v)return{model:v,scenarioType:"extendedContext"};n.log.warn(`Extended context model ${l.extendedContext} unavailable (fail pool), trying fallback`);let S=a?V("extendedContext",i,void 0,u,void 0,s):null;if(S)return{model:S,scenarioType:"extendedContext"};if(s){let C=q(n,l.extendedContext,i,"extendedContext");if(C)return{model:C,scenarioType:"extendedContext"}}}let T=k?.longContextThreshold??l?.longContextThreshold??6e4;if(h>T&&l?.longContext){n.log.info(`Using long context model due to token count: ${h}, estimated: ${e}, threshold: ${T}`);let v=K(l.longContext,i,!1,"longContext",a,d,s);if(v)return{model:v,scenarioType:"longContext"};n.log.warn(`Long context model ${l.longContext} unavailable (fail pool), trying fallback`);let S=a?V("longContext",i,void 0,u,void 0,s):null;if(S)return{model:S,scenarioType:"longContext"};if(s){let C=q(n,l.longContext,i,"longContext");if(C)return{model:C,scenarioType:"longContext"}}}if(!s&&g)return{model:g,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 v=K(l.background,i,!1,"background",a,d,s);if(v)return{model:v,scenarioType:"background"};let S=a?V("background",i,void 0,u,void 0,s):null;if(S)return{model:S,scenarioType:"background"};if(s){let C=q(n,l.background,i,"background");if(C)return{model:C,scenarioType:"background"}}n.log.warn(`Background model ${l.background} unavailable (fail pool), falling through`)}if(Array.isArray(n.body.tools)&&n.body.tools.some(v=>v.type?.startsWith("web_search"))&&l?.webSearch){let v=K(l.webSearch,i,!1,"webSearch",a,d,s);if(v)return{model:v,scenarioType:"webSearch"};n.log.warn(`WebSearch model ${l.webSearch} unavailable (fail pool), trying fallback`);let S=a?V("webSearch",i,void 0,u,void 0,s):null;if(S)return{model:S,scenarioType:"webSearch"};if(s){let C=q(n,l.webSearch,i,"webSearch");if(C)return{model:C,scenarioType:"webSearch"}}}if(n.body.thinking?.type==="enabled"&&l?.think){n.log.info(`Using think model for ${n.body.thinking}`);let v=K(l.think,i,!1,"think",a,d,s);if(v)return{model:v,scenarioType:"think"};n.log.warn(`Think model ${l.think} unavailable (fail pool), trying fallback`);let S=a?V("think",i,void 0,u,void 0,s):null;if(S)return{model:S,scenarioType:"think"};if(s){let C=q(n,l.think,i,"think");if(C)return{model:C,scenarioType:"think"}}}if(l?.default){let v=K(l.default,i,!1,"default",a,d,s);if(v)return{model:v,scenarioType:"default"};n.log.warn(`Default model ${l.default} unavailable (fail pool), trying fallback`);let S=a?V("default",i,void 0,u,void 0,s):null;if(S)return{model:S,scenarioType:"default"};let C=K(l.default,i,!0,"default",a,d,s);if(C)return n.log.warn(`No fallback available; retrying default model ${l.default} despite fail-pool state (strict=${s})`),{model:C,scenarioType:"default"}}if(s){let v=q(n,l?.default||n.body.model,i,"default");if(v)return{model:v,scenarioType:"default"}}return{model:void 0,scenarioType:"default"}},Mt=async(n,e,t)=>{let{configService:o,event:r}=t;!n.originalModel&&n.body.model&&(n.originalModel=n.body.model),ye(n,o.getAll());let s=await ic(n,o),i=s||o.get("Router"),l=i?.enableFallback===!0,a=o.get("providers")||[],c=!!s;n.enableFallback=l,n.strictProjectRouting=c,n.fallbackConfig=c?i?.fallback:i?.fallback||o.get("fallback");let u=n.clientContext?.usageScope==="session"?n.previousUsage??X.get(n.usageCacheKey):void 0,{messages:d,system:g=[],tools:f}=n.body,y=o.get("REWRITE_SYSTEM_PROMPT");if(y&&g.length>1&&g[1]?.text?.includes("<env>")){let p=await ro(y,"utf-8");g[1].text=`${p}<env>${g[1].text.split("<env>").pop()}`}try{let[p,m]=n.body.model.split(","),_=t.tokenizerService?.getTokenizerConfigForModel(p,m),k;t.tokenizerService?k=(await t.tokenizerService.countTokens({messages:d,system:g,tools:f},_,p)).tokenCount:k=It(d,g,f),n.tokenCount=k;let h,b=c?void 0:o.get("CUSTOM_ROUTER_PATH");if(b)try{h=await We(b)(n,o.getAll(),{event:r})}catch(S){n.log.error(`failed to load custom router: ${S.message}`)}if(h)n.scenarioType="default";else{let S=await dc(n,k,o,u,s,!!s);h=S.model,n.scenarioType=S.scenarioType}let{family:T}=et(n.originalModel||n.body.model),x=i?.enableFamilyRouting&&T?i.families?.[T]:void 0,v=[x?.image,i?.image].filter((S,C,P)=>!!S&&P.indexOf(S)===C);if(v.length>0&&lc(n)&&!io(h))if(v.includes(h))n.scenarioType="image";else{let S=v.map(C=>K(C,a,!1,"image",l,!c,c)).find(C=>!!C);if(S)n.log.info(`Using image model fallback for ${h}`),h=S,n.scenarioType="image";else{let C=l?V("image",a,x?.fallback,n.fallbackConfig,T||void 0,c):null;if(C)n.log.info(`Using image fallback model: ${C}`),h=C,n.scenarioType="image";else if(c){let P=q(n,v[0],a,"image");P&&(h=P,n.scenarioType="image")}else n.log.warn(`Image models ${v.join(", ")} 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 le)throw p;if(n.log.error(`Error in router middleware: ${p.message}`),c){let m=n.sessionId||n.clientContext?.stableSessionId;throw new le(`Project routing error: router failure in project mode. ${p.message}. Session: "${m||"unknown"}".`,{sessionId:m,configuredTarget:i?.default,code:"project_router_failure",statusCode:502})}n.body.model=i?.default,n.scenarioType="default"}},_e=new Map,Yr=1e3,Ie=new Set,Xr=1e3,pc=3,fc=50,mc=n=>new Promise(e=>setTimeout(e,n));qr=async n=>{let e=await rc(Qr),t=[];for await(let s of e)s.isDirectory()&&t.push(s.name);let o=t.map(async s=>{let i=so(Qr,s,`${n}.jsonl`);try{return(await sc(i)).isFile()?s:null}catch{return null}}),r=await Promise.all(o);for(let s of r)if(s)return s;return null},os=async n=>{let e=Ee(n);if(!e)return null;if(_e.has(e))return _e.get(e)||null;try{let t=await qr(e);if(!t&&!Ie.has(e)){Ie.add(e),hc();for(let o=0;o<pc&&!t;o++)await mc(fc),t=await qr(e)}return t?(_e.set(e,t),gc(),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(`
|
|
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(a=>a.startsWith("data:")&&a.trim().length>5).length===0){o.releaseLock();let a=s.length<500?s:s.slice(0,500);throw B(`Provider ${t} returned streaming response with no SSE data lines: ${a}`,400,"provider_response_error")}let l=new ReadableStream({start:a=>{a.enqueue(r.value);let c=()=>{o.read().then(({done:u,value:d})=>{u?a.close():(a.enqueue(d),c())}).catch(u=>a.error(u))};c()},cancel:()=>{o.cancel()}});return new Response(l,{headers:e.headers,status:e.status,statusText:e.statusText})}async function mc(n,e,t,o,r){let s=n.scenarioType||"default",i=n.familyFallback,l=n.modelFamily,a=n.strictProjectRouting?n.fallbackConfig:n.fallbackConfig??t.configService.get("fallback"),c=F(),u=n.provider||"",d=n.body.model||"",g=new Set,m=r?.statusCode===429||r?.isRateLimit===!0||r?.rawBody&&It(r.rawBody)||r?.message&&It(r.message);if(u&&d&&(m?(c.markRateLimited(u,d,120,r?.message),n.log.warn(`Primary model ${u},${d} rate-limited, will try fallbacks`)):c.recordFailure(u,d,r?.message),g.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(","),T=h?.trim(),x=b.join(",").trim();return!T||!x?null:{provider:T,model:x,key:`${T},${x}`}},f=[];if(l){let k=i?.[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(a?.[s])&&a[s].length>0&&f.push({name:`global/${s}`,models:a[s]}),f.length===0&&s!=="image"&&n.body?.messages?.some(b=>b.role==="user"&&Array.isArray(b.content)&&b.content.some(T=>T.type==="image"||T.type==="image_url"||Array.isArray(T?.content)&&T.content.some(x=>x.type==="image"||x.type==="image_url")))&&Array.isArray(a?.image)&&a.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:a.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(g.has(b.key))continue;g.add(b.key);let T=t.providerService.getProviders(),x=Xe(T,b.provider,b.model);if(!x){n.log.warn(`Fallback model ${h} is not configured or provider is disabled, skipping`);continue}let v=x.provider.name,S=x.model;if(!c.isAvailable(v,S)){n.log.warn(`Fallback model ${h} unavailable (fail pool), skipping`);continue}let C;for(let P=1;P<=2;P++)try{n.log.info(`Trying fallback model: ${v},${S}${P>1?" (retry)":""}`);let R={...n.body};R.model=S;let O={...n,provider:v,body:R},E=x.provider,{requestBody:A,config:N,bypass:D}=await os(R,E,o,n.headers,{req:O}),j=await rs(A,N,E,t,D,o,{req:O});try{E?.baseUrl&&j?.headers&&We(v,E.baseUrl,j.headers)}catch{}let $=await ss(A,j,E,o,D,{req:O,isCodexOnMessagesEndpoint:n.isCodexOnMessagesEndpoint||!1});return $=await ns(R,$,v),n.log.info(`Fallback model ${v},${S} succeeded`),c.recordSuccess(v,S),u&&d&&!n.strictProjectRouting&&(Te().promote(u,d,s,v,S),n.log.info(`Promoted fallback model ${v},${S} for ${u},${d}:${s}`),m?n.log.info(`Rate-limited original model ${u},${d} already marked unavailable with cooldown`):(c.forceOpen(u,d,r?.message),n.log.info(`Marked original model ${u},${d} as unavailable`))),n.provider=v,n.body=R,is($,e,R,t)}catch(R){if(C=R,P===1){n.log.warn(`Fallback model ${v},${S} failed, retrying once: ${R.message}`);continue}}c.recordFailure(v,S,C?.message),n.log.warn(`Fallback model ${v},${S} failed after retry: ${C?.message}`),t.recordUsage?.({provider:v,model:S,originalModel:n.originalModel||d||n.body.model,scenarioType:s,modelFamily:n.modelFamily,errorMessage:C?.message||String(C),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 os(n,e,t,o,r){let s=JSON.parse(JSON.stringify(n)),i=s?.system;if(typeof i=="string"&&i.includes("cch="))s.system=i.replace(/cch=[^;]+;?/g,"cch=ccr-stable;");else if(Array.isArray(i))for(let c=0;c<i.length;c++){let u=i[c],d=typeof u=="string"?u:u?.text??"";if(d.includes("cch=")){let g=d.replace(/cch=[^;]+;?/g,"cch=ccr-stable;");typeof u=="string"?i[c]=g:typeof u?.text=="string"&&(u.text=g)}}let l={},a=!1;if(a=gc(e,t,n),a&&(o instanceof Headers?o.delete("content-length"):delete o["content-length"],l.headers=o),!a&&typeof t.transformRequestOut=="function"){let c=await t.transformRequestOut(s);c.body?(s=c.body,l=c.config||{}):s=c}if(!a&&e.transformer?.use?.length)for(let c of e.transformer.use){if(!c||typeof c.transformRequestIn!="function")continue;let u=await c.transformRequestIn(s,e,r);u.body?(s=u.body,l={...l,...u.config}):s=u}if(!a&&e.transformer?.[n.model]?.use?.length)for(let c of e.transformer[n.model].use)!c||typeof c.transformRequestIn!="function"||(s=await c.transformRequestIn(s,e,r));return{requestBody:s,config:l,bypass:a}}function gc(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 hc(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 rs(n,e,t,o,r,s,i){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 a={Authorization:`Bearer ${t.apiKey}`,...e?.headers||{}};for(let u in a)(a[u]==="undefined"||["authorization","Authorization"].includes(u)&&a[u]?.includes("undefined"))&&delete a[u];bt(o.configService)&&br(o.log,i.req.id,{url:String(l),headers:a,body:n});let c=await vr(l,n,{...e,headers:JSON.parse(JSON.stringify(a)),httpsProxy:se(o.configService,t)},i,o.log);if(!c.ok){let u=await c.text();o.log.error(`[provider_response_error] Error from provider(${t.name},${n.model}: ${c.status}): ${u}`);let d=B(`Error from provider(${t.name},${n.model}: ${c.status}): ${u}`,c.status,"provider_response_error");throw d.isRateLimit=c.status===429||It(u),d.rawBody=u,d}if(c.ok){let u=c.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=${c.ok} status=${c.status} hasBody=${!!c.body}`),!d||u.includes("application/json")){let g=c.clone(),m="";try{if(m=await g.text(),!m||m.trim()==="")throw new SyntaxError("Empty JSON body");let y=JSON.parse(m);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}: ${c.status}): ${m}`);let f=It(m),_=B(`Error from provider(${t.name},${n.model}: ${c.status}): ${m}`,400,"provider_response_error");throw _.isRateLimit=f,_.rawBody=m,_}}catch(y){if(y instanceof SyntaxError){o.log.warn(`[provider_response_error] Empty or malformed JSON response from provider(${t.name},${n.model}: 200): "${m}"`);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=m,p}throw y}}}if(!n.stream&&bt(o.configService)){let d=await c.clone().text();Tr(o.log,i.req.id,{status:c.status,headers:Object.fromEntries(c.headers.entries()),body:d})}return c}async function ss(n,e,t,o,r,s){let i=e;if(!r&&t.transformer?.use?.length)for(let l of Array.from(t.transformer.use).reverse())!l||typeof l.transformResponseOut!="function"||(i=await l.transformResponseOut(i,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"||(i=await l.transformResponseOut(i,s));if(!r&&o.transformResponseIn&&(s.provider||(s.provider=t),i=await o.transformResponseIn(i,s)),s?.isCodexOnMessagesEndpoint)try{i=await new xe().transformResponseIn(i,{...s,provider:t})}catch(l){console.error("Failed to apply Responses API conversion for codex client:",l)}return i}function is(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&&bt(o.configService)){let[s,i]=n.body.tee(),l=kr(o.configService);return Cr(s,o.log,e.request.id,l),e.send(i)}return e.send(n.body)}else return n.json()}function It(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 fc,as,Mt=w(()=>{"use strict";xr();_t();Je();jn();ee();ve();xt();Yn();Ae();Z();fc=/^ccr-(opus|sonnet|haiku)(\[1m\])?$/i;as=async n=>{n.get("/",async()=>({message:"LLMs API",version:vt})),n.get("/health",async()=>({status:"ok",timestamp:new Date().toISOString()})),n.get("/providers/health",async()=>({states:F().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)=>ts(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:i,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(!i?.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,$t=w(()=>{"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 i=this.transformerService.getTransformer(s[0]);if(i)return new i(s[1])}if(typeof s=="string"){let i=this.transformerService.getTransformer(s);return typeof i=="function"?new i:i}}).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 i=this.transformerService.getTransformer(s[0]);if(i)return new i(s[1])}if(typeof s=="string"){let i=this.transformerService.getTransformer(s);return typeof i=="function"?new i:i}}).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 i=`${o.name},${s}`;this.modelRoutes.delete(i),this.modelRoutes.delete(s)}),t.models.forEach(s=>{let i=`${o.name},${s}`,l={provider:o.name,model:s,fullModel:i};this.modelRoutes.set(i,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(i=>i.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 cs,ls=w(()=>{cs=n=>n<=0?"none":n<=1024?"low":n<=8192?"medium":"high"});var us,ds=w(()=>{us=(n,e)=>(n.includes("base64")&&(n=n.split("base64").pop(),n.startsWith(",")&&(n=n.slice(1))),`data:${e};base64,${n}`)});function _c(n){return n.filter(e=>!!e?.function?.name).map(e=>({name:e.function.name,description:e.function.description,input_schema:e.function.parameters}))}function ps(n){let e=[],t=[],o=g=>{if(typeof g=="string"){t.push({type:"text",text:g});return}Array.isArray(g)&&g.forEach(m=>{if(typeof m=="string"){t.push({type:"text",text:m});return}m&&typeof m=="object"&&m.type==="text"&&m.text&&t.push({...m})})},r=()=>{let g=new Map;for(let m=0;m<t.length;m++){let y=t[m],p=y?.text??JSON.stringify(y),f=g.get(p);if(f===void 0){g.set(p,m);continue}!t[f]?.cache_control&&y?.cache_control&&(t[f]=y),t.splice(m,1),m--}};n.messages.forEach(g=>{g.role==="system"?o(g.content):e.push(g)}),r();let s=[];for(let g=0;g<e.length;g++){let m=e[g];if(m.role==="tool"){let y=m.content;try{typeof m.content=="string"&&(y=JSON.parse(m.content))}catch{}y!=null&&typeof y!="object"&&typeof y!="string"&&(y=String(y));let p={type:"tool_result",tool_use_id:m.tool_call_id,content:y};m.cache_control&&(p.cache_control=m.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(m.role==="user"){let y=[];typeof m.content=="string"?y.push({type:"text",text:m.content}):Array.isArray(m.content)&&m.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(m.role==="assistant"){let y=[];m.content&&(typeof m.content=="string"?y.push({type:"text",text:m.content}):Array.isArray(m.content)&&y.push(...m.content)),m.tool_calls&&m.tool_calls.length>0&&m.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:_})}),m.thinking&&y.unshift({type:"thinking",thinking:m.thinking.content,signature:m.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 i=()=>{let g=t.filter(m=>m?.cache_control).length;for(let m of s)Array.isArray(m.content)&&(g+=m.content.filter(y=>y?.cache_control).length);return g},l=g=>g&&typeof g=="object"?{...g}:{type:"ephemeral"},a=()=>{for(let g=s.length-1;g>=0;g--){let m=s[g]?.content;if(!Array.isArray(m))continue;let y=m.find(p=>p?.cache_control);if(y?.cache_control)return y.cache_control}for(let g=t.length-1;g>=0;g--)if(t[g]?.cache_control)return t[g].cache_control;return{type:"ephemeral"}},c=(g,m)=>{if(!Array.isArray(g?.content)||g.content.some(p=>p?.cache_control))return!1;let y=g.content.find(p=>p&&typeof p=="object"&&!p.cache_control);return y?(y.cache_control=l(m),!0):!1};(()=>{let g=4-i();if(g<=0||s.length===0)return;let m=s,y=a(),p=[];for(let f=m.length-1;f>=0;f--)m[f]?.role!=="user"||!Array.isArray(m[f].content)||p.push(f);for(let f of p){if(g<=0)break;c(m[f],y)&&g--}})();let d={messages:s,model:n.model,max_tokens:n.max_tokens||4096,temperature:n.temperature,stream:n.stream};if(t.length>0){let g=t.some(m=>m?.cache_control);d.system=g?t:t.map(m=>m.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 rs(n,e,t,o){let r=n.body;(n.ccrHookOrder||=[]).push("handler"),o.endPoint==="/v1/responses"&&r?.input&&!r?.messages&&tt(r),o.endPoint==="/v1/responses"&&!n.provider&&typeof r?.model=="string"&&yc.test(r.model)&&await Mt(n,e,{configService:t.configService,tokenizerService:t.tokenizerService});let s=n.provider;if(!s&&r?.model){let c=r.model.split(",");c.length>1&&(s=c[0],r.model=c.slice(1).join(","))}let i=s?t.providerService.getProvider(s):void 0;if(!i&&r?.model){let c=t.providerService.resolveModelRoute(r.model);c&&(i=c.provider,r.model=c.targetModel)}if(!i&&r?.model){let u=t.configService.get("Router")?.default;if(u&&u.includes(",")){let[d,...g]=u.split(","),f=t.providerService.getProvider(d);f&&(i=f,r.model=g.join(","))}}if(n.originalModel||(n.originalModel=r?.model),!i)throw B(`Provider '${s}' not found`,404,"provider_not_found");n.provider=i.name||s;let l=bc(n),a=o.endPoint==="/v1/messages"&&l;l&&e.header("X-Codex-Detected","true"),a&&e.header("X-Codex-On-Messages","true"),n.isCodexOnMessagesEndpoint=a,n.codexDetected=l;try{o.endPoint==="/v1/responses"&&r.input&&!r.messages&&tt(r);let{requestBody:c,config:u,bypass:d}=await is(r,i,o,n.headers,{req:n});if(c?.messages&&!d&&!n.isTargetAnthropic){let p=c.messages,m=new Set,_=[],k=[];for(let h of p){if(h?.role!=="system"){k.push(h);continue}let b=JSON.stringify(h.content??"");m.has(b)||(m.add(b),_.push(h))}_.length>0&&k.length>0&&(c.messages=[..._,...k])}let g=await as(c,u,i,t,d,o,{req:n});try{i?.baseUrl&&g?.headers&&Ke(s,i.baseUrl,g.headers)}catch{}let f=await cs(c,g,i,o,d,{req:n,isCodexOnMessagesEndpoint:a});f=await ss(r,f,i.name||s);let y=ls(f,e,r,t);try{let p=r.model||n.originalModel;s&&p&&U().recordSuccess(s,p)}catch{}return y}catch(c){if(c instanceof le)throw c;if(!n.__retryAttempted){n.__retryAttempted=!0;try{return await rs(n,e,t,o)}catch(d){if(n.__fallbackExhausted)throw d;c=d}}let u=await _c(n,e,t,o,c);if(u)return u;throw n.__fallbackExhausted=!0,c}}async function ss(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 a=s.length<500?s:s.slice(0,500);throw B(`Provider ${t} returned error in SSE stream: ${a}`,400,"provider_response_error")}if(s.split(`
|
|
45
|
+
`).filter(a=>a.startsWith("data:")&&a.trim().length>5).length===0){o.releaseLock();let a=s.length<500?s:s.slice(0,500);throw B(`Provider ${t} returned streaming response with no SSE data lines: ${a}`,400,"provider_response_error")}let l=new ReadableStream({start:a=>{a.enqueue(r.value);let c=()=>{o.read().then(({done:u,value:d})=>{u?a.close():(a.enqueue(d),c())}).catch(u=>a.error(u))};c()},cancel:()=>{o.cancel()}});return new Response(l,{headers:e.headers,status:e.status,statusText:e.statusText})}async function _c(n,e,t,o,r){let s=n.scenarioType||"default",i=n.familyFallback,l=n.modelFamily,a=n.strictProjectRouting?n.fallbackConfig:n.fallbackConfig??t.configService.get("fallback"),c=U(),u=n.provider||"",d=n.body.model||"",g=new Set,f=r?.statusCode===429||r?.isRateLimit===!0||r?.rawBody&&$t(r.rawBody)||r?.message&&$t(r.message);if(u&&d&&(f?(c.markRateLimited(u,d,120,r?.message),n.log.warn(`Primary model ${u},${d} rate-limited, will try fallbacks`)):c.recordFailure(u,d,r?.message),g.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(","),T=h?.trim(),x=b.join(",").trim();return!T||!x?null:{provider:T,model:x,key:`${T},${x}`}},m=[];if(l){let k=i?.[s];if(Array.isArray(k)&&k.length>0)m.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(a?.[s])&&a[s].length>0&&m.push({name:`global/${s}`,models:a[s]}),m.length===0&&s!=="image"&&n.body?.messages?.some(b=>b.role==="user"&&Array.isArray(b.content)&&b.content.some(T=>T.type==="image"||T.type==="image_url"||Array.isArray(T?.content)&&T.content.some(x=>x.type==="image"||x.type==="image_url")))&&Array.isArray(a?.image)&&a.image.length>0&&(n.log.info(`No fallback for scenario '${s}', but request has images \u2014 trying fallback.image`),m.push({name:"global/image (auto-detected)",models:a.image})),m.length===0)return null;let _=m.reduce((k,h)=>k+h.models.length,0);n.log.warn(`Request failed for ${s}, trying ${_} fallback models across ${m.length} fallback stage(s)`);for(let k of m){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(g.has(b.key))continue;g.add(b.key);let T=t.providerService.getProviders(),x=Ze(T,b.provider,b.model);if(!x){n.log.warn(`Fallback model ${h} is not configured or provider is disabled, skipping`);continue}let v=x.provider.name,S=x.model;if(!c.isAvailable(v,S)){n.log.warn(`Fallback model ${h} unavailable (fail pool), skipping`);continue}let C;for(let P=1;P<=2;P++)try{n.log.info(`Trying fallback model: ${v},${S}${P>1?" (retry)":""}`);let R={...n.body};R.model=S;let O={...n,provider:v,body:R},E=x.provider,{requestBody:A,config:N,bypass:D}=await is(R,E,o,n.headers,{req:O}),H=await as(A,N,E,t,D,o,{req:O});try{E?.baseUrl&&H?.headers&&Ke(v,E.baseUrl,H.headers)}catch{}let $=await cs(A,H,E,o,D,{req:O,isCodexOnMessagesEndpoint:n.isCodexOnMessagesEndpoint||!1});return $=await ss(R,$,v),n.log.info(`Fallback model ${v},${S} succeeded`),c.recordSuccess(v,S),u&&d&&!n.strictProjectRouting&&(ve().promote(u,d,s,v,S),n.log.info(`Promoted fallback model ${v},${S} for ${u},${d}:${s}`),f?n.log.info(`Rate-limited original model ${u},${d} already marked unavailable with cooldown`):(c.forceOpen(u,d,r?.message),n.log.info(`Marked original model ${u},${d} as unavailable`))),n.provider=v,n.body=R,ls($,e,R,t)}catch(R){if(C=R,P===1){n.log.warn(`Fallback model ${v},${S} failed, retrying once: ${R.message}`);continue}}c.recordFailure(v,S,C?.message),n.log.warn(`Fallback model ${v},${S} failed after retry: ${C?.message}`),t.recordUsage?.({provider:v,model:S,originalModel:n.originalModel||d||n.body.model,scenarioType:s,modelFamily:n.modelFamily,errorMessage:C?.message||String(C),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 is(n,e,t,o,r){let s=JSON.parse(JSON.stringify(n)),i=s?.system;if(typeof i=="string"&&i.includes("cch="))s.system=i.replace(/cch=[^;]+;?/g,"cch=ccr-stable;");else if(Array.isArray(i))for(let c=0;c<i.length;c++){let u=i[c],d=typeof u=="string"?u:u?.text??"";if(d.includes("cch=")){let g=d.replace(/cch=[^;]+;?/g,"cch=ccr-stable;");typeof u=="string"?i[c]=g:typeof u?.text=="string"&&(u.text=g)}}let l={},a=!1;if(a=kc(e,t,n),a&&(o instanceof Headers?o.delete("content-length"):delete o["content-length"],l.headers=o),!a&&typeof t.transformRequestOut=="function"){let c=await t.transformRequestOut(s);c.body?(s=c.body,l=c.config||{}):s=c}if(!a&&e.transformer?.use?.length)for(let c of e.transformer.use){if(!c||typeof c.transformRequestIn!="function")continue;let u=await c.transformRequestIn(s,e,r);u.body?(s=u.body,l={...l,...u.config}):s=u}if(!a&&e.transformer?.[n.model]?.use?.length)for(let c of e.transformer[n.model].use)!c||typeof c.transformRequestIn!="function"||(s=await c.transformRequestIn(s,e,r));return{requestBody:s,config:l,bypass:a}}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 bc(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 as(n,e,t,o,r,s,i){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 a={Authorization:`Bearer ${t.apiKey}`,...e?.headers||{}};for(let u in a)(a[u]==="undefined"||["authorization","Authorization"].includes(u)&&a[u]?.includes("undefined"))&&delete a[u];Ct(o.configService)&&Cr(o.log,i.req.id,{url:String(l),headers:a,body:n});let c=await Sr(l,n,{...e,headers:JSON.parse(JSON.stringify(a)),httpsProxy:ae(o.configService,t)},i,o.log);if(!c.ok){let u=await c.text();o.log.error(`[provider_response_error] Error from provider(${t.name},${n.model}: ${c.status}): ${u}`);let d=B(`Error from provider(${t.name},${n.model}: ${c.status}): ${u}`,c.status,"provider_response_error");throw d.isRateLimit=c.status===429||$t(u),d.rawBody=u,d}if(c.ok){let u=c.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=${c.ok} status=${c.status} hasBody=${!!c.body}`),!d||u.includes("application/json")){let g=c.clone(),f="";try{if(f=await g.text(),!f||f.trim()==="")throw new SyntaxError("Empty JSON body");let y=JSON.parse(f);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}: ${c.status}): ${f}`);let m=$t(f),_=B(`Error from provider(${t.name},${n.model}: ${c.status}): ${f}`,400,"provider_response_error");throw _.isRateLimit=m,_.rawBody=f,_}}catch(y){if(y instanceof SyntaxError){o.log.warn(`[provider_response_error] Empty or malformed JSON response from provider(${t.name},${n.model}: 200): "${f}"`);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=f,p}throw y}}}if(!n.stream&&Ct(o.configService)){let d=await c.clone().text();vr(o.log,i.req.id,{status:c.status,headers:Object.fromEntries(c.headers.entries()),body:d})}return c}async function cs(n,e,t,o,r,s){let i=e;if(!r&&t.transformer?.use?.length)for(let l of Array.from(t.transformer.use).reverse())!l||typeof l.transformResponseOut!="function"||(i=await l.transformResponseOut(i,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"||(i=await l.transformResponseOut(i,s));if(!r&&o.transformResponseIn&&(s.provider||(s.provider=t),i=await o.transformResponseIn(i,s)),s?.isCodexOnMessagesEndpoint)try{i=await new Re().transformResponseIn(i,{...s,provider:t})}catch(l){console.error("Failed to apply Responses API conversion for codex client:",l)}return i}function ls(n,e,t,o){if(n.ok||e.code(n.status),Fr(n)){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,i]=n.body.tee(),l=Tr(o.configService);return xr(s,o.log,e.request.id,l),e.send(i)}return e.send(n.body)}else return F(n)}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 Tc(n){try{return new URL(n),!0}catch{return!1}}var yc,us,Nt=w(()=>{"use strict";Rr();bt();Ge();zn();ne();Se();Rt();qn();Q();Me();te();yc=/^ccr-(opus|sonnet|haiku)(\[1m\])?$/i;us=async n=>{n.get("/",async()=>({message:"LLMs API",version:St})),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)=>rs(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:i,models:l}=t.body;if(!r?.trim())throw B("Provider name is required",400,"invalid_request");if(!s||!Tc(s))throw B("Valid base URL is required",400,"invalid_request");if(!i?.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 ue,Lt=w(()=>{"use strict";ue=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 i=this.transformerService.getTransformer(s[0]);if(i)return new i(s[1])}if(typeof s=="string"){let i=this.transformerService.getTransformer(s);return typeof i=="function"?new i:i}}).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 i=this.transformerService.getTransformer(s[0]);if(i)return new i(s[1])}if(typeof s=="string"){let i=this.transformerService.getTransformer(s);return typeof i=="function"?new i:i}}).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 i=`${o.name},${s}`;this.modelRoutes.delete(i),this.modelRoutes.delete(s)}),t.models.forEach(s=>{let i=`${o.name},${s}`,l={provider:o.name,model:s,fullModel:i};this.modelRoutes.set(i,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(i=>i.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 ds,ps=w(()=>{ds=n=>n<=0?"none":n<=1024?"low":n<=8192?"medium":"high"});var fs,ms=w(()=>{fs=(n,e)=>(n.includes("base64")&&(n=n.split("base64").pop(),n.startsWith(",")&&(n=n.slice(1))),`data:${e};base64,${n}`)});function Cc(n){return n.filter(e=>!!e?.function?.name).map(e=>({name:e.function.name,description:e.function.description,input_schema:e.function.parameters}))}function gs(n){let e=[],t=[],o=g=>{if(typeof g=="string"){t.push({type:"text",text:g});return}Array.isArray(g)&&g.forEach(f=>{if(typeof f=="string"){t.push({type:"text",text:f});return}f&&typeof f=="object"&&f.type==="text"&&f.text&&t.push({...f})})},r=()=>{let g=new Map;for(let f=0;f<t.length;f++){let y=t[f],p=y?.text??JSON.stringify(y),m=g.get(p);if(m===void 0){g.set(p,f);continue}!t[m]?.cache_control&&y?.cache_control&&(t[m]=y),t.splice(f,1),f--}};n.messages.forEach(g=>{g.role==="system"?o(g.content):e.push(g)}),r();let s=[];for(let g=0;g<e.length;g++){let f=e[g];if(f.role==="tool"){let y=f.content;try{typeof f.content=="string"&&(y=JSON.parse(f.content))}catch{}y!=null&&typeof y!="object"&&typeof y!="string"&&(y=String(y));let p={type:"tool_result",tool_use_id:f.tool_call_id,content:y};f.cache_control&&(p.cache_control=f.cache_control);let m=s[s.length-1];m&&m.role==="user"&&Array.isArray(m.content)?m.content.push(p):s.push({role:"user",content:[p]})}else if(f.role==="user"){let y=[];typeof f.content=="string"?y.push({type:"text",text:f.content}):Array.isArray(f.content)&&f.content.forEach(m=>{m&&typeof m=="object"&&m.type==="image_url"&&m.image_url?.url?y.push({type:"image",source:{type:"base64",media_type:m.media_type||"image/jpeg",data:m.image_url.url.split(",")[1]||m.image_url.url}}):y.push(m)});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(f.role==="assistant"){let y=[];f.content&&(typeof f.content=="string"?y.push({type:"text",text:f.content}):Array.isArray(f.content)&&y.push(...f.content)),f.tool_calls&&f.tool_calls.length>0&&f.tool_calls.forEach(m=>{let _={};try{_=JSON.parse(m.function.arguments)}catch{_=m.function.arguments}y.push({type:"tool_use",id:m.id,name:m.function.name,input:_})}),f.thinking&&y.unshift({type:"thinking",thinking:f.thinking.content,signature:f.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 i=()=>{let g=t.filter(f=>f?.cache_control).length;for(let f of s)Array.isArray(f.content)&&(g+=f.content.filter(y=>y?.cache_control).length);return g},l=g=>g&&typeof g=="object"?{...g}:{type:"ephemeral"},a=()=>{for(let g=s.length-1;g>=0;g--){let f=s[g]?.content;if(!Array.isArray(f))continue;let y=f.find(p=>p?.cache_control);if(y?.cache_control)return y.cache_control}for(let g=t.length-1;g>=0;g--)if(t[g]?.cache_control)return t[g].cache_control;return{type:"ephemeral"}},c=(g,f)=>{if(!Array.isArray(g?.content)||g.content.some(p=>p?.cache_control))return!1;let y=g.content.find(p=>p&&typeof p=="object"&&!p.cache_control);return y?(y.cache_control=l(f),!0):!1};(()=>{let g=4-i();if(g<=0||s.length===0)return;let f=s,y=a(),p=[];for(let m=f.length-1;m>=0;m--)f[m]?.role!=="user"||!Array.isArray(f[m].content)||p.push(m);for(let m of p){if(g<=0)break;c(f[m],y)&&g--}})();let d={messages:s,model:n.model,max_tokens:n.max_tokens||4096,temperature:n.temperature,stream:n.stream};if(t.length>0){let g=t.some(f=>f?.cache_control);d.system=g?t:t.map(f=>f.text||"").join(`
|
|
46
46
|
|
|
47
|
-
`)}return n.tools&&n.tools.length>0&&(d.tools=
|
|
48
|
-
`));let a=s.content.filter(u=>u.type==="tool_use"&&u.id);a.length&&(i.tool_calls=a.map(u=>({id:u.id,type:"function",function:{name:u.name,arguments:JSON.stringify(u.input||{})}})));let c=s.content.find(u=>u.type==="thinking");c&&(i.thinking={content:c.thinking,signature:c.signature}),t.push(i)}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=Cc(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 hs=w(()=>{});import{v4 as ao}from"uuid";var Dt,ys=w(()=>{"use strict";ps();bt();Q();ms();hs();Dt=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(i=>i.type==="text"&&i.text).map(i=>({type:"text",text:i.text,cache_control:i.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 i=s.content.filter(a=>a.type==="tool_result"&&a.tool_use_id);i.length&&i.forEach(a=>{let c={role:"tool",content:typeof a.content=="string"?a.content:JSON.stringify(a.content),tool_call_id:a.tool_use_id,cache_control:a.cache_control};t.push(c)});let l=s.content.filter(a=>a.type==="text"&&a.text||a.type==="image"&&a.source);l.length&&t.push({role:"user",content:l.map(a=>a?.type==="image"?{type:"image_url",image_url:{url:a.source?.type==="base64"?fs(a.source.data,a.source.media_type):a.source.url},media_type:a.source.media_type}:a)})}else if(s.role==="assistant"){let i={role:"assistant",content:""},l=s.content.filter(u=>u.type==="text"&&u.text);l.length&&(i.content=l.map(u=>u.text).join(`
|
|
48
|
+
`));let a=s.content.filter(u=>u.type==="tool_use"&&u.id);a.length&&(i.tool_calls=a.map(u=>({id:u.id,type:"function",function:{name:u.name,arguments:JSON.stringify(u.input||{})}})));let c=s.content.find(u=>u.type==="thinking");c&&(i.thinking={content:c.thinking,signature:c.signature}),t.push(i)}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:ds(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=gs(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,s]=e.body?e.body.tee():[null,null],i="";if(r){let d=r.getReader();try{let{value:g,done:f}=await d.read();!f&&g&&(i=new TextDecoder().decode(g))}finally{d.releaseLock()}r.cancel().catch(()=>{})}if((/^\s*(event:|data:|:\s*[A-Z])/m.test(i)||i.startsWith("data:"))&&s){let d=await this.convertOpenAIStreamToAnthropic(s,t);return new Response(d,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}let a=s?new Response(s,{status:e.status,statusText:e.statusText,headers:e.headers}):e,c=await F(a),u=this.convertOpenAIResponseToAnthropic(c,t);return new Response(JSON.stringify(u),{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,i=`msg_${Date.now()}`,l=null,a="unknown",c=!1,u=!1,d=!1,g=new Map,f=new Map,y=0,p=0,m=0,_=!1,k=!1,h=0,b=-1,T=()=>{let C=h;return h++,C},x=C=>{if(!_)try{r.enqueue(C);let P=new TextDecoder().decode(C);this.logger.debug({reqId:t.req.id,data:P,type:"send data"})}catch(P){if(P instanceof TypeError&&P.message.includes("Controller is already closed"))_=!0;else throw this.logger.debug({reqId:t.req.id,error:P instanceof Error?P.message:String(P),type:"send data error"}),P}},v=()=>{if(!_)try{if(!c){this.logger?.warn("[empty_stream] Upstream produced no data, closing silently"),r.close(),_=!0;return}if(b>=0){let P={type:"content_block_stop",index:b};x(s.encode(`event: content_block_stop
|
|
49
49
|
data: ${JSON.stringify(P)}
|
|
50
50
|
|
|
51
51
|
`)),b=-1}if(l)x(s.encode(`event: message_delta
|
|
@@ -64,53 +64,53 @@ data: ${JSON.stringify($)}
|
|
|
64
64
|
`));continue}if(a=D.model||a,!c&&!_&&!d){c=!0;let $=t?.req?.tokenCount||0,L={type:"message_start",message:{id:i,type:"message",role:"assistant",content:[],model:a,stop_reason:null,stop_sequence:null,usage:{input_tokens:$,output_tokens:0}}};x(s.encode(`event: message_start
|
|
65
65
|
data: ${JSON.stringify(L)}
|
|
66
66
|
|
|
67
|
-
`))}let
|
|
67
|
+
`))}let H=D.choices?.[0];if(D.usage){let $=D.usage?.prompt_tokens_details?.cached_tokens??D.usage?.prompt_cache_hit_tokens??0,W=(D.usage?.prompt_tokens||0)-$,ge=D.usage?.completion_tokens||0;this.logger?.info({debug_log:!0,reqId:t.req.id,phase:"anthropic_transformer_usage",providerUsage:D.usage,mappedUsage:{input_tokens:W,output_tokens:ge,cache_read_input_tokens:$},choicesLength:Array.isArray(D.choices)?D.choices.length:void 0,finishReason:H?.finish_reason});let j={input_tokens:W,output_tokens:ge,cache_read_input_tokens:$};if(!l)l={type:"message_delta",delta:{stop_reason:"end_turn",stop_sequence:null},usage:{...j}};else{let Y=l.usage||{};l.usage={input_tokens:j.input_tokens||Y.input_tokens||0,output_tokens:j.output_tokens||Y.output_tokens||0,cache_read_input_tokens:j.cache_read_input_tokens||Y.cache_read_input_tokens||0}}}if(!H)continue;if(H?.delta?.thinking&&!_&&!d&&!u){if(!k){let $=T(),L={type:"content_block_start",index:$,content_block:{type:"thinking",thinking:""}};x(s.encode(`event: content_block_start
|
|
68
68
|
data: ${JSON.stringify(L)}
|
|
69
69
|
|
|
70
|
-
`)),b=$,k=!0}if(
|
|
70
|
+
`)),b=$,k=!0}if(H.delta.thinking.signature){let $={type:"content_block_delta",index:b,delta:{type:"signature_delta",signature:H.delta.thinking.signature}};x(s.encode(`event: content_block_delta
|
|
71
71
|
data: ${JSON.stringify($)}
|
|
72
72
|
|
|
73
73
|
`));let L={type:"content_block_stop",index:b};x(s.encode(`event: content_block_stop
|
|
74
74
|
data: ${JSON.stringify(L)}
|
|
75
75
|
|
|
76
|
-
`)),b=-1}else if(
|
|
76
|
+
`)),b=-1}else if(H.delta.thinking.content){let $={type:"content_block_delta",index:b,delta:{type:"thinking_delta",thinking:H.delta.thinking.content||""}};x(s.encode(`event: content_block_delta
|
|
77
77
|
data: ${JSON.stringify($)}
|
|
78
78
|
|
|
79
|
-
`))}}if(
|
|
79
|
+
`))}}if(H?.delta?.content&&!_&&!d){if(p++,b>=0&&!u){let L={type:"content_block_stop",index:b};x(s.encode(`event: content_block_stop
|
|
80
80
|
data: ${JSON.stringify(L)}
|
|
81
81
|
|
|
82
82
|
`)),b=-1}if(!u&&!d){u=!0;let $=T(),L={type:"content_block_start",index:$,content_block:{type:"text",text:""}};x(s.encode(`event: content_block_start
|
|
83
83
|
data: ${JSON.stringify(L)}
|
|
84
84
|
|
|
85
|
-
`)),b=$}if(!_&&!d){let $={type:"content_block_delta",index:b,delta:{type:"text_delta",text:
|
|
85
|
+
`)),b=$}if(!_&&!d){let $={type:"content_block_delta",index:b,delta:{type:"text_delta",text:H.delta.content}};x(s.encode(`event: content_block_delta
|
|
86
86
|
data: ${JSON.stringify($)}
|
|
87
87
|
|
|
88
|
-
`))}}if(
|
|
88
|
+
`))}}if(H?.delta?.annotations?.length&&!_&&!d){if(b>=0&&u){let $={type:"content_block_stop",index:b};x(s.encode(`event: content_block_stop
|
|
89
89
|
data: ${JSON.stringify($)}
|
|
90
90
|
|
|
91
|
-
`)),b=-1,u=!1}
|
|
92
|
-
data: ${JSON.stringify(
|
|
91
|
+
`)),b=-1,u=!1}H?.delta?.annotations.forEach($=>{let L=T(),W={type:"content_block_start",index:L,content_block:{type:"web_search_tool_result",tool_use_id:`srvtoolu_${ao()}`,content:[{type:"web_search_result",title:$.url_citation.title,url:$.url_citation.url}]}};x(s.encode(`event: content_block_start
|
|
92
|
+
data: ${JSON.stringify(W)}
|
|
93
93
|
|
|
94
|
-
`));let
|
|
95
|
-
data: ${JSON.stringify(
|
|
94
|
+
`));let ge={type:"content_block_stop",index:L};x(s.encode(`event: content_block_stop
|
|
95
|
+
data: ${JSON.stringify(ge)}
|
|
96
96
|
|
|
97
|
-
`)),b=-1})}if(
|
|
98
|
-
data: ${JSON.stringify(
|
|
97
|
+
`)),b=-1})}if(H?.delta?.tool_calls&&!_&&!d){m++;let $=new Set;for(let L of H.delta.tool_calls){if(_)break;let W=L.index??0;if($.has(W))continue;if($.add(W),!f.has(W)){if(b>=0){let Zi={type:"content_block_stop",index:b};x(s.encode(`event: content_block_stop
|
|
98
|
+
data: ${JSON.stringify(Zi)}
|
|
99
99
|
|
|
100
|
-
`)),b=-1}let
|
|
100
|
+
`)),b=-1}let j=T();f.set(W,j);let Y=L.id||`call_ccr_${W}`,z=L.function?.name||`tool_${W}`,I={type:"content_block_start",index:j,content_block:{type:"tool_use",id:Y,name:z,input:{}}};x(s.encode(`event: content_block_start
|
|
101
101
|
data: ${JSON.stringify(I)}
|
|
102
102
|
|
|
103
|
-
`)),b=
|
|
104
|
-
data: ${JSON.stringify(
|
|
103
|
+
`)),b=j;let J={id:Y,name:z,arguments:"",contentBlockIndex:j};g.set(W,J)}else if(L.id&&L.function?.name){let j=g.get(W);j.id.startsWith("call_")&&j.name.startsWith("tool_")&&(j.id=L.id,j.name=L.function.name)}if(L.function?.arguments&&!_&&!d){let j=f.get(W);if(j===void 0)continue;let Y=g.get(W);Y&&(Y.arguments+=L.function.arguments);try{let z={type:"content_block_delta",index:j,delta:{type:"input_json_delta",partial_json:L.function.arguments}};x(s.encode(`event: content_block_delta
|
|
104
|
+
data: ${JSON.stringify(z)}
|
|
105
105
|
|
|
106
|
-
`))}catch{try{let
|
|
106
|
+
`))}catch{try{let z=L.function.arguments.replace(/[\x00-\x1F\x7F-\x9F]/g,"").replace(/\\/g,"\\\\").replace(/"/g,'\\"'),I={type:"content_block_delta",index:j,delta:{type:"input_json_delta",partial_json:z}};x(s.encode(`event: content_block_delta
|
|
107
107
|
data: ${JSON.stringify(I)}
|
|
108
108
|
|
|
109
|
-
`))}catch(
|
|
109
|
+
`))}catch(z){console.error(z)}}}}}if(H?.finish_reason&&!_&&!d){if(p===0&&m===0&&console.error("Warning: No content in the stream response!"),b>=0){let $={type:"content_block_stop",index:b};x(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"}[
|
|
113
|
-
`)||"",u={id:o.responseId,choices:[{finish_reason:o.candidates[0].finishReason?.toLowerCase()||null,index:0,message:{content:c,role:"assistant",tool_calls:a.length>0?a: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,i=!1,l=!1,a="",c=0,u=-1,d=new ReadableStream({async start(g){let
|
|
112
|
+
`)),b=-1}if(!_){let L={stop:"end_turn",length:"max_tokens",tool_calls:"tool_use",content_filter:"stop_sequence"}[H.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(D){this.logger?.error(`parseError: ${D.name} message: ${D.message} stack: ${D.stack} data: ${N}`)}}}v()}catch(C){if(!_)try{r.error(C)}catch(P){console.error(P)}}finally{if(S)try{S.releaseLock()}catch(C){console.error(C)}}},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 a=`srvtoolu_${ao()}`;r.push({type:"server_tool_use",id:a,name:"web_search",input:{query:""}}),r.push({type:"web_search_tool_result",tool_use_id:a,content:o.message.annotations.map(c=>({type:"web_search_result",url:c.url_citation.url,title:c.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(a=>{let c={};try{let u=a.function.arguments||"{}";typeof u=="object"?c=u:typeof u=="string"&&(c=JSON.parse(u))}catch{c={text:a.function.arguments||""}}r.push({type:"tool_use",id:a.id,name:a.function.name,input:c})}),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??e.usage?.prompt_cache_hit_tokens??0,i=(e.usage?.prompt_tokens||0)-s,l={id:e.id?.startsWith("msg_")?e.id:`msg_${ao().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:i,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 vc(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($e).includes(o)?o:$e.TYPE_UNSPECIFIED}else{e.anyOf=[];for(let o of t){let r=o.toUpperCase();e.anyOf.push({type:Object.values($e).includes(r)?r:$e.TYPE_UNSPECIFIED})}}}function nt(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)&&vc(n.type,e);for(let[i,l]of Object.entries(n))if(l!=null)if(i=="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 a=l.toUpperCase();e.type=Object.values($e).includes(a)?a:$e.TYPE_UNSPECIFIED}else if(t.includes(i))e[i]=nt(l);else if(o.includes(i)){let a=[];for(let c of l){if(c.type=="null"){e.nullable=!0;continue}a.push(nt(c))}e[i]=a}else if(r.includes(i)){let a={};for(let[c,u]of Object.entries(l))a[c]=nt(u);e[i]=a}else{if(i==="additionalProperties")continue;e[i]=l}return e}function xc(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=nt(e.parameters)),e.response&&(Object.keys(e.response).includes("$schema")?e.responseJsonSchema||(e.responseJsonSchema=e.response,delete e.response):e.response=nt(e.response));return n}function Ft(n){let e=[],t=n.tools?.filter(a=>a.function.name!=="web_search")?.map(a=>({name:a.function.name,description:a.function.description,parametersJsonSchema:a.function.parameters}));t?.length&&e.push(xc({functionDeclarations:t})),n.tools?.find(a=>a.function.name==="web_search")&&e.push({googleSearch:{}});let r=[],s=n.messages.filter(a=>a.role==="tool");n.messages.filter(a=>a.role!=="tool").forEach(a=>{let c;a.role==="assistant"?c="model":(["user","system"].includes(a.role),c="user");let u=[];if(typeof a.content=="string"){let d={text:a.content};a.thinking?.signature&&(d.thoughtSignature=a.thinking.signature),u.push(d)}else Array.isArray(a.content)?u.push(...a.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}}})):a.content&&typeof a.content=="object"&&(a.content.text?u.push({text:a.content.text}):u.push({text:JSON.stringify(a.content)}));if(Array.isArray(a.tool_calls)&&u.push(...a.tool_calls.map(d=>{let g={functionCall:{id:d.id||`tool_${Math.random().toString(36).substring(2,15)}`,name:d.function.name,args:JSON.parse(d.function.arguments||"{}")}};return a.thinking?.signature&&(g.thoughtSignature=a.thinking.signature),g})),u.length===0&&u.push({text:""}),r.push({role:c,parts:u}),c==="model"&&a.tool_calls){let d=a.tool_calls.map(g=>{let f=s.find(y=>y.tool_call_id===g.id);return{functionResponse:{name:g?.function?.name,response:{result:f?.content}}}});r.push({role:"user",parts:d})}});let i={};if(n.reasoning&&n.reasoning.effort&&n.reasoning.effort!=="none")if(i.thinkingConfig={includeThoughts:!0},n.model.includes("gemini-3"))i.thinkingConfig.thinkingLevel=n.reasoning.effort;else{let a=n.model.includes("pro")?[128,32768]:[0,24576],c,u=n.reasoning.max_tokens;typeof u<"u"&&(u>=a[0]&&u<=a[1]?c=u:u<a[0]?c=a[0]:u>a[1]&&(c=a[1]),i.thinkingConfig.thinkingBudget=c)}let l={contents:r,tools:e.length?e:void 0,generationConfig:i};if(n.tool_choice){let a={functionCallingConfig:{}};n.tool_choice==="auto"?a.functionCallingConfig.mode="auto":n.tool_choice==="none"?a.functionCallingConfig.mode="none":n.tool_choice==="required"?a.functionCallingConfig.mode="any":n.tool_choice?.function?.name&&(a.functionCallingConfig.mode="any",a.functionCallingConfig.allowedFunctionNames=[n.tool_choice?.function?.name]),l.toolConfig=a}return l}function Ut(n){let e=n.contents,t=n.tools,o=n.model,r=n.max_tokens,s=n.temperature,i=n.stream,l=n.tool_choice,a={messages:[],model:o,max_tokens:r,temperature:s,stream:i,tool_choice:l};return Array.isArray(e)&&e.forEach(c=>{typeof c=="string"?a.messages.push({role:"user",content:c}):typeof c.text=="string"?a.messages.push({role:"user",content:c.text||null}):c.role==="user"?a.messages.push({role:"user",content:c?.parts?.map(u=>({type:"text",text:u.text||""}))||[]}):c.role==="model"&&a.messages.push({role:"assistant",content:c?.parts?.map(u=>({type:"text",text:u.text||""}))||[]})}),Array.isArray(t)&&(a.tools=[],t.forEach(c=>{Array.isArray(c.functionDeclarations)&&c.functionDeclarations.forEach(u=>{a.tools.push({type:"function",function:{name:u.name,description:u.description,parameters:u.parameters}})})})),a}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="",i=o.candidates[0]?.content?.parts||[],l=[];for(let d of i)d.text&&d.thought===!0?r+=d.text:l.push(d);s=i.find(d=>d.thoughtSignature)?.thoughtSignature;let a=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||{})}}))||[],c=l?.filter(d=>d.text)?.map(d=>d.text)?.join(`
|
|
113
|
+
`)||"",u={id:o.responseId,choices:[{finish_reason:o.candidates[0].finishReason?.toLowerCase()||null,index:0,message:{content:c,role:"assistant",tool_calls:a.length>0?a: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,i=!1,l=!1,a="",c=0,u=-1,d=new ReadableStream({async start(g){let f=async(m,_)=>{if(m.startsWith("data: ")){let k=m.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],T=b.content?.parts||[];T.filter(C=>C.text&&C.thought===!0).forEach(C=>{l||(l=!0);let P={choices:[{delta:{role:"assistant",content:null,thinking:{content:C.text}},finish_reason:null,index:c,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(P)}
|
|
114
114
|
|
|
115
115
|
`))});let x=T.find(C=>C.thoughtSignature)?.thoughtSignature;if(x&&!s){if(!l){let P={choices:[{delta:{role:"assistant",content:null,thinking:{content:"(no content)"}},finish_reason:null,index:c,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(P)}
|
|
116
116
|
|
|
@@ -127,93 +127,93 @@ data: ${JSON.stringify($)}
|
|
|
127
127
|
|
|
128
128
|
`)),!i&&S&&(i=!0)}v.length>0&&(v.forEach(C=>{c++,u++;let P={choices:[{delta:{role:"assistant",tool_calls:[{...C,index:u}]},finish_reason:b.finishReason?.toLowerCase()||null,index:c,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&&(P.choices[0].delta.annotations=b.groundingMetadata.groundingChunks.map((R,O)=>{let E=b?.groundingMetadata?.groundingSupports?.filter(A=>A.groundingChunkIndices?.includes(O));return{type:"url_citation",url_citation:{url:R?.web?.uri||"",title:R?.web?.title||"",content:E?.[0]?.segment?.text||"",start_index:E?.[0]?.segment?.startIndex||0,end_index:E?.[0]?.segment?.endIndex||0}}})),_.enqueue(r.encode(`data: ${JSON.stringify(P)}
|
|
129
129
|
|
|
130
|
-
`))}),!i&&S&&(i=!0))}catch(h){t?.error(`Error parsing ${e} stream chunk`,k,h.message)}}}},y=n.body.getReader(),p="";try{for(;;){let{done:
|
|
131
|
-
`);p=k.pop()||"";for(let h of k)await
|
|
130
|
+
`))}),!i&&S&&(i=!0))}catch(h){t?.error(`Error parsing ${e} stream chunk`,k,h.message)}}}},y=n.body.getReader(),p="";try{for(;;){let{done:m,value:_}=await y.read();if(m){p&&await f(p,g);break}p+=o.decode(_,{stream:!0});let k=p.split(`
|
|
131
|
+
`);p=k.pop()||"";for(let h of k)await f(h,g)}}catch(m){g.error(m)}finally{g.close()}}});return new Response(d,{status:n.status,statusText:n.statusText,headers:n.headers})}}var $e,co=w(()=>{"use strict";$e={TYPE_UNSPECIFIED:"TYPE_UNSPECIFIED",STRING:"STRING",NUMBER:"NUMBER",INTEGER:"INTEGER",BOOLEAN:"BOOLEAN",ARRAY:"ARRAY",OBJECT:"OBJECT",NULL:"NULL"}});var Ht,_s=w(()=>{"use strict";co();Ht=class{name="gemini";endPoint="/v1beta/models/:modelAndAction";async transformRequestIn(e,t){return{body:Ft(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=Ut;async transformResponseOut(e){return jt(e,this.name,this.logger)}}});async function Sc(){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
|
|
135
|
-
`);for(let
|
|
136
|
-
`))},d=(g,
|
|
134
|
+
3. Use Google Cloud environment with default service account`)}}var zt,ks=w(()=>{"use strict";co();zt=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"),a=JSON.parse(l);a&&a.project_id&&(o=a.project_id)}catch(i){console.error("Error extracting project_id from GOOGLE_APPLICATION_CREDENTIALS:",i)}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 Sc();return{body:Ft(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 Ut(e)}async transformResponseOut(e){return jt(e,this.name)}}});var Jt,bs=w(()=>{"use strict";Q();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,i=r.thinking?.signature,l="";if(typeof r.content=="string"){let c=/<thinking>([\s\S]*?)<\/thinking>/g.exec(r.content);c&&(l=c[1].trim(),r.content=r.content.replace(c[0],"").trim())}s&&typeof s=="string"&&s.trim()?(r.reasoning_content=s,i&&(r.reasoning_content_signature=i)):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 F(e);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,i="",l=new ReadableStream({async start(a){let c=e.body.getReader(),u=(g,f,y)=>{let p=g.split(`
|
|
135
|
+
`);for(let m of p)m.trim()&&f.enqueue(y.encode(m+`
|
|
136
|
+
`))},d=(g,f)=>{let{controller:y,encoder:p}=f;if(g.startsWith("data: ")&&g.trim()!=="data: [DONE]")try{let m=JSON.parse(g.slice(6));if(m.choices?.[0]?.delta?.reasoning_content){f.appendReasoningContent(m.choices[0].delta.reasoning_content);let _={...m,choices:[{...m.choices[0],delta:{...m.choices[0].delta,thinking:{content:m.choices[0].delta.reasoning_content}}}]};delete _.choices[0].delta.reasoning_content;let k=`data: ${JSON.stringify(_)}
|
|
137
137
|
|
|
138
|
-
`;y.enqueue(p.encode(k));return}if(
|
|
138
|
+
`;y.enqueue(p.encode(k));return}if(m.choices?.[0]?.delta?.content&&f.reasoningContent()&&!f.isReasoningComplete()){f.setReasoningComplete(!0);let _="ccr_think_signature",k=m.choices[0].delta.content,h={...m,choices:[{...m.choices[0],delta:{...m.choices[0].delta,content:null,thinking:{content:f.reasoningContent(),signature:_}}}]};delete h.choices[0].delta.reasoning_content;let b=`data: ${JSON.stringify(h)}
|
|
139
139
|
|
|
140
|
-
`;y.enqueue(p.encode(b));let T={...
|
|
140
|
+
`;y.enqueue(p.encode(b));let T={...m,choices:[{...m.choices[0],delta:{...m.choices[0].delta,content:k}}]};delete T.choices[0].delta.reasoning_content;let x=`data: ${JSON.stringify(T)}
|
|
141
141
|
|
|
142
|
-
`;y.enqueue(p.encode(x));return}if(
|
|
142
|
+
`;y.enqueue(p.encode(x));return}if(m.choices[0]?.delta?.reasoning_content&&delete m.choices[0].delta.reasoning_content,m.choices?.[0]?.delta&&Object.keys(m.choices[0].delta).length>0){let _=`data: ${JSON.stringify(m)}
|
|
143
143
|
|
|
144
144
|
`;y.enqueue(p.encode(_))}}catch{y.enqueue(p.encode(g+`
|
|
145
145
|
`))}else y.enqueue(p.encode(g+`
|
|
146
|
-
`))};try{for(;;){let{done:g,value:
|
|
147
|
-
`);i=p.pop()||"";for(let
|
|
148
|
-
`))}}}catch(g){console.error("Stream error:",g),a.error(g)}finally{try{c.releaseLock()}catch(g){console.error("Error releasing reader lock:",g)}a.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
|
|
146
|
+
`))};try{for(;;){let{done:g,value:f}=await c.read();if(g){i.trim()&&u(i,a,o);break}let y=t.decode(f,{stream:!0});i+=y;let p=i.split(`
|
|
147
|
+
`);i=p.pop()||"";for(let m of p)if(m.trim())try{d(m,{controller:a,encoder:o,reasoningContent:()=>r,appendReasoningContent:_=>r+=_,isReasoningComplete:()=>s,setReasoningComplete:_=>s=_})}catch(_){console.error("Error processing line:",m,_),a.enqueue(o.encode(m+`
|
|
148
|
+
`))}}}catch(g){console.error("Stream error:",g),a.error(g)}finally{try{c.releaseLock()}catch(g){console.error("Error releasing reader lock:",g)}a.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,Ts=w(()=>{"use strict";Q();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.
|
|
152
|
-
2. Task: "What\u2019s the weather today?" \u2014 If no tool is available to answer, use ExitTool after reasoning that none can fulfill the task.`,parameters:{type:"object",properties:{response:{type:"string",description:"Your response will be forwarded to the user exactly as returned \u2014 the tool will not modify or post-process it in any way."}},required:["response"]}}})),e}async transformResponseOut(e){if(e.headers.get("Content-Type")?.includes("application/json")){let t=await e
|
|
153
|
-
`);for(let
|
|
154
|
-
`))},d=(g,
|
|
152
|
+
2. Task: "What\u2019s the weather today?" \u2014 If no tool is available to answer, use ExitTool after reasoning that none can fulfill the task.`,parameters:{type:"object",properties:{response:{type:"string",description:"Your response will be forwarded to the user exactly as returned \u2014 the tool will not modify or post-process it in any way."}},required:["response"]}}})),e}async transformResponseOut(e){if(e.headers.get("Content-Type")?.includes("application/json")){let t=await F(e);if(t?.choices?.[0]?.message.tool_calls?.length&&t?.choices?.[0]?.message.tool_calls[0]?.function?.name==="ExitTool"){let o=t?.choices[0]?.message.tool_calls[0],r=JSON.parse(o.function.arguments||"{}");t.choices[0].message.content=r.response||"",delete t.choices[0].message.tool_calls}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="",i="",l=new ReadableStream({async start(a){let c=e.body.getReader(),u=(g,f,y)=>{let p=g.split(`
|
|
153
|
+
`);for(let m of p)m.trim()&&f.enqueue(y.encode(m+`
|
|
154
|
+
`))},d=(g,f)=>{let{controller:y,encoder:p,exitToolIndex:m,setExitToolIndex:_,appendExitToolResponse:k}=f;if(g.startsWith("data: ")&&g.trim()!=="data: [DONE]")try{let h=JSON.parse(g.slice(6));if(h.choices[0]?.delta?.tool_calls?.length){let b=h.choices[0].delta.tool_calls[0];if(b.function?.name==="ExitTool"){_(b.index);return}else if(m()>-1&&b.index===m()&&b.function.arguments){k(b.function.arguments);try{let T=JSON.parse(f.exitToolResponse());h.choices=[{delta:{role:"assistant",content:T.response||""}}];let x=`data: ${JSON.stringify(h)}
|
|
155
155
|
|
|
156
156
|
`;y.enqueue(p.encode(x))}catch{}return}}if(h.choices?.[0]?.delta&&Object.keys(h.choices[0].delta).length>0){let b=`data: ${JSON.stringify(h)}
|
|
157
157
|
|
|
158
158
|
`;y.enqueue(p.encode(b))}}catch{y.enqueue(p.encode(g+`
|
|
159
159
|
`))}else y.enqueue(p.encode(g+`
|
|
160
|
-
`))};try{for(;;){let{done:g,value:
|
|
161
|
-
`);i=p.pop()||"";for(let
|
|
162
|
-
`))}}}catch(g){console.error("Stream error:",g),a.error(g)}finally{try{c.releaseLock()}catch(g){console.error("Error releasing reader lock:",g)}a.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
|
|
163
|
-
`);for(let k of _)k.trim()&&p.enqueue(
|
|
164
|
-
`))},
|
|
160
|
+
`))};try{for(;;){let{done:g,value:f}=await c.read();if(g){i.trim()&&u(i,a,o);break}let y=t.decode(f,{stream:!0});i+=y;let p=i.split(`
|
|
161
|
+
`);i=p.pop()||"";for(let m of p)if(m.trim())try{d(m,{controller:a,encoder:o,exitToolIndex:()=>r,setExitToolIndex:_=>r=_,exitToolResponse:()=>s,appendExitToolResponse:_=>s+=_})}catch(_){console.error("Error processing line:",m,_),a.enqueue(o.encode(m+`
|
|
162
|
+
`))}}}catch(g){console.error("Stream error:",g),a.error(g)}finally{try{c.releaseLock()}catch(g){console.error("Error releasing reader lock:",g)}a.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 Rc}from"uuid";var Wt,Cs=w(()=>{"use strict";Q();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 F(e);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="",i=!1,l=!1,a="",c=new ReadableStream({async start(u){let d=e.body.getReader(),g=(y,p,m)=>{let _=y.split(`
|
|
163
|
+
`);for(let k of _)k.trim()&&p.enqueue(m.encode(k+`
|
|
164
|
+
`))},f=(y,p)=>{let{controller:m,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"){m.enqueue(_.encode(`data: ${JSON.stringify({error:h.choices?.[0].error})}
|
|
165
165
|
|
|
166
166
|
`));return}h.choices?.[0]?.delta?.content&&!p.hasTextContent()&&p.setHasTextContent(!0);let b=h.choices?.[0]?.delta?.reasoning||h.choices?.[0]?.delta?.reasoning_content;if(b){p.appendReasoningContent(b);let C={...h,choices:[{...h.choices?.[0],delta:{...h.choices[0].delta,thinking:{content:b}}}]};C.choices?.[0]?.delta&&(delete C.choices[0].delta.reasoning,delete C.choices[0].delta.reasoning_content);let P=`data: ${JSON.stringify(C)}
|
|
167
167
|
|
|
168
|
-
`;
|
|
168
|
+
`;m.enqueue(_.encode(P));return}if(h.choices?.[0]?.delta?.content&&p.reasoningContent()&&!p.isReasoningComplete()){p.setReasoningComplete(!0);let C="ccr_think_signature",P=h.choices[0].delta.content,R={...h,choices:[{...h.choices?.[0],delta:{...h.choices[0].delta,content:null,thinking:{content:p.reasoningContent(),signature:C}}}]};R.choices?.[0]?.delta&&delete R.choices[0].delta.reasoning;let O=`data: ${JSON.stringify(R)}
|
|
169
169
|
|
|
170
|
-
`;
|
|
170
|
+
`;m.enqueue(_.encode(O));let E={...h,choices:[{...h.choices?.[0],delta:{...h.choices[0].delta,content:P}}]};E.choices?.[0]?.delta&&(delete E.choices[0].delta.reasoning,delete E.choices[0].delta.reasoning_content);let A=`data: ${JSON.stringify(E)}
|
|
171
171
|
|
|
172
|
-
`;
|
|
172
|
+
`;m.enqueue(_.encode(A));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(C=>{C.id=`call_${Rc()}`}),h.choices?.[0]?.delta?.tool_calls?.length&&!l&&(l=!0);let T=h.choices?.[0]?.delta,x=T&&Object.keys(T).length>0,v=h.choices?.[0]?.finish_reason,S=h.usage;if(x||v||S){let C=`data: ${JSON.stringify(h)}
|
|
173
173
|
|
|
174
|
-
`;
|
|
175
|
-
`))}}else
|
|
176
|
-
`))};try{for(;;){let{done:y,value:p}=await d.read();if(y){a.trim()&&g(a,u,o);break}if(!p||p.length===0)continue;let
|
|
177
|
-
`);a=k.pop()||"";for(let h of k)if(h.trim())try{
|
|
174
|
+
`;m.enqueue(_.encode(C))}}catch{m.enqueue(_.encode(y+`
|
|
175
|
+
`))}}else m.enqueue(_.encode(y+`
|
|
176
|
+
`))};try{for(;;){let{done:y,value:p}=await d.read();if(y){a.trim()&&g(a,u,o);break}if(!p||p.length===0)continue;let m;try{m=t.decode(p,{stream:!0})}catch(k){console.warn("Failed to decode chunk",k);continue}if(m.length===0)continue;if(a+=m,a.length>1e6){console.warn("Buffer size exceeds limit, processing partial data");let k=a.split(`
|
|
177
|
+
`);a=k.pop()||"";for(let h of k)if(h.trim())try{f(h,{controller:u,encoder:o,hasTextContent:()=>r,setHasTextContent:b=>r=b,reasoningContent:()=>s,appendReasoningContent:b=>s+=b,isReasoningComplete:()=>i,setReasoningComplete:b=>i=b})}catch(b){console.error("Error processing line:",h,b),u.enqueue(o.encode(h+`
|
|
178
178
|
`))}continue}let _=a.split(`
|
|
179
|
-
`);a=_.pop()||"";for(let k of _)if(k.trim())try{
|
|
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(c,{status:e.status,statusText:e.statusText,headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}return e}}});var
|
|
181
|
-
`);for(let _ of
|
|
182
|
-
`))},g=(
|
|
183
|
-
|
|
184
|
-
`;p.enqueue(
|
|
185
|
-
`))}}else p.enqueue(
|
|
186
|
-
`))};try{for(;;){let{done:
|
|
179
|
+
`);a=_.pop()||"";for(let k of _)if(k.trim())try{f(k,{controller:u,encoder:o,hasTextContent:()=>r,setHasTextContent:h=>r=h,reasoningContent:()=>s,appendReasoningContent:h=>s+=h,isReasoningComplete:()=>i,setReasoningComplete:h=>i=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(c,{status:e.status,statusText:e.statusText,headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}return e}}});var Gt,vs=w(()=>{"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 wc}from"uuid";var Kt,xs=w(()=>{"use strict";Q();Kt=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 F(e);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="",i=!1,l="",a=new ReadableStream({async start(c){let u=e.body.getReader(),d=(f,y,p)=>{let m=f.split(`
|
|
181
|
+
`);for(let _ of m)_.trim()&&y.enqueue(p.encode(_+`
|
|
182
|
+
`))},g=(f,y)=>{let{controller:p,encoder:m}=y;if(f.startsWith("data: ")&&f.trim()!=="data: [DONE]"){let _=f.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_${wc()}`}),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
|
+
|
|
184
|
+
`;p.enqueue(m.encode(h))}catch{p.enqueue(m.encode(f+`
|
|
185
|
+
`))}}else p.enqueue(m.encode(f+`
|
|
186
|
+
`))};try{for(;;){let{done:f,value:y}=await u.read();if(f){l.trim()&&d(l,c,o);break}if(!y||y.length===0)continue;let p;try{p=t.decode(y,{stream:!0})}catch(_){console.warn("Failed to decode chunk",_);continue}if(p.length===0)continue;if(l+=p,l.length>1e6){console.warn("Buffer size exceeds limit, processing partial data");let _=l.split(`
|
|
187
187
|
`);l=_.pop()||"";for(let k of _)if(k.trim())try{g(k,{controller:c,encoder:o,hasTextContent:()=>r,setHasTextContent:h=>r=h,reasoningContent:()=>s,appendReasoningContent:h=>s+=h,isReasoningComplete:()=>i,setReasoningComplete:h=>i=h})}catch(h){console.error("Error processing line:",k,h),c.enqueue(o.encode(k+`
|
|
188
|
-
`))}continue}let
|
|
189
|
-
`);l=
|
|
190
|
-
`))}}}catch(
|
|
188
|
+
`))}continue}let m=l.split(`
|
|
189
|
+
`);l=m.pop()||"";for(let _ of m)if(_.trim())try{g(_,{controller:c,encoder:o,hasTextContent:()=>r,setHasTextContent:k=>r=k,reasoningContent:()=>s,appendReasoningContent:k=>s+=k,isReasoningComplete:()=>i,setReasoningComplete:k=>i=k})}catch(k){console.error("Error processing line:",_,k),c.enqueue(o.encode(_+`
|
|
190
|
+
`))}}}catch(f){console.error("Stream error:",f),c.error(f)}finally{try{u.releaseLock()}catch(f){console.error("Error releasing reader lock:",f)}c.close()}}});return new Response(a,{status:e.status,statusText:e.statusText,headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}return e}}});var Qt,Ss=w(()=>{"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 Pc from"json5";import{jsonrepair as Ec}from"jsonrepair";function lo(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=Pc.parse(n);return e?.debug("Tool arguments JSON5 parsing successful"),JSON.stringify(o)}catch(o){try{let r=Ec(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 Rs=w(()=>{});var Vt,ws=w(()=>{"use strict";Rs();Q();Vt=class{name="enhancetool";async transformResponseOut(e){if(e.headers.get("Content-Type")?.includes("application/json")){let t=await F(e);if(t?.choices?.[0]?.message?.tool_calls?.length)for(let o of t.choices[0].message.tool_calls)o.function?.arguments&&(o.function.arguments=lo(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,i="",l=!1,a=!1,c="",u=new ReadableStream({async start(d){let g=e.body.getReader(),f=(m,_,k)=>{let h=m.split(`
|
|
191
191
|
`);for(let b of h)b.trim()&&_.enqueue(k.encode(b+`
|
|
192
|
-
`))},y=(
|
|
192
|
+
`))},y=(m,_,k)=>{let h="";try{h=lo(r.arguments||"",this.logger)}catch(v){console.error(`${v.message} ${v.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"}]},T={...m,choices:[{...m.choices[0],delta:b}]};T.choices[0].delta.content!==void 0&&delete T.choices[0].delta.content;let x=`data: ${JSON.stringify(T)}
|
|
193
193
|
|
|
194
|
-
`;_.enqueue(k.encode(x))},p=(
|
|
194
|
+
`;_.enqueue(k.encode(x))},p=(m,_)=>{let{controller:k,encoder:h}=_;if(m.startsWith("data: ")&&m.trim()!=="data: [DONE]"){let b=m.slice(6);try{let T=JSON.parse(b);if(T.choices?.[0]?.delta?.tool_calls?.length){let v=T.choices[0].delta.tool_calls[0];if(typeof r.index>"u"){r={index:v.index,name:v.function?.name||"",id:v.id||"",arguments:v.function?.arguments||""},v.function?.arguments&&(v.function.arguments="");let S=`data: ${JSON.stringify(T)}
|
|
195
195
|
|
|
196
196
|
`;k.enqueue(h.encode(S));return}else if(r.index===v.index){v.function?.arguments&&(r.arguments+=v.function.arguments);return}else{y(T,k,h),r={index:v.index,name:v.function?.name||"",id:v.id||"",arguments:v.function?.arguments||""};return}}if(T.choices?.[0]?.finish_reason==="tool_calls"&&r.index!==void 0){y(T,k,h),r={};return}T.choices?.[0]?.delta?.tool_calls?.length&&_.hasTextContent()&&(typeof T.choices[0].index=="number"?T.choices[0].index+=1:T.choices[0].index=1);let x=`data: ${JSON.stringify(T)}
|
|
197
197
|
|
|
198
|
-
`;k.enqueue(h.encode(x))}catch{k.enqueue(h.encode(
|
|
199
|
-
`))}}else k.enqueue(h.encode(
|
|
200
|
-
`))};try{for(;;){let{done:
|
|
198
|
+
`;k.enqueue(h.encode(x))}catch{k.enqueue(h.encode(m+`
|
|
199
|
+
`))}}else k.enqueue(h.encode(m+`
|
|
200
|
+
`))};try{for(;;){let{done:m,value:_}=await g.read();if(m){c.trim()&&f(c,d,o);break}if(!_||_.length===0)continue;let k;try{k=t.decode(_,{stream:!0})}catch(b){console.warn("Failed to decode chunk",b);continue}if(k.length===0)continue;if(c+=k,c.length>1e6){console.warn("Buffer size exceeds limit, processing partial data");let b=c.split(`
|
|
201
201
|
`);c=b.pop()||"";for(let T of b)if(T.trim())try{p(T,{controller:d,encoder:o,hasTextContent:()=>s,setHasTextContent:x=>s=x,reasoningContent:()=>i,appendReasoningContent:x=>i+=x,isReasoningComplete:()=>l,setReasoningComplete:x=>l=x})}catch(x){console.error("Error processing line:",T,x),d.enqueue(o.encode(T+`
|
|
202
202
|
`))}continue}let h=c.split(`
|
|
203
203
|
`);c=h.pop()||"";for(let b of h)if(b.trim())try{p(b,{controller:d,encoder:o,hasTextContent:()=>s,setHasTextContent:T=>s=T,reasoningContent:()=>i,appendReasoningContent:T=>i+=T,isReasoningComplete:()=>l,setReasoningComplete:T=>l=T})}catch(T){console.error("Error processing line:",b,T),d.enqueue(o.encode(b+`
|
|
204
|
-
`))}}}catch(
|
|
205
|
-
`);for(let
|
|
206
|
-
`))},d=(g,
|
|
204
|
+
`))}}}catch(m){console.error("Stream error:",m),d.error(m)}finally{try{g.releaseLock()}catch(m){console.error("Error releasing reader lock:",m)}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 Yt,Ps=w(()=>{"use strict";Q();Yt=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 F(e);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,i="",l=new ReadableStream({async start(a){let c=e.body.getReader(),u=(g,f,y)=>{let p=g.split(`
|
|
205
|
+
`);for(let m of p)m.trim()&&f.enqueue(y.encode(m+`
|
|
206
|
+
`))},d=(g,f)=>{let{controller:y,encoder:p}=f;if(this.logger?.debug({line:g},"Processing reason line"),g.startsWith("data: ")&&g.trim()!=="data: [DONE]")try{let m=JSON.parse(g.slice(6));if(console.log(JSON.stringify(m)),m.choices?.[0]?.delta?.reasoning_content){f.appendReasoningContent(m.choices[0].delta.reasoning_content);let _={...m,choices:[{...m.choices[0],delta:{...m.choices[0].delta,thinking:{content:m.choices[0].delta.reasoning_content}}}]};delete _.choices[0].delta.reasoning_content;let k=`data: ${JSON.stringify(_)}
|
|
207
207
|
|
|
208
|
-
`;y.enqueue(p.encode(k));return}if(
|
|
208
|
+
`;y.enqueue(p.encode(k));return}if(m.choices?.[0]?.delta?.content&&f.reasoningContent()&&!f.isReasoningComplete()){f.setReasoningComplete(!0);let _="ccr_think_signature",k=m.choices[0].delta.content,h={...m,choices:[{...m.choices[0],delta:{...m.choices[0].delta,content:null,thinking:{content:f.reasoningContent(),signature:_}}}]};delete h.choices[0].delta.reasoning_content;let b=`data: ${JSON.stringify(h)}
|
|
209
209
|
|
|
210
|
-
`;y.enqueue(p.encode(b))}if(
|
|
210
|
+
`;y.enqueue(p.encode(b))}if(m.choices?.[0]?.delta?.reasoning_content&&delete m.choices[0].delta.reasoning_content,m.choices?.[0]?.delta&&Object.keys(m.choices[0].delta).length>0){f.isReasoningComplete()&&m.choices[0].index++;let _=`data: ${JSON.stringify(m)}
|
|
211
211
|
|
|
212
212
|
`;y.enqueue(p.encode(_))}}catch{y.enqueue(p.encode(g+`
|
|
213
213
|
`))}else y.enqueue(p.encode(g+`
|
|
214
|
-
`))};try{for(;;){let{done:g,value:
|
|
215
|
-
`);i=p.pop()||"";for(let
|
|
216
|
-
`))}}}catch(g){console.error("Stream error:",g),a.error(g)}finally{try{c.releaseLock()}catch(g){console.error("Error releasing reader lock:",g)}a.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
|
|
214
|
+
`))};try{for(;;){let{done:g,value:f}=await c.read();if(g){i.trim()&&u(i,a,o);break}let y=t.decode(f,{stream:!0});i+=y;let p=i.split(`
|
|
215
|
+
`);i=p.pop()||"";for(let m of p)if(m.trim())try{d(m,{controller:a,encoder:o,reasoningContent:()=>r,appendReasoningContent:_=>r+=_,isReasoningComplete:()=>s,setReasoningComplete:_=>s=_})}catch(_){console.error("Error processing line:",m,_),a.enqueue(o.encode(m+`
|
|
216
|
+
`))}}}catch(g){console.error("Stream error:",g),a.error(g)}finally{try{c.releaseLock()}catch(g){console.error("Error releasing reader lock:",g)}a.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 Xt,Es=w(()=>{"use strict";Xt=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,Os=w(()=>{"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 As(n){let e=[];for(let o=0;o<n.messages.length;o++){let r=n.messages[o],s=o===n.messages.length-1,i=r.role==="assistant",l=[];typeof r.content=="string"?l.push({type:"text",text:r.content}):Array.isArray(r.content)&&r.content.forEach(a=>{a.type==="text"?l.push({type:"text",text:a.text||""}):a.type==="image_url"&&l.push({type:"image",source:{type:"base64",media_type:a.media_type||"image/jpeg",data:a.image_url.url}})}),!(!s&&l.length===0&&!r.tool_calls&&!r.content)&&(s&&i&&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 Is(n){let e=n,o={messages:e.messages.map(r=>{let s=r.content.map(i=>i.type==="text"?{type:"text",text:i.text||""}:i.type==="image"&&i.source?{type:"image_url",image_url:{url:i.source.data},media_type:i.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 Ms(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(i=>({id:i.id,type:"function",function:{name:i.name,arguments:JSON.stringify(i.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,a)=>{if(l.startsWith("data: ")){let c=l.slice(6).trim();if(c){t?.debug({chunkStr:c},`${e} chunk:`);try{let u=JSON.parse(c);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)}};a.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)}};a.enqueue(r.encode(`data: ${JSON.stringify(d)}
|
|
219
219
|
|
|
@@ -226,93 +226,93 @@ 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)}};a.enqueue(r.encode(`data: ${JSON.stringify(d)}
|
|
227
227
|
|
|
228
228
|
`))}}catch(u){t?.error(`Error parsing ${e} stream chunk`,c,u.message)}}}},i=new ReadableStream({async start(l){let a=n.body.getReader(),c="";try{for(;;){let{done:u,value:d}=await a.read();if(u){c&&s(c,l);break}c+=o.decode(d,{stream:!0});let g=c.split(`
|
|
229
|
-
`);c=g.pop()||"";for(let
|
|
229
|
+
`);c=g.pop()||"";for(let f of g)s(f,l)}}catch(u){l.error(u)}finally{l.close()}}});return new Response(i,{status:n.status,statusText:n.statusText,headers:n.headers})}return n}var $s=w(()=>{"use strict"});async function Oc(){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
|
|
233
|
-
`);for(let k of _)k.trim()&&p.enqueue(
|
|
234
|
-
`))},
|
|
232
|
+
3. Use Google Cloud environment with default service account`)}}var Zt,Ns=w(()=>{"use strict";$s();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"),a=JSON.parse(l);a&&a.project_id&&(o=a.project_id)}catch(i){console.error("Error extracting project_id from GOOGLE_APPLICATION_CREDENTIALS:",i)}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 Oc();return{body:As(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 Is(e)}async transformResponseOut(e){return Ms(e,this.name,this.logger)}}});var en,Ls=w(()=>{"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,Ds=w(()=>{"use strict";tn=class{name="streamoptions";async transformRequestIn(e){return e.stream&&(e.stream_options={include_usage:!0}),e}}});var nn,Fs=w(()=>{"use strict";nn=class{name="OpenAI";endPoint="/v1/chat/completions"}});var on,Us=w(()=>{"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 Ac}from"uuid";var rn,js=w(()=>{"use strict";Q();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 F(e);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="",i=!1,l=!1,a="",c=new ReadableStream({async start(u){let d=e.body.getReader(),g=(y,p,m)=>{let _=y.split(`
|
|
233
|
+
`);for(let k of _)k.trim()&&p.enqueue(m.encode(k+`
|
|
234
|
+
`))},f=(y,p)=>{let{controller:m,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"&&m.enqueue(_.encode(`data: ${JSON.stringify({error:h.choices?.[0].error})}
|
|
235
235
|
|
|
236
236
|
`)),h.choices?.[0]?.delta?.content&&!p.hasTextContent()&&p.setHasTextContent(!0),h.choices?.[0]?.delta?.reasoning){p.appendReasoningContent(h.choices[0].delta.reasoning);let T={...h,choices:[{...h.choices?.[0],delta:{...h.choices[0].delta,thinking:{content:h.choices[0].delta.reasoning}}}]};T.choices?.[0]?.delta&&delete T.choices[0].delta.reasoning;let x=`data: ${JSON.stringify(T)}
|
|
237
237
|
|
|
238
|
-
`;
|
|
238
|
+
`;m.enqueue(_.encode(x));return}if(h.choices?.[0]?.delta?.content&&p.reasoningContent()&&!p.isReasoningComplete()){p.setReasoningComplete(!0);let x={...h,choices:[{...h.choices?.[0],delta:{...h.choices[0].delta,content:null,thinking:{content:p.reasoningContent(),signature:"ccr_think_signature"}}}]};x.choices?.[0]?.delta&&delete x.choices[0].delta.reasoning;let v=`data: ${JSON.stringify(x)}
|
|
239
239
|
|
|
240
|
-
`;
|
|
240
|
+
`;m.enqueue(_.encode(v))}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(T=>{T.id=`call_${Ac()}`}),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
|
-
`;
|
|
243
|
-
`))}}else
|
|
244
|
-
`))};try{for(;;){let{done:y,value:p}=await d.read();if(y){a.trim()&&g(a,u,o);break}if(!p||p.length===0)continue;let
|
|
245
|
-
`);a=k.pop()||"";for(let h of k)if(h.trim())try{
|
|
242
|
+
`;m.enqueue(_.encode(b))}catch{m.enqueue(_.encode(y+`
|
|
243
|
+
`))}}else m.enqueue(_.encode(y+`
|
|
244
|
+
`))};try{for(;;){let{done:y,value:p}=await d.read();if(y){a.trim()&&g(a,u,o);break}if(!p||p.length===0)continue;let m;try{m=t.decode(p,{stream:!0})}catch(k){console.warn("Failed to decode chunk",k);continue}if(m.length===0)continue;if(a+=m,a.length>1e6){console.warn("Buffer size exceeds limit, processing partial data");let k=a.split(`
|
|
245
|
+
`);a=k.pop()||"";for(let h of k)if(h.trim())try{f(h,{controller:u,encoder:o,hasTextContent:()=>r,setHasTextContent:b=>r=b,reasoningContent:()=>s,appendReasoningContent:b=>s+=b,isReasoningComplete:()=>i,setReasoningComplete:b=>i=b})}catch(b){console.error("Error processing line:",h,b),u.enqueue(o.encode(h+`
|
|
246
246
|
`))}continue}let _=a.split(`
|
|
247
|
-
`);a=_.pop()||"";for(let k of _)if(k.trim())try{
|
|
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(c,{status:e.status,statusText:e.statusText,headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}return e}}});var
|
|
247
|
+
`);a=_.pop()||"";for(let k of _)if(k.trim())try{f(k,{controller:u,encoder:o,hasTextContent:()=>r,setHasTextContent:h=>r=h,reasoningContent:()=>s,appendReasoningContent:h=>s+=h,isReasoningComplete:()=>i,setReasoningComplete:h=>i=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(c,{status:e.status,statusText:e.statusText,headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}return e}}});var uo,Ic,sn,Hs=w(()=>{"use strict";Q();uo=`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.`,Ic=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<Ic)&&(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:uo}):o.content=[{type:"text",text:uo},{type:"text",text:o.content||""}]),o.role==="tool"&&e.messages.push({role:"user",content:[{type:"text",text:uo}]}),e}async transformResponseOut(e){let t="<reasoning_content>",o="</reasoning_content>";if(e.headers.get("Content-Type")?.includes("application/json")){let r=await F(e);if(r.choices[0]?.message.content){let s=/<reasoning_content>(.*?)<\/reasoning_content>/s,i=r.choices[0]?.message.content.match(s);i&&i[1]&&(r.thinking={content:i[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,i=new TextEncoder,l=new ReadableStream({async start(a){let c=e.body.getReader(),u="",d="SEARCHING",g="",f="",y=(p,m)=>{if(typeof m!="string"){p.choices?.[0]?.delta&&Object.keys(p.choices[0].delta).length>0&&!p.choices[0].delta.content&&(p.choices[0].index=r,a.enqueue(i.encode(`data: ${JSON.stringify(p)}
|
|
256
256
|
|
|
257
|
-
`)));return}let _=g+
|
|
257
|
+
`)));return}let _=g+m;for(g="";_.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))){g=_.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 x={...p.choices[0].delta,thinking:{content:h}};delete x.content;let v={...p,choices:[{...p.choices[0],delta:x,index:r}]};a.enqueue(i.encode(`data: ${JSON.stringify(v)}
|
|
258
258
|
|
|
259
259
|
`))}let b={...p.choices[0].delta,thinking:{signature:"ccr_think_signature"}};delete b.content;let T={...p,choices:[{...p.choices[0],delta:b,index:r}]};a.enqueue(i.encode(`data: ${JSON.stringify(T)}
|
|
260
260
|
|
|
261
261
|
`)),r++,_=_.substring(k+o.length),d="FINAL"}else{let h=_;for(let b=o.length-1;b>0;b--)if(_.endsWith(o.substring(0,b))){g=_.substring(_.length-b),h=_.substring(0,_.length-b);break}if(h.length>0){let b={...p.choices[0].delta,thinking:{content:h}};delete b.content;let T={...p,choices:[{...p.choices[0],delta:b,index:r}]};a.enqueue(i.encode(`data: ${JSON.stringify(T)}
|
|
262
262
|
|
|
263
|
-
`))}_=""}}else if(d==="FINAL"){if(_.length>0)if(/^\s*$/.test(_))
|
|
263
|
+
`))}_=""}}else if(d==="FINAL"){if(_.length>0)if(/^\s*$/.test(_))f+=_;else{let h=f+_,b={...p.choices[0].delta,content:h};b.thinking&&delete b.thinking;let T={...p,choices:[{...p.choices[0],delta:b}]};a.enqueue(i.encode(`data: ${JSON.stringify(T)}
|
|
264
264
|
|
|
265
|
-
`)),
|
|
265
|
+
`)),f=""}r++,_=""}};try{for(;;){let{done:p,value:m}=await c.read();if(p)break;let _=s.decode(m,{stream:!0});u+=_;let k=u.split(`
|
|
266
266
|
`);u=k.pop()||"";for(let h of k)if(h.trim()){if(h.trim()==="data: [DONE]"){a.enqueue(i.encode(h+`
|
|
267
267
|
|
|
268
268
|
`));break}if(h.startsWith("data:"))try{let b=JSON.parse(h.slice(5));y(b,b.choices?.[0]?.delta?.content)}catch{a.enqueue(i.encode(h+`
|
|
269
269
|
`))}else a.enqueue(i.encode(h+`
|
|
270
|
-
`))}}}catch(p){console.error("Stream error:",p),a.error(p)}finally{try{c.releaseLock()}catch(p){console.error("Error releasing reader lock:",p)}if(d==="REASONING"){let
|
|
270
|
+
`))}}}catch(p){console.error("Stream error:",p),a.error(p)}finally{try{c.releaseLock()}catch(p){console.error("Error releasing reader lock:",p)}if(d==="REASONING"){let m={choices:[{delta:{thinking:{signature:"ccr_think_signature"}}}]};a.enqueue(i.encode(`data: ${JSON.stringify(m)}
|
|
271
271
|
|
|
272
|
-
`))}a.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
|
|
273
|
-
`));break}let g=o.decode(d,{stream:!0});i+=g;let
|
|
274
|
-
`);i=
|
|
272
|
+
`))}a.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,zs=w(()=>{"use strict";Q();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="",i="",l=new ReadableStream({async start(a){let c=e.body.getReader();try{for(;;){let{done:u,value:d}=await c.read();if(u){i.trim()&&a.enqueue(r.encode(i+`
|
|
273
|
+
`));break}let g=o.decode(d,{stream:!0});i+=g;let f=i.split(`
|
|
274
|
+
`);i=f.pop()||"";for(let y of f)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 m={...p,choices:[{...p.choices[0],delta:{thinking:{content:p.choices[0].delta.reasoning_content}}}]};delete m.choices[0].delta.reasoning_content,a.enqueue(r.encode(`data: ${JSON.stringify(m)}
|
|
275
275
|
|
|
276
|
-
`));continue}if(p.choices?.[0]?.delta?.content&&s&&!p.choices[0]?.delta?.reasoning_content){let
|
|
276
|
+
`));continue}if(p.choices?.[0]?.delta?.content&&s&&!p.choices[0]?.delta?.reasoning_content){let m=Date.now().toString(),_={...p,choices:[{...p.choices[0],delta:{content:null,thinking:{content:s,signature:m}}}]};a.enqueue(r.encode(`data: ${JSON.stringify(_)}
|
|
277
277
|
|
|
278
278
|
`)),s=""}p.choices?.[0]?.delta?.reasoning_content&&delete p.choices[0].delta.reasoning_content,p.choices?.[0]?.delta&&Object.keys(p.choices[0].delta).length>0&&a.enqueue(r.encode(`data: ${JSON.stringify(p)}
|
|
279
279
|
|
|
280
280
|
`))}catch{a.enqueue(r.encode(y+`
|
|
281
281
|
`))}else a.enqueue(r.encode(y+`
|
|
282
|
-
`))}}catch(u){a.error(u)}finally{try{c.releaseLock()}catch{}a.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
|
|
283
|
-
`);for(let k of _)k.trim()&&p.enqueue(
|
|
284
|
-
`))},
|
|
282
|
+
`))}}catch(u){a.error(u)}finally{try{c.releaseLock()}catch{}a.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 F(e);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 Mc}from"uuid";var cn,Js=w(()=>{"use strict";Q();cn=class{constructor(e){this.options=e}static TransformerName="opencode";endPoint="/v1/chat/completions";async transformRequestIn(e){let t=e.reasoning?.enabled||e.messages.some(o=>o.thinking?.content);return e.messages.forEach(o=>{if(Array.isArray(o.content)&&o.content.forEach(r=>{r.type==="image_url"&&(r.image_url.url.startsWith("http")||(r.image_url.url=`data:${r.media_type};base64,${r.image_url.url}`),delete r.media_type)}),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)):t&&o.tool_calls?.length&&!o.reasoning_content&&(o.reasoning_content=" "),o.thinking&&delete o.thinking}}),Object.assign(e,this.options||{}),e}async transformResponseOut(e){if(e.headers.get("Content-Type")?.includes("application/json")){let t=await F(e);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="",i=!1,l=!1,a="",c=new ReadableStream({async start(u){let d=e.body.getReader(),g=(y,p,m)=>{let _=y.split(`
|
|
283
|
+
`);for(let k of _)k.trim()&&p.enqueue(m.encode(k+`
|
|
284
|
+
`))},f=(y,p)=>{let{controller:m,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"){m.enqueue(_.encode(`data: ${JSON.stringify({error:k.choices?.[0]?.error})}
|
|
285
285
|
|
|
286
|
-
`));return}k.choices?.[0]?.delta?.content&&!p.hasTextContent()&&p.setHasTextContent(!0);let h=k.choices?.[0]?.delta?.reasoning||k.choices?.[0]?.delta?.reasoning_content;if(h){p.appendReasoningContent(h);let S={...k,choices:[{...k.choices?.[0],delta:{...k.choices[0].delta,thinking:{content:h}}}]};S.choices?.[0]?.delta&&(delete S.choices[0].delta.reasoning,delete S.choices[0].delta.reasoning_content),
|
|
286
|
+
`));return}k.choices?.[0]?.delta?.content&&!p.hasTextContent()&&p.setHasTextContent(!0);let h=k.choices?.[0]?.delta?.reasoning||k.choices?.[0]?.delta?.reasoning_content;if(h){p.appendReasoningContent(h);let S={...k,choices:[{...k.choices?.[0],delta:{...k.choices[0].delta,thinking:{content:h}}}]};S.choices?.[0]?.delta&&(delete S.choices[0].delta.reasoning,delete S.choices[0].delta.reasoning_content),m.enqueue(_.encode(`data: ${JSON.stringify(S)}
|
|
287
287
|
|
|
288
|
-
`));return}if(k.choices?.[0]?.delta?.content&&p.reasoningContent()&&!p.isReasoningComplete()){p.setReasoningComplete(!0);let S="ccr_think_signature",C=k.choices[0].delta.content,P={...k,choices:[{...k.choices?.[0],delta:{...k.choices[0].delta,content:null,thinking:{content:p.reasoningContent(),signature:S}}}]};P.choices?.[0]?.delta&&(delete P.choices[0].delta.reasoning,delete P.choices[0].delta.reasoning_content),
|
|
288
|
+
`));return}if(k.choices?.[0]?.delta?.content&&p.reasoningContent()&&!p.isReasoningComplete()){p.setReasoningComplete(!0);let S="ccr_think_signature",C=k.choices[0].delta.content,P={...k,choices:[{...k.choices?.[0],delta:{...k.choices[0].delta,content:null,thinking:{content:p.reasoningContent(),signature:S}}}]};P.choices?.[0]?.delta&&(delete P.choices[0].delta.reasoning,delete P.choices[0].delta.reasoning_content),m.enqueue(_.encode(`data: ${JSON.stringify(P)}
|
|
289
289
|
|
|
290
|
-
`));let R={...k,choices:[{...k.choices?.[0],delta:{...k.choices[0].delta,content:C}}]};R.choices?.[0]?.delta&&(delete R.choices[0].delta.reasoning,delete R.choices[0].delta.reasoning_content),
|
|
290
|
+
`));let R={...k,choices:[{...k.choices?.[0],delta:{...k.choices[0].delta,content:C}}]};R.choices?.[0]?.delta&&(delete R.choices[0].delta.reasoning,delete R.choices[0].delta.reasoning_content),m.enqueue(_.encode(`data: ${JSON.stringify(R)}
|
|
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(S=>{S.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(S=>{S.id=`call_${Mc()}`}),k.choices?.[0]?.delta?.tool_calls?.length&&!l&&(l=!0);let b=k.choices?.[0]?.delta,T=b&&Object.keys(b).length>0,x=k.choices?.[0]?.finish_reason,v=k.usage;(T||x||v)&&m.enqueue(_.encode(`data: ${JSON.stringify(k)}
|
|
293
293
|
|
|
294
|
-
`))}catch{
|
|
295
|
-
`))}else
|
|
296
|
-
`))};try{for(;;){let{done:y,value:p}=await d.read();if(y){a.trim()&&g(a,u,o);break}if(!p||p.length===0)continue;let
|
|
297
|
-
`);a=k.pop()||"";for(let h of k)if(h.trim())try{
|
|
294
|
+
`))}catch{m.enqueue(_.encode(y+`
|
|
295
|
+
`))}else m.enqueue(_.encode(y+`
|
|
296
|
+
`))};try{for(;;){let{done:y,value:p}=await d.read();if(y){a.trim()&&g(a,u,o);break}if(!p||p.length===0)continue;let m;try{m=t.decode(p,{stream:!0})}catch(k){console.warn("Failed to decode chunk",k);continue}if(m.length===0)continue;if(a+=m,a.length>1e6){console.warn("Buffer size exceeds limit, processing partial data");let k=a.split(`
|
|
297
|
+
`);a=k.pop()||"";for(let h of k)if(h.trim())try{f(h,{controller:u,encoder:o,hasTextContent:()=>r,setHasTextContent:b=>r=b,reasoningContent:()=>s,appendReasoningContent:b=>s+=b,isReasoningComplete:()=>i,setReasoningComplete:b=>i=b})}catch(b){console.error("Error processing line:",h,b),u.enqueue(o.encode(h+`
|
|
298
298
|
`))}continue}let _=a.split(`
|
|
299
|
-
`);a=_.pop()||"";for(let k of _)if(k.trim())try{
|
|
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(c,{status:e.status,statusText:e.statusText,headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}return e}}});var
|
|
299
|
+
`);a=_.pop()||"";for(let k of _)if(k.trim())try{f(k,{controller:u,encoder:o,hasTextContent:()=>r,setHasTextContent:h=>r=h,reasoningContent:()=>s,appendReasoningContent:h=>s+=h,isReasoningComplete:()=>i,setReasoningComplete:h=>i=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(c,{status:e.status,statusText:e.statusText,headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}return e}}});var Bs,Ws=w(()=>{ys();_s();ks();bs();Ts();Cs();vs();xs();Ss();ws();Ps();Es();Os();Ns();Ls();Ds();Fs();Us();js();qn();Hs();zs();Js();Bs={AnthropicTransformer:Dt,GeminiTransformer:Ht,VertexGeminiTransformer:zt,VertexClaudeTransformer:Zt,DeepseekTransformer:Jt,TooluseTransformer:Bt,OpenrouterTransformer:Wt,OpenAITransformer:nn,MaxTokenTransformer:Gt,GroqTransformer:Kt,CleancacheTransformer:Qt,EnhanceToolTransformer:Vt,ReasoningTransformer:Yt,SamplingTransformer:Xt,MaxCompletionTokens:qt,CerebrasTransformer:en,StreamOptionsTransformer:tn,CustomParamsTransformer:on,VercelTransformer:rn,OpenAIResponsesTransformer:Re,ForceReasoningTransformer:sn,KimiTransformer:an,OpenCodeTransformer:cn}});var Ne,po=w(()=>{"use strict";Ws();Ne=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=We(We.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(Hs).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 Oc}from"tiktoken";var tt,Bs=w(()=>{"use strict";tt=class{type="tiktoken";name;encoding;constructor(e="cl100k_base"){this.name=`tiktoken-${e}`;try{this.encoding=Oc(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:i}=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(a=>{if(a.type==="text")o+=t.encode(a.text).length;else if(a.type==="tool_use")o+=t.encode(JSON.stringify(a.input)).length;else if(a.type==="tool_result"){let c=typeof a.content=="string"?a.content:JSON.stringify(a.content);o+=t.encode(c).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(a=>{o+=t.encode(a||"").length}))}),i&&i.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 an}from"path";import{homedir as Ac}from"os";import{existsSync as uo,mkdirSync as Ic}from"fs";import{promises as cn}from"fs";import{Tokenizer as Mc}from"@huggingface/tokenizers";var ln,Js=w(()=>{"use strict";ln=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||an(Ac(),".claude-code-router",".huggingface"),this.safeModelName=e.replace(/\//g,"_").replace(/[^a-zA-Z0-9_-]/g,"_"),this.name=`huggingface-${e.split("/").pop()}`}getCachePaths(){let e=an(this.cacheDir,this.safeModelName);return{modelDir:e,tokenizerJson:an(e,"tokenizer.json"),tokenizerConfig:an(e,"tokenizer_config.json")}}ensureDir(e){uo(e)||Ic(e,{recursive:!0})}async loadFromCache(){try{let e=this.getCachePaths();if(!uo(e.tokenizerJson)||!uo(e.tokenizerConfig))return null;let[t,o]=await Promise.all([cn.readFile(e.tokenizerJson,"utf-8"),cn.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,i]=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,a]=await Promise.all([s.json(),i.ok?i.json():Promise.resolve({})]);return this.ensureDir(e.modelDir),await Promise.all([cn.writeFile(e.tokenizerJson,JSON.stringify(l,null,2)),cn.writeFile(e.tokenizerConfig,JSON.stringify(a,null,2))]),{tokenizerJson:l,tokenizerConfig:a}}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 Mc(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 i of o)if(typeof i.content=="string")t.push(i.content);else if(Array.isArray(i.content))for(let l of i.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 i of r)if(i.type==="text"){if(typeof i.text=="string")t.push(i.text);else if(Array.isArray(i.text))for(let l of i.text)l&&t.push(l)}}if(s)for(let i of s)i.name&&t.push(i.name),i.description&&t.push(i.description),i.input_schema&&t.push(JSON.stringify(i.input_schema));return t.join(" ")}}});var un,Ws=w(()=>{"use strict";Z();un=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),i={method:"POST",headers:o,body:JSON.stringify(t),signal:r.signal},l=this.options.resolveProxyUrl?.();l&&(i.dispatcher=W(l));let a=await fetch(this.config.url,i);if(clearTimeout(s),!a.ok)throw new Error(`API tokenizer request failed: ${a.status} ${a.statusText}`);let c=await a.json();return this.extractTokenCount(c)}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,po=w(()=>{"use strict";Bs();Js();Ws();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 tt("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 tt(e.encoding||"cl100k_base");break;case"huggingface":this.logger?.info(`Initializing HuggingFace tokenizer for model: ${e.model}`),r=new ln(e.model,this.logger,{timeout:this.options.timeout});break;case"api":r=new un(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 Gs(n){if(!n||typeof n!="object"||jc(n))return null;for(let t of Uc(n)){let o=Fc(t);if(o)return o}return null}function Fc(n){if(!n||typeof n!="object")return null;let e={},t=dn(n,$c);if(t!==void 0){let i=Ks(t);e.usedDailyBalance=i,e.limitDaily=100}let o=dn(n,Nc);if(o!==void 0){let i=Ks(o);e.usedBalance=i,e.totalBalance=100}let r=dn(n,Lc);if(r!==void 0){let i=Qs(r);i&&(e.resetTime=i)}let s=dn(n,Dc);if(s!==void 0){let i=Qs(s);i&&(e.resetTime7d=i,e.resetTime||(e.resetTime=i))}return e.usedDailyBalance===void 0&&e.limitDaily===void 0&&e.usedBalance===void 0&&e.totalBalance===void 0&&e.resetTime===void 0?null:e}function Ks(n){return!Number.isFinite(n)||n<=0?0:Math.round(n*1e4)/100}function dn(n,e){for(let t of e){let o=M(n?.[t]);if(o!==void 0)return o}}function Uc(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 i of o)s[i]&&typeof s[i]=="object"&&r(s[i])}};return r(n),e}function jc(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 Qs(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 xo(n){let e=So(n);return e?e==="kimi.com"||e.endsWith(".kimi.com")||e==="moonshot.cn"||e.endsWith(".moonshot.cn")?Qc:e==="minimaxi.com"||e.endsWith(".minimaxi.com")||e==="minimax.io"||e.endsWith(".minimax.io")?Vc:e==="deepseek.com"||e.endsWith(".deepseek.com")?Hc:e==="openrouter.ai"||e.endsWith(".openrouter.ai")?zc:e==="siliconflow.com"||e.endsWith(".siliconflow.com")||e==="siliconflow.cn"||e.endsWith(".siliconflow.cn")?Bc:e==="bigmodel.cn"||e.endsWith(".bigmodel.cn")?Jc:e==="dashscope.aliyuncs.com"||e.endsWith(".dashscope.aliyuncs.com")?Wc:e==="maas.aliyuncs.com"||e.endsWith(".maas.aliyuncs.com")?Gc:e==="xf-yun.com"||e.endsWith(".xf-yun.com")||e==="xfyun.cn"||e.endsWith(".xfyun.cn")||e==="xfyun.com"||e.endsWith(".xfyun.com")?Kc:null:null}function Yc(n){let e=So(n);return e?.endsWith(".siliconflow.cn")||e==="siliconflow.cn"?"https://api.siliconflow.cn/v1/user/info":"https://api.siliconflow.com/v1/user/info"}function Xc(n,e){let t=Co(n);if(t.length===0)return null;let o=String(e||"").split(":").map(s=>s.trim()).filter(Boolean);return t.find(s=>{let i=s?.codingPlanAppCredentialDTO||s?.appCredential||s,l=String(i?.apiKey||i?.api_key||"").trim();return l&&o.some(a=>a.includes(l)||l.includes(a))})||t[0]}function Co(n){return!n||typeof n!="object"?[]:!Array.isArray(n)&&n.codingPlanUsageDTO?[n]:Array.isArray(n)?n.flatMap(e=>Co(e)):Object.values(n).flatMap(e=>Co(e))}function vo(n,e){let t=n.match(new RegExp(`(?:^|;\\s*)${e}=([^;]+)`));return t?decodeURIComponent(t[1]):void 0}function So(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 te,fo,mo,go,ho,yo,$c,Nc,Lc,Dc,_o,ko,bo,To,Hc,zc,Bc,Jc,Wc,Gc,Kc,Qc,Vc,Ro=w(()=>{"use strict";Z();te=class{async fetchJson(e,t,o,r,s){let i=s||t.apiKey;if(!i)return null;let l={method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${i}`},signal:AbortSignal.timeout(o)};try{r&&(l.dispatcher=W(r));let a=await fetch(e,l);return a.ok?await a.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}},fo=class extends te{async queryQuota(e,t,o){let r=await this.fetchJson("https://api.deepseek.com/user/balance",e,t,o),i=(Array.isArray(r?.balance_infos)?r.balance_infos:[]).find(a=>M(a?.total_balance)!==void 0);if(!i)return null;let l=M(i.total_balance);return l===void 0?null:{totalBalance:l,currency:typeof i.currency=="string"?i.currency:void 0}}},mo=class extends te{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 i={},l=M(s.limit),a=M(s.limit_remaining),c=M(s.usage),u=M(s.usage_daily);return l!==void 0&&(i.totalBalance=l),a!==void 0&&(i.remainingBalance=a),c!==void 0&&(i.usedBalance=c),u!==void 0&&(i.usedDailyBalance=u),this.hasQuotaData(i)?i:null}},go=class extends te{async queryQuota(e,t,o){let r=Yc(e.baseUrl),i=(await this.fetchJson(r,e,t,o))?.data;if(!i||typeof i!="object")return null;let l={},a=M(i.totalBalance),c=M(i.balance);return a!==void 0&&(l.totalBalance=a),c!==void 0&&(l.remainingBalance=c),a!==void 0&&c!==void 0&&(l.usedBalance=Math.max(0,a-c)),this.hasQuotaData(l)?l:null}},ho=class extends te{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=W(o));let i=await fetch("https://api.z.ai/api/monitor/usage/quota/limit",s);if(!i.ok)return null;let l=await i.json(),a=Array.isArray(l?.data?.limits)?l.data.limits:[],c=null,u=null,d=null;for(let m of a)m.type==="TOKENS_LIMIT"?m.unit===3?c=m:m.unit===6?u=m:c||(c=m):m.type==="TIME_LIMIT"&&(d=m);let g={};if(c){let m=M(c.currentValue),y=M(c.usage),p=M(c.remaining),f=M(c.percentage);m!==void 0?g.usedDailyBalance=m:f!==void 0&&(g.usedDailyBalance=f,g.limitDaily=100),y!==void 0?g.limitDaily=y:m!==void 0&&p!==void 0&&(g.limitDaily=m+p),c.nextResetTime&&(g.resetTime=new Date(c.nextResetTime).toISOString())}if(u){let m=M(u.currentValue),y=M(u.usage),p=M(u.remaining),f=M(u.percentage);m!==void 0?g.usedBalance=m:f!==void 0&&(g.usedBalance=f,g.totalBalance=100),y!==void 0?g.totalBalance=y:m!==void 0&&p!==void 0&&(g.totalBalance=m+p),u.nextResetTime&&!g.resetTime&&(g.resetTime=new Date(u.nextResetTime).toISOString())}if(d){if(g.usedDailyBalance===void 0){let m=M(d.currentValue);m!==void 0&&(g.usedDailyBalance=m)}if(g.limitDaily===void 0){let m=M(d.usage),y=M(d.currentValue),p=M(d.remaining);m!==void 0?g.limitDaily=m:y!==void 0&&p!==void 0&&(g.limitDaily=y+p)}d.nextResetTime&&!g.resetTime&&(g.resetTime=new Date(d.nextResetTime).toISOString())}return this.hasQuotaData(g)?g:null}catch{return null}}},yo=class extends te{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"}}}),i=new URLSearchParams({params:s,region:"cn-beijing"}).toString();try{o&&(r.dispatcher=W(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:i});if(!l.ok)return null;let c=(await l.json())?.data?.DataV2?.data?.data?.codingPlanInstanceInfos;if(!Array.isArray(c)||c.length===0)return null;let u=c[0]?.codingPlanQuotaInfo;if(!u)return null;let d={},g=M(u.per5HourUsedQuota),m=M(u.per5HourTotalQuota);g!==void 0&&(d.usedDailyBalance=g),m!==void 0&&(d.limitDaily=m);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}}};$c=["per5HourPercentage","per5HourUsedPercentage","fiveHourPercentage"],Nc=["per1WeekPercentage","perWeekPercentage","per1WeekUsedPercentage"],Lc=["per5HourResetTime","per5HourNextResetTime","fiveHourResetTime"],Dc=["per1WeekResetTime","per1WeekNextResetTime","perWeekResetTime"];_o=class extends te{async queryQuota(e,t,o){let r=e.quotaToken?.trim();if(!r)return null;let s=e.quotaSecToken?.trim();if(s){try{let i=await this.queryOfficialEndpoint(r,s,t,o);if(i)return i}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",i=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":i}}}),a=new URLSearchParams({params:l,region:"cn-beijing",sec_token:t}).toString(),c={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:a,signal:AbortSignal.timeout(o)};try{r&&(c.dispatcher=W(r));let u=await fetch(`https://bailian-cs.console.aliyun.com/data/api.json?action=BroadScopeAspnGateway&product=sfm_bailian&api=${encodeURIComponent(s)}&_v=undefined`,c);if(!u.ok)return null;let d=await u.json();return Gs(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"}}}),i=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:i,signal:AbortSignal.timeout(t)};try{o&&(l.dispatcher=W(o));let a=await fetch(`https://cs-data.qianwenai.com/data/api.json?product=sfm_bailian&action=BroadScopeAspnGateway&api=${encodeURIComponent(r)}`,l);if(!a.ok)return null;let c=await a.json();return Gs(c)}catch{return null}}},ko=class extends te{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=W(o));let i=await fetch("https://maas.xfyun.cn/api/v1/gpt-finetune/coding-plan/list?page=1&size=10",s);if(!i.ok)return null;let l=await i.json();if(l?.succeed===!1||l?.failed===!0)return null;let a=Xc(l,e.apiKey),c=a?.codingPlanUsageDTO||a?.usage||a;if(!c||typeof c!="object")return null;let u={},d=M(c.rp5hUsage),g=M(c.rp5hLimit);d!==void 0&&(u.usedDailyBalance=d),g!==void 0&&(u.limitDaily=g);let m=M(c.rpwUsage),y=M(c.rpwLimit);return m!==void 0&&(u.usedBalance=m),y!==void 0&&(u.totalBalance=y),u.remainingBalance===void 0&&y!==void 0&&m!==void 0&&(u.remainingBalance=Math.max(0,y-m)),this.hasQuotaData(u)?u:null}catch{return null}}},bo=class extends te{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=W(o));let i=await fetch("https://api.kimi.com/coding/v1/usages",s);if(!i.ok)return null;let l=await i.json(),a={},c=Array.isArray(l?.limits)?l.limits:[];if(c.length>0&&c[0]?.detail){let d=c[0].detail,g=M(d.limit),m=M(d.remaining),y=d.resetTime;g!==void 0&&m!==void 0&&(a.usedDailyBalance=Math.max(0,g-m),a.limitDaily=g),y&&(a.resetTime=new Date(y).toISOString())}let u=l?.usage;if(u){let d=M(u.limit),g=M(u.remaining),m=M(u.used),y=u.resetTime;d!==void 0&&(a.totalBalance=d,m!==void 0?a.usedBalance=m:g!==void 0&&(a.usedBalance=Math.max(0,d-g),a.remainingBalance=g)),y&&(a.resetTime7d=new Date(y).toISOString(),a.resetTime||(a.resetTime=a.resetTime7d))}return this.hasQuotaData(a)?a:null}catch{return null}}},To=class extends te{async queryQuota(e,t,o){let r=e.quotaToken||e.apiKey;if(!r)return null;let s=So(e.baseUrl)||"api.minimaxi.com",i=s.endsWith(".minimax.io")||s==="minimax.io"?"api.minimax.io":"api.minimaxi.com";try{let l=[`https://${i}/v1/token_plan/remains`,`https://${i}/v1/api/openplatform/coding_plan/remains`],a=null;for(let b of l)if(a=await this.fetchJson(b,e,t,o,r.trim()),a)break;if(!a)return null;if(a?.base_resp){let b=a.base_resp.status_code;if(b!==void 0&&b!==0)return null}let c=Array.isArray(a?.model_remains)?a.model_remains:[];if(c.length===0)return null;let u=c[0],d={},g=M(u.current_interval_total_count),m=M(u.current_interval_usage_count),y=M(u.current_interval_remaining_percent),p=M(u.end_time);g!==void 0&&m!==void 0&&g>0?(d.usedDailyBalance=Math.max(0,g-m),d.limitDaily=g):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}}},Hc=new fo,zc=new mo,Bc=new go,Jc=new ho,Wc=new yo,Gc=new _o,Kc=new ko,Qc=new bo,Vc=new To});function Vs(n){return{[qc]:n,[Zc]:vt}}function tl(n){return n===!0||n==="true"||n===1||n==="1"}function nl(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 ol(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 rl(n){try{let e=new URL(n).hostname.toLowerCase();return e.includes("moonshot")||e.includes("kimi")}catch{return!1}}async function wo(n,e,t){let o=performance.now(),r=()=>Math.max(0,Math.round(performance.now()-o)),s=ol(n.baseUrl);if(!s)return{success:!1,error:"Cannot derive models endpoint from baseUrl",errorKind:"network",latencyMs:r()};try{let i={method:"GET",headers:{Authorization:`Bearer ${n.apiKey}`},signal:AbortSignal.timeout(e)};t&&(i.dispatcher=W(t));let l=await fetch(s,i);if(l.headers&&We(n.name,n.baseUrl,l.headers),l.ok)return{success:!0,headers:l.headers,latencyMs:r()};if(l.status===429)return{success:!1,error:`HTTP 429: ${(await l.text().catch(()=>"")).slice(0,100)||"Rate limited"}`,headers:l.headers,latencyMs:r(),errorKind:"http"};if(l.status>=400&&l.status<500)return{success:!0,headers:l.headers,latencyMs:r()};let a=await l.text().catch(()=>"");return{success:!1,error:`HTTP ${l.status}: ${a.slice(0,100)}`,headers:l.headers,latencyMs:r(),errorKind:"http"}}catch(i){let l=i?.message||i?.toString()||"Unknown probe error",a=i?.name==="TimeoutError"||i?.name==="AbortError"||i?.code===20||i?.code==="ABORT_ERR";return{success:!1,error:l,latencyMs:r(),errorKind:a?"timeout":"network"}}}async function sl(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,i=n.baseUrl.includes("/messages")||r.includes("claude");try{let l={"Content-Type":"application/json",...Vs("scheduled-wakeup")};i?(l["x-api-key"]=n.apiKey,l["anthropic-version"]="2023-06-01"):l.Authorization=`Bearer ${n.apiKey}`;let a={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&&(a.dispatcher=W(t)),o?.info(`Sending scheduled wake-up call to provider ${n.name} using model ${r}...`);let c=await fetch(s,a);if(c.ok)return{success:!0};let u=await c.text().catch(()=>"");return{success:!1,error:`HTTP ${c.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,i=n.baseUrl.includes("/messages")||e.includes("claude");try{let l={"Content-Type":"application/json",...Vs("rate-limit-probe")};i?(l["x-api-key"]=n.apiKey,l["anthropic-version"]="2023-06-01"):l.Authorization=`Bearer ${n.apiKey}`;let a={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&&(a.dispatcher=W(o)),r?.debug?.(`Sending independent ping to rate-limited model ${n.name} (${e})...`);let c=await fetch(s,a);if(c.ok)return{success:!0};let u=await c.text().catch(()=>"");return{success:!1,error:`HTTP ${c.status}: ${u.slice(0,200)||"Unknown error"}`}}catch(l){return{success:!1,error:l?.message||l?.toString()||"Unknown ping error"}}}function Ys(n,e,t,o,r){return ue||(ue=new pn(n,e,t,o,r)),ue}function Ne(n,e,t,o,r){let s=Ys(n,e,t,o,r);return s.start(),s}function Po(){ue&&ue.stop()}function fn(){ue&&(ue.stop(),ue=null)}var qc,Zc,el,pn,ue,mn=w(()=>{"use strict";ee();ve();Ro();Re();jn();Z();qc="x-claude-code-router-source",Zc="x-claude-code-router-version";el={enabled:!0,quotaProbeIntervalMinutes:10,probeTimeoutMs:15e3,slowThresholdMs:3e3,initialDelayMs:5e3,excludeProviders:[]};pn=class{config;quotaProbeTimer;healthProbeTimer;wakeupTimer;rateLimitProbeTimer;lastWakeupDate=new Map;getProviders;resolveProxyUrl;logger;getConfig;running=!1;probeTelemetry=new Map;constructor(e,t,o,r,s){this.config={...el,...t},this.getProviders=e,this.resolveProxyUrl=o,this.logger=r,this.getConfig=s}recordProbe(e,t,o){let r=Date.now(),s=t.success&&t.latencyMs>this.config.slowThresholdMs,i;t.success?i=s?"slow":"healthy":i=t.errorKind==="timeout"?"timeout":"error";let l=this.probeTelemetry.get(e),a={provider:e,latencyMs:t.latencyMs,status:i,isSlow:s,errorKind:t.errorKind,errorMessage:t.error,lastProbeAt:r,lastSuccessAt:t.success?r:l?.lastSuccessAt,source:o};return this.probeTelemetry.set(e,a),s&&this.logger?.warn?.(`Slow network detected for provider ${e}: probe took ${t.latencyMs} ms (threshold ${this.config.slowThresholdMs} ms)`),a}getProbeTelemetry(){return Array.from(this.probeTelemetry.values()).map(e=>({...e}))}getProviderProbeTelemetry(e){let t=this.probeTelemetry.get(e);return t?{...t}:void 0}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=F();if(e.length===0)return;let o=[];for(let s of e){let i=xo(s.baseUrl),l=Array.isArray(s.models)?s.models:[],a=this.resolveProxyUrl?.(s);if(!i){let c;try{c=new URL(s.baseUrl).hostname}catch{c=void 0}this.logger?.debug?.(`No quota adapter for provider ${s.name}`+(c?` (host: ${c})`:"")+" \u2014 skipping quota probe")}i&&o.push({provider:s.name,models:l,type:"quota-adapter",promise:i.queryQuota(s,this.config.probeTimeoutMs,a).then(c=>{if(c){eo(s.name,c),this.logger?.debug?.(`Stored quota probe result for ${s.name}`);let u=c.limitDaily!==void 0&&c.usedDailyBalance!==void 0&&c.usedDailyBalance>=c.limitDaily,d=c.totalBalance!==void 0&&c.usedBalance!==void 0&&c.usedBalance>=c.totalBalance;if(u||d){let g=u?`Quota exhausted: 5h limit reached (${c.usedDailyBalance}/${c.limitDaily})`:`Quota exhausted: 7d balance depleted (${c.usedBalance}/${c.totalBalance})`;for(let m of l){if(t.getState(s.name,m)?.rateLimitUntil){this.logger?.debug?.(`Skip forceOpen for ${s.name} (${m}): already rate-limited with active cooldown`);continue}t.forceOpen(s.name,m,g)}this.logger?.warn?.(`${g} for ${s.name}, marked as unhealthy`)}else for(let g of l){let m=t.getState(s.name,g);m&&m.status==="open"&&m.lastError?.includes("Quota exhausted")&&(t.recover(s.name,g),this.logger?.info?.(`Quota recovered for ${s.name} (${g}), marked as healthy`))}}})}),rl(s.baseUrl)&&o.push({provider:s.name,models:l,type:"rate-limit-headers",promise:wo(s,this.config.probeTimeoutMs,a).then(c=>{this.recordProbe(s.name,c,"rate-limit-headers")})})}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 i=r[s];if(i.status==="rejected"){let l=o[s];this.logger?.warn?.(`Quota probe failed for ${l.provider} (${l.type}): ${i.reason}`)}}}async runHealthProbe(){let e=F(),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=>wo(r,this.config.probeTimeoutMs,this.resolveProxyUrl?.(r))));for(let r=0;r<t.length;r++){let s=t[r],i=o[r],l=Array.isArray(s.models)?s.models:[];if(i.status==="fulfilled"){let a=i.value;if(this.recordProbe(s.name,a,"health"),a.success){let c=0;for(let u of l){let d=e.getState(s.name,u);if(d&&d.status==="open"){let g=d.lastError?.includes("Quota exhausted"),m=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(g){this.logger?.debug?.(`Skipping health probe recovery for ${s.name} (${u}) because quota is exhausted`);continue}if(m||d.rateLimitUntil){this.logger?.debug?.(`Skipping health probe recovery for rate-limited ${s.name} (${u})`);continue}}e.recordSuccess(s.name,u),c++}c>0&&this.logger?.info?.(`Health probe succeeded for ${s.name}`)}else{for(let c of l)e.recordFailure(s.name,c,a.error);this.logger?.warn?.(`Health probe failed for ${s.name}: ${a.error}`)}}else{this.recordProbe(s.name,{success:!1,error:i.reason?.message||String(i.reason||"Probe error"),latencyMs:0,errorKind:"network"},"health");for(let a of l)e.recordFailure(s.name,a,i.reason?.message||"Probe error");this.logger?.warn?.(`Health probe error for ${s.name}: ${i.reason}`)}}}async runRateLimitProbe(){let e=F(),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[i,...l]=s.split(","),a=l.join(",");if(!i||!a)continue;let c=e.getState(i,a);if(!c||!c.rateLimitUntil)continue;if(Date.now()>=c.rateLimitUntil){e.recover(i,a),this.logger?.info?.(`Rate-limit cooldown expired, auto-recovered ${s}`);continue}let u=o.find(d=>d?.name===i&&d.enabled!==!1);if(!u){this.logger?.warn?.(`Provider ${i} not found or disabled for rate-limit probe`);continue}try{let d=await il(u,a,r,this.resolveProxyUrl?.(u),this.logger);if(d.success)this.logger?.info?.(`Rate-limit probe succeeded for ${s}, recovering model`),e.recover(i,a);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 g=Date.now();c.rateLimitUntil&&c.rateLimitUntil>g?c.rateLimitUntil+=120*1e3:c.rateLimitUntil=g+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=nl(t),i=this.getConfig&&this.getConfig("WAKEUP_TIME")||"06:00";for(let l of e){let a=l.wakeupTime||i,[c,u]=a.split(":"),d=parseInt(c,10),g=parseInt(u,10);if(isNaN(d)||isNaN(g))continue;let m=o>d||o===d&&r>=g,y=(d*60+g)*6e4-(o*60+r)*6e4,p=y>0&&y<=300*1e3;(m||p)&&!this.hasWakeupFiredToday(l.name,s)&&(this.logger?.info?.(`Scheduled wake-up triggered for provider ${l.name} at ${a}`),sl(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?tl(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(l=>l.name===e);if(!o)return this.logger?.warn?.(`Provider ${e} not found for manual probe`),{success:!1,latencyMs:0,status:"error",isSlow:!1,error:`Provider ${e} not found`};if(o.enabled===!1)return this.logger?.warn?.(`Provider ${e} is disabled, skipping manual probe`),{success:!1,latencyMs:0,status:"error",isSlow:!1,error:`Provider ${e} is disabled`};let r=await wo(o,this.config.probeTimeoutMs,this.resolveProxyUrl?.(o)),s=this.recordProbe(o.name,r,"manual"),i=Array.isArray(o.models)?o.models:[];if(r.success)for(let l of i)F().recordSuccess(o.name,l);else for(let l of i)F().recordFailure(o.name,l,r.error);return{success:r.success,latencyMs:r.latencyMs,status:s.status,isSlow:s.isSlow,errorKind:r.errorKind,error:r.error}}},ue=null});var Xs=w(()=>{"use strict"});var Eo,nt,qs=w(()=>{"use strict";Eo=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()}},nt=new Eo});var re,Oo=w(()=>{"use strict";re=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
|
|
303
|
+
Stack: ${e.stack}`)}}async registerDefaultTransformersInternal(){try{Object.values(Bs).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 $c}from"tiktoken";var ot,Gs=w(()=>{"use strict";ot=class{type="tiktoken";name;encoding;constructor(e="cl100k_base"){this.name=`tiktoken-${e}`;try{this.encoding=$c(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:i}=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(a=>{if(a.type==="text")o+=t.encode(a.text).length;else if(a.type==="tool_use")o+=t.encode(JSON.stringify(a.input)).length;else if(a.type==="tool_result"){let c=typeof a.content=="string"?a.content:JSON.stringify(a.content);o+=t.encode(c).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(a=>{o+=t.encode(a||"").length}))}),i&&i.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 Nc}from"os";import{existsSync as fo,mkdirSync as Lc}from"fs";import{promises as un}from"fs";import{Tokenizer as Dc}from"@huggingface/tokenizers";var dn,Ks=w(()=>{"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(Nc(),".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)||Lc(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,i]=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,a]=await Promise.all([s.json(),i.ok?i.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(a,null,2))]),{tokenizerJson:l,tokenizerConfig:a}}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 Dc(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 i of o)if(typeof i.content=="string")t.push(i.content);else if(Array.isArray(i.content))for(let l of i.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 i of r)if(i.type==="text"){if(typeof i.text=="string")t.push(i.text);else if(Array.isArray(i.text))for(let l of i.text)l&&t.push(l)}}if(s)for(let i of s)i.name&&t.push(i.name),i.description&&t.push(i.description),i.input_schema&&t.push(JSON.stringify(i.input_schema));return t.join(" ")}}});var pn,Qs=w(()=>{"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),i={method:"POST",headers:o,body:JSON.stringify(t),signal:r.signal},l=this.options.resolveProxyUrl?.();l&&(i.dispatcher=G(l));let a=await fetch(this.config.url,i);if(clearTimeout(s),!a.ok)throw new Error(`API tokenizer request failed: ${a.status} ${a.statusText}`);let c=await a.json();return this.extractTokenCount(c)}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 Le,mo=w(()=>{"use strict";Gs();Ks();Qs();te();Le=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 ae(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 Vs(n){if(!n||typeof n!="object"||Bc(n))return null;for(let t of Jc(n)){let o=zc(t);if(o)return o}return null}function zc(n){if(!n||typeof n!="object")return null;let e={},t=fn(n,Fc);if(t!==void 0){let i=Ys(t);e.usedDailyBalance=i,e.limitDaily=100}let o=fn(n,Uc);if(o!==void 0){let i=Ys(o);e.usedBalance=i,e.totalBalance=100}let r=fn(n,jc);if(r!==void 0){let i=Xs(r);i&&(e.resetTime=i)}let s=fn(n,Hc);if(s!==void 0){let i=Xs(s);i&&(e.resetTime7d=i,e.resetTime||(e.resetTime=i))}return e.usedDailyBalance===void 0&&e.limitDaily===void 0&&e.usedBalance===void 0&&e.totalBalance===void 0&&e.resetTime===void 0?null:e}function Ys(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 Jc(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 i of o)s[i]&&typeof s[i]=="object"&&r(s[i])}};return r(n),e}function Bc(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 Xs(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")?qc:e==="minimaxi.com"||e.endsWith(".minimaxi.com")||e==="minimax.io"||e.endsWith(".minimax.io")?Zc:e==="deepseek.com"||e.endsWith(".deepseek.com")?Wc:e==="openrouter.ai"||e.endsWith(".openrouter.ai")?Gc:e==="siliconflow.com"||e.endsWith(".siliconflow.com")||e==="siliconflow.cn"||e.endsWith(".siliconflow.cn")?Kc:e==="bigmodel.cn"||e.endsWith(".bigmodel.cn")?Qc:e==="dashscope.aliyuncs.com"||e.endsWith(".dashscope.aliyuncs.com")?Vc:e==="maas.aliyuncs.com"||e.endsWith(".maas.aliyuncs.com")?Yc:e==="xf-yun.com"||e.endsWith(".xf-yun.com")||e==="xfyun.cn"||e.endsWith(".xfyun.cn")||e==="xfyun.com"||e.endsWith(".xfyun.com")?Xc:null:null}function el(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 tl(n,e){let t=xo(n);if(t.length===0)return null;let o=String(e||"").split(":").map(s=>s.trim()).filter(Boolean);return t.find(s=>{let i=s?.codingPlanAppCredentialDTO||s?.appCredential||s,l=String(i?.apiKey||i?.api_key||"").trim();return l&&o.some(a=>a.includes(l)||l.includes(a))})||t[0]}function xo(n){return!n||typeof n!="object"?[]:!Array.isArray(n)&&n.codingPlanUsageDTO?[n]:Array.isArray(n)?n.flatMap(e=>xo(e)):Object.values(n).flatMap(e=>xo(e))}function So(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,go,ho,yo,_o,ko,Fc,Uc,jc,Hc,bo,To,Co,vo,Wc,Gc,Kc,Qc,Vc,Yc,Xc,qc,Zc,Po=w(()=>{"use strict";te();oe=class{async fetchJson(e,t,o,r,s){let i=s||t.apiKey;if(!i)return null;let l={method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${i}`},signal:AbortSignal.timeout(o)};try{r&&(l.dispatcher=G(r));let a=await fetch(e,l);return a.ok?await a.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 oe{async queryQuota(e,t,o){let r=await this.fetchJson("https://api.deepseek.com/user/balance",e,t,o),i=(Array.isArray(r?.balance_infos)?r.balance_infos:[]).find(a=>M(a?.total_balance)!==void 0);if(!i)return null;let l=M(i.total_balance);return l===void 0?null:{totalBalance:l,currency:typeof i.currency=="string"?i.currency:void 0}}},ho=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 i={},l=M(s.limit),a=M(s.limit_remaining),c=M(s.usage),u=M(s.usage_daily);return l!==void 0&&(i.totalBalance=l),a!==void 0&&(i.remainingBalance=a),c!==void 0&&(i.usedBalance=c),u!==void 0&&(i.usedDailyBalance=u),this.hasQuotaData(i)?i:null}},yo=class extends oe{async queryQuota(e,t,o){let r=el(e.baseUrl),i=(await this.fetchJson(r,e,t,o))?.data;if(!i||typeof i!="object")return null;let l={},a=M(i.totalBalance),c=M(i.balance);return a!==void 0&&(l.totalBalance=a),c!==void 0&&(l.remainingBalance=c),a!==void 0&&c!==void 0&&(l.usedBalance=Math.max(0,a-c)),this.hasQuotaData(l)?l:null}},_o=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 i=await fetch("https://api.z.ai/api/monitor/usage/quota/limit",s);if(!i.ok)return null;let l=await i.json(),a=Array.isArray(l?.data?.limits)?l.data.limits:[],c=null,u=null,d=null;for(let f of a)f.type==="TOKENS_LIMIT"?f.unit===3?c=f:f.unit===6?u=f:c||(c=f):f.type==="TIME_LIMIT"&&(d=f);let g={};if(c){let f=M(c.currentValue),y=M(c.usage),p=M(c.remaining),m=M(c.percentage);f!==void 0?g.usedDailyBalance=f:m!==void 0&&(g.usedDailyBalance=m,g.limitDaily=100),y!==void 0?g.limitDaily=y:f!==void 0&&p!==void 0&&(g.limitDaily=f+p),c.nextResetTime&&(g.resetTime=new Date(c.nextResetTime).toISOString())}if(u){let f=M(u.currentValue),y=M(u.usage),p=M(u.remaining),m=M(u.percentage);f!==void 0?g.usedBalance=f:m!==void 0&&(g.usedBalance=m,g.totalBalance=100),y!==void 0?g.totalBalance=y:f!==void 0&&p!==void 0&&(g.totalBalance=f+p),u.nextResetTime&&!g.resetTime&&(g.resetTime=new Date(u.nextResetTime).toISOString())}if(d){if(g.usedDailyBalance===void 0){let f=M(d.currentValue);f!==void 0&&(g.usedDailyBalance=f)}if(g.limitDaily===void 0){let f=M(d.usage),y=M(d.currentValue),p=M(d.remaining);f!==void 0?g.limitDaily=f:y!==void 0&&p!==void 0&&(g.limitDaily=y+p)}d.nextResetTime&&!g.resetTime&&(g.resetTime=new Date(d.nextResetTime).toISOString())}return this.hasQuotaData(g)?g:null}catch{return null}}},ko=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"}}}),i=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:i});if(!l.ok)return null;let c=(await l.json())?.data?.DataV2?.data?.data?.codingPlanInstanceInfos;if(!Array.isArray(c)||c.length===0)return null;let u=c[0]?.codingPlanQuotaInfo;if(!u)return null;let d={},g=M(u.per5HourUsedQuota),f=M(u.per5HourTotalQuota);g!==void 0&&(d.usedDailyBalance=g),f!==void 0&&(d.limitDaily=f);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}}};Fc=["per5HourPercentage","per5HourUsedPercentage","fiveHourPercentage"],Uc=["per1WeekPercentage","perWeekPercentage","per1WeekUsedPercentage"],jc=["per5HourResetTime","per5HourNextResetTime","fiveHourResetTime"],Hc=["per1WeekResetTime","per1WeekNextResetTime","perWeekResetTime"];bo=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 i=await this.queryOfficialEndpoint(r,s,t,o);if(i)return i}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",i=So(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":i}}}),a=new URLSearchParams({params:l,region:"cn-beijing",sec_token:t}).toString(),c={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:a,signal:AbortSignal.timeout(o)};try{r&&(c.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`,c);if(!u.ok)return null;let d=await u.json();return Vs(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"}}}),i=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:i,signal:AbortSignal.timeout(t)};try{o&&(l.dispatcher=G(o));let a=await fetch(`https://cs-data.qianwenai.com/data/api.json?product=sfm_bailian&action=BroadScopeAspnGateway&api=${encodeURIComponent(r)}`,l);if(!a.ok)return null;let c=await a.json();return Vs(c)}catch{return null}}},To=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:(So(e.quotaToken,"atp-auth-token")||So(e.quotaToken,"tenantToken")||e.quotaToken).trim(),Cookie:e.quotaToken},signal:AbortSignal.timeout(t)};try{o&&(s.dispatcher=G(o));let i=await fetch("https://maas.xfyun.cn/api/v1/gpt-finetune/coding-plan/list?page=1&size=10",s);if(!i.ok)return null;let l=await i.json();if(l?.succeed===!1||l?.failed===!0)return null;let a=tl(l,e.apiKey),c=a?.codingPlanUsageDTO||a?.usage||a;if(!c||typeof c!="object")return null;let u={},d=M(c.rp5hUsage),g=M(c.rp5hLimit);d!==void 0&&(u.usedDailyBalance=d),g!==void 0&&(u.limitDaily=g);let f=M(c.rpwUsage),y=M(c.rpwLimit);return f!==void 0&&(u.usedBalance=f),y!==void 0&&(u.totalBalance=y),u.remainingBalance===void 0&&y!==void 0&&f!==void 0&&(u.remainingBalance=Math.max(0,y-f)),this.hasQuotaData(u)?u: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={method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${r.trim()}`},signal:AbortSignal.timeout(t)};try{o&&(s.dispatcher=G(o));let i=await fetch("https://api.kimi.com/coding/v1/usages",s);if(!i.ok)return null;let l=await i.json(),a={},c=Array.isArray(l?.limits)?l.limits:[];if(c.length>0&&c[0]?.detail){let d=c[0].detail,g=M(d.limit),f=M(d.remaining),y=d.resetTime;g!==void 0&&f!==void 0&&(a.usedDailyBalance=Math.max(0,g-f),a.limitDaily=g),y&&(a.resetTime=new Date(y).toISOString())}let u=l?.usage;if(u){let d=M(u.limit),g=M(u.remaining),f=M(u.used),y=u.resetTime;d!==void 0&&(a.totalBalance=d,f!==void 0?a.usedBalance=f:g!==void 0&&(a.usedBalance=Math.max(0,d-g),a.remainingBalance=g)),y&&(a.resetTime7d=new Date(y).toISOString(),a.resetTime||(a.resetTime=a.resetTime7d))}return this.hasQuotaData(a)?a:null}catch{return null}}},vo=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",i=s.endsWith(".minimax.io")||s==="minimax.io"?"api.minimax.io":"api.minimaxi.com";try{let l=[`https://${i}/v1/token_plan/remains`,`https://${i}/v1/api/openplatform/coding_plan/remains`],a=null;for(let b of l)if(a=await this.fetchJson(b,e,t,o,r.trim()),a)break;if(!a)return null;if(a?.base_resp){let b=a.base_resp.status_code;if(b!==void 0&&b!==0)return null}let c=Array.isArray(a?.model_remains)?a.model_remains:[];if(c.length===0)return null;let u=c[0],d={},g=M(u.current_interval_total_count),f=M(u.current_interval_usage_count),y=M(u.current_interval_remaining_percent),p=M(u.end_time);g!==void 0&&f!==void 0&&g>0?(d.usedDailyBalance=Math.max(0,g-f),d.limitDaily=g):y!==void 0&&(d.limitDaily=100,d.usedDailyBalance=Math.max(0,100-y)),p&&(d.resetTime=new Date(p).toISOString());let m=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 m!==void 0&&_!==void 0&&m>0?(d.usedBalance=Math.max(0,m-_),d.remainingBalance=_,d.totalBalance=m):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}}},Wc=new go,Gc=new ho,Kc=new yo,Qc=new _o,Vc=new ko,Yc=new bo,Xc=new To,qc=new Co,Zc=new vo});function qs(n){return{[nl]:n,[ol]:St}}function sl(n){return n===!0||n==="true"||n===1||n==="1"}function il(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 cl(n){try{let e=new URL(n).hostname.toLowerCase();return e.includes("moonshot")||e.includes("kimi")}catch{return!1}}async function Eo(n,e,t){let o=performance.now(),r=()=>Math.max(0,Math.round(performance.now()-o)),s=al(n.baseUrl);if(!s)return{success:!1,error:"Cannot derive models endpoint from baseUrl",errorKind:"network",latencyMs:r()};try{let i={method:"GET",headers:{Authorization:`Bearer ${n.apiKey}`},signal:AbortSignal.timeout(e)};t&&(i.dispatcher=G(t));let l=await fetch(s,i);if(l.headers&&Ke(n.name,n.baseUrl,l.headers),l.ok)return{success:!0,headers:l.headers,latencyMs:r()};if(l.status===429)return{success:!1,error:`HTTP 429: ${(await l.text().catch(()=>"")).slice(0,100)||"Rate limited"}`,headers:l.headers,latencyMs:r(),errorKind:"http"};if(l.status>=400&&l.status<500)return{success:!0,headers:l.headers,latencyMs:r()};let a=await l.text().catch(()=>"");return{success:!1,error:`HTTP ${l.status}: ${a.slice(0,100)}`,headers:l.headers,latencyMs:r(),errorKind:"http"}}catch(i){let l=i?.message||i?.toString()||"Unknown probe error",a=i?.name==="TimeoutError"||i?.name==="AbortError"||i?.code===20||i?.code==="ABORT_ERR";return{success:!1,error:l,latencyMs:r(),errorKind:a?"timeout":"network"}}}async function ll(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,i=n.baseUrl.includes("/messages")||r.includes("claude");try{let l={"Content-Type":"application/json",...qs("scheduled-wakeup")};i?(l["x-api-key"]=n.apiKey,l["anthropic-version"]="2023-06-01"):l.Authorization=`Bearer ${n.apiKey}`;let a={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&&(a.dispatcher=G(t)),o?.info(`Sending scheduled wake-up call to provider ${n.name} using model ${r}...`);let c=await fetch(s,a);if(c.ok)return{success:!0};let u=await c.text().catch(()=>"");return{success:!1,error:`HTTP ${c.status}: ${u.slice(0,200)||"Unknown error"}`}}catch(l){return{success:!1,error:l?.message||l?.toString()||"Unknown wake-up error"}}}async function ul(n,e,t,o,r){let s=n.baseUrl,i=n.baseUrl.includes("/messages")||e.includes("claude");try{let l={"Content-Type":"application/json",...qs("rate-limit-probe")};i?(l["x-api-key"]=n.apiKey,l["anthropic-version"]="2023-06-01"):l.Authorization=`Bearer ${n.apiKey}`;let a={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&&(a.dispatcher=G(o)),r?.debug?.(`Sending independent ping to rate-limited model ${n.name} (${e})...`);let c=await fetch(s,a);if(c.ok)return{success:!0};let u=await c.text().catch(()=>"");return{success:!1,error:`HTTP ${c.status}: ${u.slice(0,200)||"Unknown error"}`}}catch(l){return{success:!1,error:l?.message||l?.toString()||"Unknown ping error"}}}function Zs(n,e,t,o,r){return pe||(pe=new mn(n,e,t,o,r)),pe}function De(n,e,t,o,r){let s=Zs(n,e,t,o,r);return s.start(),s}function Oo(){pe&&pe.stop()}function gn(){pe&&(pe.stop(),pe=null)}var nl,ol,rl,mn,pe,hn=w(()=>{"use strict";ne();Se();Po();Pe();zn();te();nl="x-claude-code-router-source",ol="x-claude-code-router-version";rl={enabled:!0,quotaProbeIntervalMinutes:10,probeTimeoutMs:15e3,slowThresholdMs:3e3,initialDelayMs:5e3,excludeProviders:[]};mn=class{config;quotaProbeTimer;healthProbeTimer;wakeupTimer;rateLimitProbeTimer;lastWakeupDate=new Map;getProviders;resolveProxyUrl;logger;getConfig;running=!1;probeTelemetry=new Map;constructor(e,t,o,r,s){this.config={...rl,...t},this.getProviders=e,this.resolveProxyUrl=o,this.logger=r,this.getConfig=s}recordProbe(e,t,o){let r=Date.now(),s=t.success&&t.latencyMs>this.config.slowThresholdMs,i;t.success?i=s?"slow":"healthy":i=t.errorKind==="timeout"?"timeout":"error";let l=this.probeTelemetry.get(e),a={provider:e,latencyMs:t.latencyMs,status:i,isSlow:s,errorKind:t.errorKind,errorMessage:t.error,lastProbeAt:r,lastSuccessAt:t.success?r:l?.lastSuccessAt,source:o};return this.probeTelemetry.set(e,a),s&&this.logger?.warn?.(`Slow network detected for provider ${e}: probe took ${t.latencyMs} ms (threshold ${this.config.slowThresholdMs} ms)`),a}getProbeTelemetry(){return Array.from(this.probeTelemetry.values()).map(e=>({...e}))}getProviderProbeTelemetry(e){let t=this.probeTelemetry.get(e);return t?{...t}:void 0}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 i=Ro(s.baseUrl),l=Array.isArray(s.models)?s.models:[],a=this.resolveProxyUrl?.(s);if(!i){let c;try{c=new URL(s.baseUrl).hostname}catch{c=void 0}this.logger?.debug?.(`No quota adapter for provider ${s.name}`+(c?` (host: ${c})`:"")+" \u2014 skipping quota probe")}i&&o.push({provider:s.name,models:l,type:"quota-adapter",promise:i.queryQuota(s,this.config.probeTimeoutMs,a).then(c=>{if(c){no(s.name,c),this.logger?.debug?.(`Stored quota probe result for ${s.name}`);let u=c.limitDaily!==void 0&&c.usedDailyBalance!==void 0&&c.usedDailyBalance>=c.limitDaily,d=c.totalBalance!==void 0&&c.usedBalance!==void 0&&c.usedBalance>=c.totalBalance;if(u||d){let g=u?`Quota exhausted: 5h limit reached (${c.usedDailyBalance}/${c.limitDaily})`:`Quota exhausted: 7d balance depleted (${c.usedBalance}/${c.totalBalance})`;for(let f of l){if(t.getState(s.name,f)?.rateLimitUntil){this.logger?.debug?.(`Skip forceOpen for ${s.name} (${f}): already rate-limited with active cooldown`);continue}t.forceOpen(s.name,f,g)}this.logger?.warn?.(`${g} for ${s.name}, marked as unhealthy`)}else for(let g of l){let f=t.getState(s.name,g);f&&f.status==="open"&&f.lastError?.includes("Quota exhausted")&&(t.recover(s.name,g),this.logger?.info?.(`Quota recovered for ${s.name} (${g}), marked as healthy`))}}})}),cl(s.baseUrl)&&o.push({provider:s.name,models:l,type:"rate-limit-headers",promise:Eo(s,this.config.probeTimeoutMs,a).then(c=>{this.recordProbe(s.name,c,"rate-limit-headers")})})}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 i=r[s];if(i.status==="rejected"){let l=o[s];this.logger?.warn?.(`Quota probe failed for ${l.provider} (${l.type}): ${i.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=>Eo(r,this.config.probeTimeoutMs,this.resolveProxyUrl?.(r))));for(let r=0;r<t.length;r++){let s=t[r],i=o[r],l=Array.isArray(s.models)?s.models:[];if(i.status==="fulfilled"){let a=i.value;if(this.recordProbe(s.name,a,"health"),a.success){let c=0;for(let u of l){let d=e.getState(s.name,u);if(d&&d.status==="open"){let g=d.lastError?.includes("Quota exhausted"),f=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(g){this.logger?.debug?.(`Skipping health probe recovery for ${s.name} (${u}) because quota is exhausted`);continue}if(f||d.rateLimitUntil){this.logger?.debug?.(`Skipping health probe recovery for rate-limited ${s.name} (${u})`);continue}}e.recordSuccess(s.name,u),c++}c>0&&this.logger?.info?.(`Health probe succeeded for ${s.name}`)}else{for(let c of l)e.recordFailure(s.name,c,a.error);this.logger?.warn?.(`Health probe failed for ${s.name}: ${a.error}`)}}else{this.recordProbe(s.name,{success:!1,error:i.reason?.message||String(i.reason||"Probe error"),latencyMs:0,errorKind:"network"},"health");for(let a of l)e.recordFailure(s.name,a,i.reason?.message||"Probe error");this.logger?.warn?.(`Health probe error for ${s.name}: ${i.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[i,...l]=s.split(","),a=l.join(",");if(!i||!a)continue;let c=e.getState(i,a);if(!c||!c.rateLimitUntil)continue;if(Date.now()>=c.rateLimitUntil){e.recover(i,a),this.logger?.info?.(`Rate-limit cooldown expired, auto-recovered ${s}`);continue}let u=o.find(d=>d?.name===i&&d.enabled!==!1);if(!u){this.logger?.warn?.(`Provider ${i} not found or disabled for rate-limit probe`);continue}try{let d=await ul(u,a,r,this.resolveProxyUrl?.(u),this.logger);if(d.success)this.logger?.info?.(`Rate-limit probe succeeded for ${s}, recovering model`),e.recover(i,a);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 g=Date.now();c.rateLimitUntil&&c.rateLimitUntil>g?c.rateLimitUntil+=120*1e3:c.rateLimitUntil=g+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=il(t),i=this.getConfig&&this.getConfig("WAKEUP_TIME")||"06:00";for(let l of e){let a=l.wakeupTime||i,[c,u]=a.split(":"),d=parseInt(c,10),g=parseInt(u,10);if(isNaN(d)||isNaN(g))continue;let f=o>d||o===d&&r>=g,y=(d*60+g)*6e4-(o*60+r)*6e4,p=y>0&&y<=300*1e3;(f||p)&&!this.hasWakeupFiredToday(l.name,s)&&(this.logger?.info?.(`Scheduled wake-up triggered for provider ${l.name} at ${a}`),ll(l,3e4,this.resolveProxyUrl?.(l),this.logger).then(m=>{m.success?this.logger?.info?.(`Successfully woke up provider ${l.name}`):this.logger?.error?.(`Failed to wake up provider ${l.name}: ${m.error}`)}).catch(m=>{this.logger?.error?.(`Error in wake-up task for ${l.name}: ${m}`)}))}}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(l=>l.name===e);if(!o)return this.logger?.warn?.(`Provider ${e} not found for manual probe`),{success:!1,latencyMs:0,status:"error",isSlow:!1,error:`Provider ${e} not found`};if(o.enabled===!1)return this.logger?.warn?.(`Provider ${e} is disabled, skipping manual probe`),{success:!1,latencyMs:0,status:"error",isSlow:!1,error:`Provider ${e} is disabled`};let r=await Eo(o,this.config.probeTimeoutMs,this.resolveProxyUrl?.(o)),s=this.recordProbe(o.name,r,"manual"),i=Array.isArray(o.models)?o.models:[];if(r.success)for(let l of i)U().recordSuccess(o.name,l);else for(let l of i)U().recordFailure(o.name,l,r.error);return{success:r.success,latencyMs:r.latencyMs,status:s.status,isSlow:s.isSlow,errorKind:r.errorKind,error:r.error}}},pe=null});var ei=w(()=>{"use strict"});var Ao,rt,ti=w(()=>{"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 ie,Io=w(()=>{"use strict";ie=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 Fe,Mo=w(()=>{"use strict";Fe=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,$o=w(()=>{"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 i=await e(s,o);i!==void 0&&o.enqueue(i)}}catch(r){o.error(r)}finally{t.releaseLock()}}})}});var No=w(()=>{"use strict";Io();Mo();$o()});var ni=w(()=>{"use strict"});var st,Lo=w(()=>{"use strict";st=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:i}=t||{},l="";if(r){let a=new Date().toISOString();l+=this.config.colors?`${this.colors.cyan}[${a}]${this.colors.reset} `:`[${a}] `}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 i&&Object.keys(i).length>0&&(l+=`
|
|
311
311
|
`+(this.config.colors?`${this.colors.dim}`:""),l+="Metadata: "+JSON.stringify(i,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 rt,No=w(()=>{"use strict";rt=class{type="webhook";config;defaultTimeout=3e4;constructor(e){if(!e.url)throw new Error("Webhook URL is required");this.config={method:"POST",retry:{maxAttempts:3,backoffMs:1e3},silent:!1,...e}}buildHeaders(){let e={"Content-Type":"application/json",...this.config.headers||{}};if(this.config.auth)switch(this.config.auth.type){case"bearer":this.config.auth.token&&(e.Authorization=`Bearer ${this.config.auth.token}`);break;case"basic":if(this.config.auth.username&&this.config.auth.password){let t=Buffer.from(`${this.config.auth.username}:${this.config.auth.password}`).toString("base64");e.Authorization=`Basic ${t}`}break;case"custom":this.config.auth.custom&&(e[this.config.auth.custom.header]=this.config.auth.custom.value);break}return e}buildBody(e,t){let{format:o="json",timestamp:r=!0,prefix:s,metadata:i}=t||{},l={data:e};return r&&(l.timestamp=new Date().toISOString()),s&&(l.prefix=s),i&&Object.keys(i).length>0&&(l.metadata=i),l}async sendRequest(e,t,o,r,s){let i=new AbortController,l=setTimeout(()=>i.abort(),s);try{let a=await fetch(e,{method:t,headers:o,body:JSON.stringify(r),signal:i.signal});if(clearTimeout(l),!a.ok)throw new Error(`HTTP ${a.status}: ${a.statusText}`);return a}catch(a){throw clearTimeout(l),a}}delay(e){return new Promise(t=>setTimeout(t,e))}async sendWithRetry(e,t,o,r,s,i){let l=null;for(let a=1;a<=i.maxAttempts;a++)try{return await this.sendRequest(e,t,o,r,s)}catch(c){if(l=c,a===i.maxAttempts)break;let u=i.backoffMs*Math.pow(2,a-1);console.warn(`[WebhookOutputHandler] Request failed (attempt ${a}/${i.maxAttempts}), retrying in ${u}ms...`,c.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),i=await this.sendWithRetry(this.config.url,this.config.method,r,s,o,this.config.retry);return!0}catch(r){let s=r instanceof Error?r.message:String(r);if(this.config.silent)return console.error(`[WebhookOutputHandler] Failed to send data: ${s}`),!1;throw new Error(`Webhook output failed: ${s}`)}}}});import{writeFileSync as al,existsSync as cl,mkdirSync as ll}from"fs";import{join as ei}from"path";import{tmpdir as ul}from"os";var st,Lo=w(()=>{"use strict";st=class{type="temp-file";config;baseDir;constructor(e={}){this.config={subdirectory:"claude-code-router",extension:"json",includeTimestamp:!1,prefix:"session",...e};let t=ul();this.baseDir=ei(t,this.config.subdirectory),this.ensureDir()}ensureDir(){try{cl(this.baseDir)||ll(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 ei(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 al(s,JSON.stringify(r,null,2),"utf-8"),!0}catch{return!1}}getBaseDir(){return this.baseDir}}});var Do,De,ti=w(()=>{"use strict";$o();No();Lo();Do=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 ot(e.config);case"webhook":return new rt(e.config);case"temp-file":return new st(e.config);default:throw new Error(`Unknown output handler type: ${e.type}`)}}unregisterHandler(e){return this.handlers.delete(e)}getHandler(e){return this.handlers.get(e)}getAllHandlers(){return new Map(this.handlers)}clearHandlers(){this.handlers.clear()}setDefaultOptions(e){this.defaultOptions={...this.defaultOptions,...e}}getDefaultOptions(){return{...this.defaultOptions}}async output(e,t){let o={...this.defaultOptions,...t},r={success:[],failed:[]},s=Array.from(this.handlers.entries()).map(async([i,l])=>{try{await l.output(e,o)?r.success.push(i):r.failed.push(i)}catch(a){console.error(`[OutputManager] Handler ${i} failed:`,a),r.failed.push(i)}});return await Promise.all(s),r}async outputTo(e,t,o){let r={...this.defaultOptions,...o},s={success:[],failed:[]},i=e.map(async l=>{let a=this.handlers.get(l);if(!a){console.warn(`[OutputManager] Handler ${l} not found`),s.failed.push(l);return}try{await a.output(t,r)?s.success.push(l):s.failed.push(l)}catch(c){console.error(`[OutputManager] Handler ${l} failed:`,c),s.failed.push(l)}});return await Promise.all(i),s}async outputToType(e,t,o){let r=Array.from(this.handlers.entries()).filter(([s,i])=>i.type===e).map(([s])=>s);return this.outputTo(r,t,o)}},De=new Do});var Fo=w(()=>{"use strict";Zs();$o();No();Lo();ti()});import dl from"fastify-plugin";function ni(n,e,t=0){if(n<=0)return 0;let o=Math.max((e-t)/1e3,pl);return Math.round(n/o)}function at(n){let e=(n.match(/[\u4e00-\u9fa5]/g)||[]).length,t=n.length-e;return Math.ceil(e/1.5+t/4)}async function oi(n,e,t,o=!1){let r=o?"[Token Speed Final]":"[Token Speed]",s={requestId:n.requestId.substring(0,8),sessionId:n.sessionId,stream:n.stream,tokenCount:n.tokenCount,tokensPerSecond:n.tokensPerSecond,timeToFirstToken:n.timeToFirstToken?`${n.timeToFirstToken}ms`:"N/A",duration:`${((n.lastTokenTime-n.startTime)/1e3).toFixed(2)}s`,timestamp:Date.now()},i={prefix:r,metadata:{sessionId:n.sessionId},...t};for(let l of e)try{await De.outputToType(l,s,i)}catch(a){console.error(`[TokenSpeedPlugin] Failed to output to ${l}:`,a)}}var it,Uo,pl,hn,ri=w(()=>{"use strict";Mo();Fo();Ve();it=new Map,Uo=new Map,pl=1,hn={name:"token-speed",version:"1.0.0",description:"Statistics for streaming response token generation speed",register:dl(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)De.registerHandlers(t.outputHandlers);else{let i=[];for(let l of o)l==="console"?i.push({type:"console",enabled:!0,config:{colors:!0,level:"log"}}):l==="temp-file"?i.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");i.length>0&&De.registerHandlers(i)}t.outputOptions&&De.setDefaultOptions(t.outputOptions);let r=async i=>{let l=n.tokenizerService;if(!l)return n.log?.warn("TokenizerService not available"),null;if(!i.provider||!i.model)return null;let a=i.provider,c=i.model,u=`${a}:${c}`;if(Uo.has(u))return Uo.get(u);let d=l.getTokenizerConfigForModel(a,c);if(!d)return n.log?.debug(`No tokenizer config for ${a}:${c}, using fallback`),null;try{let g=await l.getTokenizer(d,a);return Uo.set(u,g),n.log?.info(`Created tokenizer for ${a}:${c} - ${g.name}`),g}catch(g){return n.log?.warn(`Failed to create tokenizer for ${a}:${c}: ${g.message}`),null}},s=i=>{let l=new URL(`http://127.0.0.1${i}`).pathname;return l.endsWith("/v1/messages")||l.endsWith("/v1/responses")};n.addHook("onRequest",async i=>{s(i.url)&&(i.requestStartTime=performance.now())}),n.addHook("onSend",async(i,l,a)=>{let c=i.requestStartTime;if(!c)return;let u=i.id||Date.now().toString(),d=i.usageSessionId;if(!d)try{d=Qe(i.body?.metadata?.user_id)}catch{}if(!d){let f=i.headers?.["x-request-id"],_=Array.isArray(f)?f[0]:f;d=(typeof _=="string"?_:void 0)||u}let g=await r(i);if(a instanceof ReadableStream){it.set(u,{requestId:u,sessionId:d,startTime:c,lastTokenTime:c,tokenCount:0,tokensPerSecond:0,stream:!0});let[f,_]=a.tee(),k=async()=>{let h=null,b=async T=>{let x=it.get(u);if(!x)return;let v=x.firstTokenTime?x.firstTokenTime-x.startTime:0,C=(T?x.lastTokenTime:performance.now())-x.startTime;x.tokensPerSecond=ni(x.tokenCount,C,v),await oi(x,o,t.outputOptions,T).catch(P=>{n.log?.warn(`Failed to output streaming stats: ${P.message}`)})};try{let x=_.pipeThrough(new TextDecoderStream).pipeThrough(new re).getReader();for(h=setInterval(async()=>{it.get(u)&&await b(!1)},1e3);;){let{done:v,value:S}=await x.read();if(v)break;let C=S,P=it.get(u);if(!P)continue;let R=performance.now(),O=C.event||C.data?.type,E=C.event==="content_block_start"||C.event==="content_block_delta"||C.event==="text_block"||C.event==="content_block"||O==="response.output_text.delta"||O==="response.function_call_arguments.delta"||O==="response.reasoning_summary_text.delta";!P.firstTokenTime&&E&&(P.firstTokenTime=R,P.timeToFirstToken=Math.round(R-P.startTime));let A="";if(C.event==="content_block_delta"&&C.data?.delta){let N=C.data.delta.type;N==="text_delta"?A=C.data.delta.text||"":N==="input_json_delta"?A=C.data.delta.partial_json||"":N==="thinking_delta"&&(A=C.data.delta.thinking||"")}if((O==="response.output_text.delta"||O==="response.function_call_arguments.delta"||O==="response.reasoning_summary_text.delta")&&(A=typeof C.data?.delta=="string"?C.data.delta:""),A){let N=g&&g.encodeText?g.encodeText(A).length:at(A);P.tokenCount+=N,P.lastTokenTime=R}(C.event==="message_stop"||O==="response.completed"||O==="response.failed")&&(h&&(clearInterval(h),h=null),await b(!0),it.delete(u))}}catch(T){h&&clearInterval(h),T.name!=="AbortError"&&T.code!=="ERR_STREAM_PREMATURE_CLOSE"&&n.log?.warn(`Error processing token stats: ${T.message}`)}};return i.tokenSpeedCapturePromise=k().catch(h=>{console.log(h),n.log?.warn(`Background stats processing failed: ${h.message}`)}),f}let m=performance.now(),y=0,p=!1;if(a&&typeof a=="string")try{let f=JSON.parse(a);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,g)Array.isArray(_)?y=_.reduce((k,h)=>{if(h.type==="text"){let b=h.text||"";return k+(g.encodeText?g.encodeText(b).length:at(b))}return k},0):typeof _=="string"&&(y=g.encodeText?g.encodeText(_).length:at(_));else{let k=Array.isArray(_)?_.map(h=>h.text).join(""):typeof _=="string"?_:"";y=at(k)}}}catch{}if(p){let f=m-c,_={requestId:u,sessionId:d,startTime:c,lastTokenTime:m,tokenCount:y,tokensPerSecond:ni(y,f),stream:!1};await oi(_,o,t.outputOptions,!0)}return a})})}});var jo=w(()=>{"use strict";Xs();qs();ri();Fo()});import X from"node:fs/promises";import si from"json5";import ye from"node:path";import{CONFIG_FILE as q,HOME_DIR as yn,PLUGINS_DIR as fl}from"@wengine-ai/claude-code-router-shared";function ii(){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,ct,_n,zo,ne,kn,Fe,ml,Bo,bn=w(()=>{"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},ct=async n=>{try{await X.access(n)}catch{await X.mkdir(n,{recursive:!0})}},_n=async()=>{await ct(yn),await ct(fl),await ct(ye.join(yn,"logs"))},zo=async()=>{let n=await X.readFile(q,"utf-8");return si.parse(n)},ne=async()=>{try{let n=await X.readFile(q,"utf-8");try{let e=si.parse(n);return Ho(e)}catch(e){console.error(`Failed to parse config file at ${q}`),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 _n();let e=await kn();e&&console.log(`Backed up existing configuration file to ${e}`);let t={PORT:3456,Providers:[],Router:{}};return await Fe(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 ${q}`),console.error("Error details:",n.message),process.exit(1)}};kn=async()=>{ii();try{if(await X.access(q).then(()=>!0).catch(()=>!1)){let n=new Date().toISOString().replace(/[:.]/g,"-"),e=`${q}.${n}.bak`;await X.copyFile(q,e);try{let t=ye.dirname(q),o=ye.basename(q),s=(await X.readdir(t)).filter(i=>i.startsWith(o)&&i.endsWith(".bak")).sort().reverse();if(s.length>3)for(let i=3;i<s.length;i++){let l=ye.join(t,s[i]);await X.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},Fe=async n=>{ii(),await ct(yn),await ml();let e=`${JSON.stringify(n,null,2)}`;await X.writeFile(q,e)},ml=async()=>{if(!await X.access(q).then(()=>!0).catch(()=>!1))return;let e=ye.join(yn,"config-history");await ct(e);let t=new Date().toISOString().replace(/[:.]/g,"-"),o=ye.join(e,`config-${t}.json`);await X.copyFile(q,o);try{let s=(await X.readdir(e)).filter(i=>i.startsWith("config-")&&i.endsWith(".json")).sort().reverse();if(s.length>50)for(let i of s.slice(50))await X.unlink(ye.join(e,i))}catch(r){console.warn("Failed to prune config-history:",r)}},Bo=async()=>{let n=await ne();return Object.assign(process.env,n),n}});function gl(n){return n?.cache_read_input_tokens??n?.input_tokens_details?.cached_tokens??n?.prompt_tokens_details?.cached_tokens??0}function hl(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:gl(n),cache_creation_input_tokens:hl(n)}}function Tn(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 Jo=w(()=>{"use strict"});function Cn(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(Wo(r,s))}return}if(Array.isArray(n)){for(let o of n)Cn(o,e,t);return}if(typeof n=="object")for(let o of Object.values(n))Cn(o,e,t)}}function ai(n){let e=n?.Providers||n?.providers||[],t=new Set,o=new Set;for(let r of e){let s=r?.name;if(!s)continue;t.add(s);let i=Array.isArray(r?.models)?r.models:[];for(let l of i)l&&o.add(Wo(s,l))}return Cn(n?.Router,t,o),Cn(n?.fallback,t,o),o}function lt(n,e){try{let t=F();if(!t?.getAllStates||!t?.recover)return 0;let o=ai(n),r=0;for(let s of t.getAllStates()||[]){let i=s?.provider,l=s?.model;!i||!l||o.has(Wo(i,l))||(t.recover(i,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=F();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 yl,Wo,xn=w(()=>{"use strict";ee();yl="\0",Wo=(n,e)=>`${n}${yl}${e}`});function _l(n){return/\[1m\]/i.test(n)?1e6:2e5}function kl(n){let e=n.toLowerCase();return e.includes("haiku")||e.includes("mini")?8192:32e3}function bl(n,e=n){let t=_l(n),o=kl(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 Sn(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 Go=w(()=>{"use strict"});function Tl(n){let e=n.ip||n.connection?.remoteAddress||"";return e==="127.0.0.1"||e==="::1"||e==="::ffff:127.0.0.1"}var Rn,Ko=w(()=>{"use strict";Rn=n=>async(e,t,o)=>{if(["/","/health"].includes(e.url)||e.url.startsWith("/ui")||Tl(e))return o();let s=n.Providers||n.providers||[];if(!s||s.length===0)return o();let i=n.APIKEY;if(!i){let u=[`http://127.0.0.1:${n.PORT||3456}`,`http://localhost:${n.PORT||3456}`];if(e.headers.origin&&!u.includes(e.headers.origin)){t.status(403).send("CORS not allowed for this origin");return}else t.header("Access-Control-Allow-Origin",`http://127.0.0.1:${n.PORT||3456}`),t.header("Access-Control-Allow-Origin",`http://localhost:${n.PORT||3456}`);return o()}let l=e.headers.authorization||e.headers["x-api-key"],a=Array.isArray(l)?l[0]:l||"";if(!a){t.log.warn({url:e.url,headers:Object.keys(e.headers)},"[AUTH] No auth header"),t.status(401).send("APIKEY is missing");return}let c="";if(a.startsWith("Bearer")?c=a.split(" ")[1]:c=a,c!==i){t.log.warn({url:e.url,gotPrefix:c.slice(0,10),gotSuffix:c.slice(-6),gotLen:c.length,expectedPrefix:i.slice(0,6),expectedSuffix:i.slice(-6),expectedLen:i.length},"[AUTH] Key mismatch"),t.status(401).send("Invalid API key");return}o()}});var gi={};Nn(gi,{append:()=>ft,clear:()=>Zo,close:()=>zl,getOldestRecordTimestamp:()=>Bl,query:()=>qo,querySummary:()=>mt,readTokenSpeedStats:()=>er});import{existsSync as Yo,mkdirSync as Cl,readFileSync as Vo,readdirSync as vl}from"fs";import{join as He}from"path";import{homedir as xl,tmpdir as Sl}from"os";import Rl from"better-sqlite3";function Al(){Yo(Pn)||Cl(Pn,{recursive:!0})}function pt(){if(pe)return pe;Al();let n=new Rl(wl);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&&(Il(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")),$l(n),pi(n,!0),Xo=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 it,Do=w(()=>{"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:i}=t||{},l={data:e};return r&&(l.timestamp=new Date().toISOString()),s&&(l.prefix=s),i&&Object.keys(i).length>0&&(l.metadata=i),l}async sendRequest(e,t,o,r,s){let i=new AbortController,l=setTimeout(()=>i.abort(),s);try{let a=await fetch(e,{method:t,headers:o,body:JSON.stringify(r),signal:i.signal});if(clearTimeout(l),!a.ok)throw new Error(`HTTP ${a.status}: ${a.statusText}`);return a}catch(a){throw clearTimeout(l),a}}delay(e){return new Promise(t=>setTimeout(t,e))}async sendWithRetry(e,t,o,r,s,i){let l=null;for(let a=1;a<=i.maxAttempts;a++)try{return await this.sendRequest(e,t,o,r,s)}catch(c){if(l=c,a===i.maxAttempts)break;let u=i.backoffMs*Math.pow(2,a-1);console.warn(`[WebhookOutputHandler] Request failed (attempt ${a}/${i.maxAttempts}), retrying in ${u}ms...`,c.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),i=await this.sendWithRetry(this.config.url,this.config.method,r,s,o,this.config.retry);return!0}catch(r){let s=r instanceof Error?r.message:String(r);if(this.config.silent)return console.error(`[WebhookOutputHandler] Failed to send data: ${s}`),!1;throw new Error(`Webhook output failed: ${s}`)}}}});import{writeFileSync as dl,existsSync as pl,mkdirSync as fl}from"fs";import{join as oi}from"path";import{tmpdir as ml}from"os";var at,Fo=w(()=>{"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=ml();this.baseDir=oi(t,this.config.subdirectory),this.ensureDir()}ensureDir(){try{pl(this.baseDir)||fl(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 oi(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 dl(s,JSON.stringify(r,null,2),"utf-8"),!0}catch{return!1}}getBaseDir(){return this.baseDir}}});var Uo,Ue,ri=w(()=>{"use strict";Lo();Do();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 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([i,l])=>{try{await l.output(e,o)?r.success.push(i):r.failed.push(i)}catch(a){console.error(`[OutputManager] Handler ${i} failed:`,a),r.failed.push(i)}});return await Promise.all(s),r}async outputTo(e,t,o){let r={...this.defaultOptions,...o},s={success:[],failed:[]},i=e.map(async l=>{let a=this.handlers.get(l);if(!a){console.warn(`[OutputManager] Handler ${l} not found`),s.failed.push(l);return}try{await a.output(t,r)?s.success.push(l):s.failed.push(l)}catch(c){console.error(`[OutputManager] Handler ${l} failed:`,c),s.failed.push(l)}});return await Promise.all(i),s}async outputToType(e,t,o){let r=Array.from(this.handlers.entries()).filter(([s,i])=>i.type===e).map(([s])=>s);return this.outputTo(r,t,o)}},Ue=new Uo});var jo=w(()=>{"use strict";ni();Lo();Do();Fo();ri()});import gl from"fastify-plugin";function si(n,e,t=0){if(n<=0)return 0;let o=Math.max((e-t)/1e3,hl);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 ii(n,e,t,o=!1){let r=o?"[Token Speed Final]":"[Token Speed]",s={requestId:n.requestId.substring(0,8),sessionId:n.sessionId,stream:n.stream,tokenCount:n.tokenCount,tokensPerSecond:n.tokensPerSecond,timeToFirstToken:n.timeToFirstToken?`${n.timeToFirstToken}ms`:"N/A",duration:`${((n.lastTokenTime-n.startTime)/1e3).toFixed(2)}s`,timestamp:Date.now()},i={prefix:r,metadata:{sessionId:n.sessionId},...t};for(let l of e)try{await Ue.outputToType(l,s,i)}catch(a){console.error(`[TokenSpeedPlugin] Failed to output to ${l}:`,a)}}var ct,Ho,hl,_n,ai=w(()=>{"use strict";No();jo();Xe();ct=new Map,Ho=new Map,hl=1,_n={name:"token-speed",version:"1.0.0",description:"Statistics for streaming response token generation speed",register:gl(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)Ue.registerHandlers(t.outputHandlers);else{let i=[];for(let l of o)l==="console"?i.push({type:"console",enabled:!0,config:{colors:!0,level:"log"}}):l==="temp-file"?i.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");i.length>0&&Ue.registerHandlers(i)}t.outputOptions&&Ue.setDefaultOptions(t.outputOptions);let r=async i=>{let l=n.tokenizerService;if(!l)return n.log?.warn("TokenizerService not available"),null;if(!i.provider||!i.model)return null;let a=i.provider,c=i.model,u=`${a}:${c}`;if(Ho.has(u))return Ho.get(u);let d=l.getTokenizerConfigForModel(a,c);if(!d)return n.log?.debug(`No tokenizer config for ${a}:${c}, using fallback`),null;try{let g=await l.getTokenizer(d,a);return Ho.set(u,g),n.log?.info(`Created tokenizer for ${a}:${c} - ${g.name}`),g}catch(g){return n.log?.warn(`Failed to create tokenizer for ${a}:${c}: ${g.message}`),null}},s=i=>{let l=new URL(`http://127.0.0.1${i}`).pathname;return l.endsWith("/v1/messages")||l.endsWith("/v1/responses")};n.addHook("onRequest",async i=>{s(i.url)&&(i.requestStartTime=performance.now())}),n.addHook("onSend",async(i,l,a)=>{let c=i.requestStartTime;if(!c)return;let u=i.id||Date.now().toString(),d=i.usageSessionId;if(!d)try{d=Ye(i.body?.metadata?.user_id)}catch{}if(!d){let m=i.headers?.["x-request-id"],_=Array.isArray(m)?m[0]:m;d=(typeof _=="string"?_:void 0)||u}let g=await r(i);if(a instanceof ReadableStream){ct.set(u,{requestId:u,sessionId:d,startTime:c,lastTokenTime:c,tokenCount:0,tokensPerSecond:0,stream:!0});let[m,_]=a.tee(),k=async()=>{let h=null,b=async T=>{let x=ct.get(u);if(!x)return;let v=x.firstTokenTime?x.firstTokenTime-x.startTime:0,C=(T?x.lastTokenTime:performance.now())-x.startTime;x.tokensPerSecond=si(x.tokenCount,C,v),await ii(x,o,t.outputOptions,T).catch(P=>{n.log?.warn(`Failed to output streaming stats: ${P.message}`)})};try{let x=_.pipeThrough(new TextDecoderStream).pipeThrough(new ie).getReader();for(h=setInterval(async()=>{ct.get(u)&&await b(!1)},1e3);;){let{done:v,value:S}=await x.read();if(v)break;let C=S,P=ct.get(u);if(!P)continue;let R=performance.now(),O=C.event||C.data?.type,E=C.event==="content_block_start"||C.event==="content_block_delta"||C.event==="text_block"||C.event==="content_block"||O==="response.output_text.delta"||O==="response.function_call_arguments.delta"||O==="response.reasoning_summary_text.delta";!P.firstTokenTime&&E&&(P.firstTokenTime=R,P.timeToFirstToken=Math.round(R-P.startTime));let A="";if(C.event==="content_block_delta"&&C.data?.delta){let N=C.data.delta.type;N==="text_delta"?A=C.data.delta.text||"":N==="input_json_delta"?A=C.data.delta.partial_json||"":N==="thinking_delta"&&(A=C.data.delta.thinking||"")}if((O==="response.output_text.delta"||O==="response.function_call_arguments.delta"||O==="response.reasoning_summary_text.delta")&&(A=typeof C.data?.delta=="string"?C.data.delta:""),A){let N=g&&g.encodeText?g.encodeText(A).length:lt(A);P.tokenCount+=N,P.lastTokenTime=R}(C.event==="message_stop"||O==="response.completed"||O==="response.failed")&&(h&&(clearInterval(h),h=null),await b(!0),ct.delete(u))}}catch(T){h&&clearInterval(h),T.name!=="AbortError"&&T.code!=="ERR_STREAM_PREMATURE_CLOSE"&&n.log?.warn(`Error processing token stats: ${T.message}`)}};return i.tokenSpeedCapturePromise=k().catch(h=>{console.log(h),n.log?.warn(`Background stats processing failed: ${h.message}`)}),m}let f=performance.now(),y=0,p=!1;if(a&&typeof a=="string")try{let m=JSON.parse(a);if(typeof m.usage?.output_tokens=="number")y=m.usage.output_tokens,p=!0;else{let _=m.content??m.message?.content;if(_!==void 0)if(p=!0,g)Array.isArray(_)?y=_.reduce((k,h)=>{if(h.type==="text"){let b=h.text||"";return k+(g.encodeText?g.encodeText(b).length:lt(b))}return k},0):typeof _=="string"&&(y=g.encodeText?g.encodeText(_).length:lt(_));else{let k=Array.isArray(_)?_.map(h=>h.text).join(""):typeof _=="string"?_:"";y=lt(k)}}}catch{}if(p){let m=f-c,_={requestId:u,sessionId:d,startTime:c,lastTokenTime:f,tokenCount:y,tokensPerSecond:si(y,m),stream:!1};await ii(_,o,t.outputOptions,!0)}return a})})}});var zo=w(()=>{"use strict";ei();ti();ai();jo()});import Z from"node:fs/promises";import ci from"json5";import ke from"node:path";import{CONFIG_FILE as ee,HOME_DIR as kn,PLUGINS_DIR as yl}from"@wengine-ai/claude-code-router-shared";function li(){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 Jo,ut,bn,Bo,re,Tn,je,_l,Wo,Cn=w(()=>{"use strict";Jo=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(Jo);if(n!==null&&typeof n=="object"){let e={};for(let[t,o]of Object.entries(n))e[t]=Jo(o);return e}return n},ut=async n=>{try{await Z.access(n)}catch{await Z.mkdir(n,{recursive:!0})}},bn=async()=>{await ut(kn),await ut(yl),await ut(ke.join(kn,"logs"))},Bo=async()=>{let n=await Z.readFile(ee,"utf-8");return ci.parse(n)},re=async()=>{try{let n=await Z.readFile(ee,"utf-8");try{let e=ci.parse(n);return Jo(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 Tn();e&&console.log(`Backed up existing configuration file to ${e}`);let t={PORT:3456,Providers:[],Router:{}};return await je(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)}};Tn=async()=>{li();try{if(await Z.access(ee).then(()=>!0).catch(()=>!1)){let n=new Date().toISOString().replace(/[:.]/g,"-"),e=`${ee}.${n}.bak`;await Z.copyFile(ee,e);try{let t=ke.dirname(ee),o=ke.basename(ee),s=(await Z.readdir(t)).filter(i=>i.startsWith(o)&&i.endsWith(".bak")).sort().reverse();if(s.length>3)for(let i=3;i<s.length;i++){let l=ke.join(t,s[i]);await Z.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},je=async n=>{li(),await ut(kn),await _l();let e=`${JSON.stringify(n,null,2)}`;await Z.writeFile(ee,e)},_l=async()=>{if(!await Z.access(ee).then(()=>!0).catch(()=>!1))return;let e=ke.join(kn,"config-history");await ut(e);let t=new Date().toISOString().replace(/[:.]/g,"-"),o=ke.join(e,`config-${t}.json`);await Z.copyFile(ee,o);try{let s=(await Z.readdir(e)).filter(i=>i.startsWith("config-")&&i.endsWith(".json")).sort().reverse();if(s.length>50)for(let i of s.slice(50))await Z.unlink(ke.join(e,i))}catch(r){console.warn("Failed to prune config-history:",r)}},Wo=async()=>{let n=await re();return Object.assign(process.env,n),n}});function kl(n){return n?.cache_read_input_tokens??n?.input_tokens_details?.cached_tokens??n?.prompt_tokens_details?.cached_tokens??0}function bl(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 He(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:kl(n),cache_creation_input_tokens:bl(n)}}function vn(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 Go=w(()=>{"use strict"});function xn(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(Ko(r,s))}return}if(Array.isArray(n)){for(let o of n)xn(o,e,t);return}if(typeof n=="object")for(let o of Object.values(n))xn(o,e,t)}}function ui(n){let e=n?.Providers||n?.providers||[],t=new Set,o=new Set;for(let r of e){let s=r?.name;if(!s)continue;t.add(s);let i=Array.isArray(r?.models)?r.models:[];for(let l of i)l&&o.add(Ko(s,l))}return xn(n?.Router,t,o),xn(n?.fallback,t,o),o}function dt(n,e){try{let t=U();if(!t?.getAllStates||!t?.recover)return 0;let o=ui(n),r=0;for(let s of t.getAllStates()||[]){let i=s?.provider,l=s?.model;!i||!l||o.has(Ko(i,l))||(t.recover(i,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 Sn(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 Tl,Ko,Rn=w(()=>{"use strict";ne();Tl="\0",Ko=(n,e)=>`${n}${Tl}${e}`});function Cl(n){return/\[1m\]/i.test(n)?1e6:2e5}function vl(n){let e=n.toLowerCase();return e.includes("haiku")||e.includes("mini")?8192:32e3}function xl(n,e=n){let t=Cl(n),o=vl(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,xl(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 Qo=w(()=>{"use strict"});function Sl(n){let e=n.ip||n.connection?.remoteAddress||"";return e==="127.0.0.1"||e==="::1"||e==="::ffff:127.0.0.1"}var Pn,Vo=w(()=>{"use strict";Pn=n=>async(e,t,o)=>{if(["/","/health"].includes(e.url)||e.url.startsWith("/ui")||Sl(e))return o();let s=n.Providers||n.providers||[];if(!s||s.length===0)return o();let i=n.APIKEY;if(!i){let u=[`http://127.0.0.1:${n.PORT||3456}`,`http://localhost:${n.PORT||3456}`];if(e.headers.origin&&!u.includes(e.headers.origin)){t.status(403).send("CORS not allowed for this origin");return}else t.header("Access-Control-Allow-Origin",`http://127.0.0.1:${n.PORT||3456}`),t.header("Access-Control-Allow-Origin",`http://localhost:${n.PORT||3456}`);return o()}let l=e.headers.authorization||e.headers["x-api-key"],a=Array.isArray(l)?l[0]:l||"";if(!a){t.log.warn({url:e.url,headers:Object.keys(e.headers)},"[AUTH] No auth header"),t.status(401).send("APIKEY is missing");return}let c="";if(a.startsWith("Bearer")?c=a.split(" ")[1]:c=a,c!==i){t.log.warn({url:e.url,gotPrefix:c.slice(0,10),gotSuffix:c.slice(-6),gotLen:c.length,expectedPrefix:i.slice(0,6),expectedSuffix:i.slice(-6),expectedLen:i.length},"[AUTH] Key mismatch"),t.status(401).send("Invalid API key");return}o()}});var _i={};Dn(_i,{append:()=>gt,clear:()=>tr,close:()=>Gl,getOldestRecordTimestamp:()=>Kl,query:()=>er,querySummary:()=>ht,readTokenSpeedStats:()=>nr});import{existsSync as qo,mkdirSync as Rl,readFileSync as Xo,readdirSync as wl}from"fs";import{join as Je}from"path";import{homedir as Pl,tmpdir as El}from"os";import Ol from"better-sqlite3";function Nl(){qo(On)||Rl(On,{recursive:!0})}function mt(){if(me)return me;Nl();let n=new Ol(Al);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&&(Ll(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")),Fl(n),gi(n,!0),Zo=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,
|
|
@@ -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
|
-
`),
|
|
329
|
+
`),me=n,me}function Ll(n){n.exec(`
|
|
330
330
|
CREATE TABLE IF NOT EXISTS usage_records (
|
|
331
331
|
id TEXT PRIMARY KEY,
|
|
332
332
|
timestamp TEXT NOT NULL,
|
|
@@ -363,12 +363,12 @@ ${this.toMarkdown(s,t+1)}`:`${o}${r}: ${s}`).join(`
|
|
|
363
363
|
CREATE INDEX IF NOT EXISTS idx_usage_records_scenario_timestamp ON usage_records(scenario_type, timestamp);
|
|
364
364
|
CREATE INDEX IF NOT EXISTS idx_usage_records_client_timestamp ON usage_records(client_type, timestamp);
|
|
365
365
|
CREATE INDEX IF NOT EXISTS idx_usage_records_session_timestamp ON usage_records(session_id, timestamp);
|
|
366
|
-
`)}function
|
|
366
|
+
`)}function Dl(n,e){return n.prepare("SELECT value FROM usage_meta WHERE key = ?").get(e)?.value}function pt(n,e,t){n.prepare(`
|
|
367
367
|
INSERT INTO usage_meta (key, value)
|
|
368
368
|
VALUES (?, ?)
|
|
369
369
|
ON CONFLICT(key) DO UPDATE SET value = excluded.value
|
|
370
|
-
`).run(e,t)}function
|
|
371
|
-
`)){let a=l.trim();if(a)try{let c=JSON.parse(a);if(!
|
|
370
|
+
`).run(e,t)}function Fl(n){if(Dl(n,di)||!qo(Yo))return;let e=jl(n,"INSERT OR IGNORE"),t=Xo(Yo,"utf-8"),o=0,r=0,s=0;n.transaction(()=>{for(let l of t.split(`
|
|
371
|
+
`)){let a=l.trim();if(a)try{let c=JSON.parse(a);if(!Ul(c)){r++;continue}e.run(mi(An(c))).changes>0?o++:s++}catch{r++}}pt(n,di,new Date().toISOString()),pt(n,"legacy_usage_jsonl_migrated_path",Yo),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 Ul(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 jl(n,e="INSERT"){return n.prepare(`
|
|
372
372
|
${e} INTO usage_records (
|
|
373
373
|
id, timestamp, session_id, provider, original_model, model, upstream_model, model_family,
|
|
374
374
|
scenario_type, client_type,
|
|
@@ -382,11 +382,11 @@ ${this.toMarkdown(s,t+1)}`:`${o}${r}: ${s}`).join(`
|
|
|
382
382
|
@cache_read_input_tokens, @cache_creation_input_tokens, @ttft,
|
|
383
383
|
@tokens_per_second, @duration_ms, @status, @error_message, @response_body
|
|
384
384
|
)
|
|
385
|
-
`)}function
|
|
386
|
-
SELECT ${t} AS key, ${
|
|
385
|
+
`)}function Hl(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,Il);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=n.stream?be(n.ttft):null;return{...n,ttft:r,tokensPerSecond:Hl(e,o,r)}}function fe(n){return typeof n=="string"?n:n==null?"":String(n)}function En(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 fi(n){return n==="success"?"success":"error"}function mi(n){let e=An(n);return{id:fe(e.id),timestamp:fe(e.timestamp),session_id:fe(e.sessionId),provider:fe(e.provider),original_model:fe(e.originalModel),model:fe(e.model),upstream_model:En(e.upstreamModel)??null,model_family:fe(e.modelFamily),scenario_type:fe(e.scenarioType),client_type:En(e.clientType)??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:fi(e.status),error_message:En(e.errorMessage)??null,response_body:En(e.responseBody)??null}}function zl(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,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:fi(n.status),errorMessage:n.error_message??void 0,responseBody:n.response_body??void 0})}function Jl(){return new Date(Date.now()-Ml*24*60*60*1e3).toISOString()}function gi(n,e=!1){let t=Date.now();!e&&t-pi<$l||(n.prepare("DELETE FROM usage_records WHERE timestamp < ?").run(Jl()),pi=t)}function hi(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 ze(n,e,t,o=""){let r=o?e.sql?`${e.sql} AND ${o}`:`WHERE ${o}`:e.sql,s=n.prepare(`
|
|
386
|
+
SELECT ${t} AS key, ${Bl}
|
|
387
387
|
FROM usage_records ${r}
|
|
388
388
|
GROUP BY key
|
|
389
|
-
`).all(...e.params),i={};for(let l of s)l.key!=null&&(i[String(l.key)]={count:l.count,inputTokens:l.inputTokens,outputTokens:l.outputTokens,cacheReadInputTokens:l.cacheReadInputTokens,cacheCreationInputTokens:l.cacheCreationInputTokens});return i}function
|
|
389
|
+
`).all(...e.params),i={};for(let l of s)l.key!=null&&(i[String(l.key)]={count:l.count,inputTokens:l.inputTokens,outputTokens:l.outputTokens,cacheReadInputTokens:l.cacheReadInputTokens,cacheCreationInputTokens:l.cacheCreationInputTokens});return i}function yi(n,e){let t=hi(e),o=n.prepare(`
|
|
390
390
|
SELECT
|
|
391
391
|
COUNT(*) AS totalRequests,
|
|
392
392
|
COALESCE(SUM(CASE WHEN status = 'success' THEN 1 ELSE 0 END), 0) AS successCount,
|
|
@@ -397,14 +397,14 @@ ${this.toMarkdown(s,t+1)}`:`${o}${r}: ${s}`).join(`
|
|
|
397
397
|
AVG(CASE WHEN status = 'success' AND ttft IS NOT NULL THEN ttft END) AS avgTtft,
|
|
398
398
|
AVG(CASE WHEN status = 'success' AND tokens_per_second IS NOT NULL THEN tokens_per_second END) AS avgTokensPerSecond
|
|
399
399
|
FROM usage_records ${t.sql}
|
|
400
|
-
`).get(...t.params);return{totalRequests:o.totalRequests,successCount:o.successCount,errorCount:o.totalRequests-o.successCount,totalInputTokens:o.totalInputTokens,totalOutputTokens:o.totalOutputTokens,totalCacheReadInputTokens:o.totalCacheReadInputTokens,totalCacheCreationInputTokens:o.totalCacheCreationInputTokens,avgTtft:o.avgTtft!=null?Math.round(o.avgTtft):null,avgTokensPerSecond:o.avgTokensPerSecond!=null?Math.round(o.avgTokensPerSecond):null,byModel:
|
|
400
|
+
`).get(...t.params);return{totalRequests:o.totalRequests,successCount:o.successCount,errorCount:o.totalRequests-o.successCount,totalInputTokens:o.totalInputTokens,totalOutputTokens:o.totalOutputTokens,totalCacheReadInputTokens:o.totalCacheReadInputTokens,totalCacheCreationInputTokens:o.totalCacheCreationInputTokens,avgTtft:o.avgTtft!=null?Math.round(o.avgTtft):null,avgTokensPerSecond:o.avgTokensPerSecond!=null?Math.round(o.avgTokensPerSecond):null,byModel:ze(n,t,"model"),byProvider:ze(n,t,"provider"),byScenario:ze(n,t,"scenario_type"),byFamily:ze(n,t,"model_family || '/' || scenario_type","model_family IS NOT NULL AND model_family != ''"),byDay:ze(n,t,"date(timestamp, 'localtime')"),byClient:ze(n,t,"CASE WHEN client_type IS NULL OR client_type = '' THEN 'unknown' ELSE client_type END")}}function gt(n){let e=mt(),t=An(n);Zo.run(mi(t)),gi(e)}function er(n){let e=mt(),t=hi(n),o=Number.isFinite(n.page)&&n.page>0?Math.floor(n.page):1,r=Number.isFinite(n.pageSize)&&n.pageSize>0?Math.min(Math.floor(n.pageSize),Wl):50,s=(o-1)*r,i=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),a=yi(e,n);return{records:l.map(zl),summary:a,total:i.count,page:o,pageSize:r}}function ht(n,e,t){let o=mt();return yi(o,{startTime:n,endTime:e,status:t})}function tr(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 Gl(){me&&(me.pragma("wal_checkpoint(TRUNCATE)"),me.close(),me=null,Zo=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 nr(n){let e=Je(El(),"claude-code-router"),t=Je(e,`session-${n}.json`);if(qo(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=wl(e),r=new RegExp(`^session-${n}-\\d+\\.json$`),s=o.filter(i=>r.test(i));if(s.length>0){let i=s.sort().reverse(),l=Je(e,i[0]);try{let a=Xo(l,"utf-8"),c=JSON.parse(a);return{ttft:be(c.timeToFirstToken),tokensPerSecond:be(c.tokensPerSecond)}}catch{return{ttft:null,tokensPerSecond:null}}}}catch{}return{ttft:null,tokensPerSecond:null}}function Kl(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 On,Al,Yo,Il,Ml,$l,di,me,Zo,pi,Bl,Wl,yt=w(()=>{"use strict";On=Je(Pl(),".claude-code-router","data"),Al=Je(On,"usage.sqlite"),Yo=Je(On,"usage.jsonl"),Il=1,Ml=180,$l=3600*1e3,di="legacy_usage_jsonl_migrated_at",me=null,Zo=null,pi=0;Bl=`
|
|
401
401
|
COUNT(*) AS count,
|
|
402
402
|
COALESCE(SUM(CASE WHEN status = 'success' THEN input_tokens ELSE 0 END), 0) AS inputTokens,
|
|
403
403
|
COALESCE(SUM(CASE WHEN status = 'success' THEN output_tokens ELSE 0 END), 0) AS outputTokens,
|
|
404
404
|
COALESCE(SUM(CASE WHEN status = 'success' THEN cache_read_input_tokens ELSE 0 END), 0) AS cacheReadInputTokens,
|
|
405
405
|
COALESCE(SUM(CASE WHEN status = 'success' THEN cache_creation_input_tokens ELSE 0 END), 0) AS cacheCreationInputTokens
|
|
406
|
-
`;Hl=200});import{existsSync as Jl}from"fs";import{homedir as Wl}from"os";import{join as Gl}from"path";import{writeFile as Kl}from"fs/promises";async function hi(){let n=Wl(),e=Gl(n,".claude.json");if(!Jl(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 Kl(e,JSON.stringify(o,null,2))}}var yi=w(()=>{"use strict"});import{existsSync as Ql,readdirSync as Vl,statSync as Yl,unlinkSync as Xl}from"fs";import{join as _i}from"path";import{HOME_DIR as ql}from"@wengine-ai/claude-code-router-shared";function bi(n=_i(ql,"logs")){try{if(!Ql(n))return;let e=Date.now()-eu;for(let t of Vl(n)){if(!/^ccr-.*\.log$/.test(t))continue;let o=_i(n,t),r=Yl(o);r.isFile()&&r.mtime.getTime()<e&&Xl(o)}}catch(e){console.warn("Failed to prune old server log files:",e)}}function Ti(){ki||(ki=!0,bi(),setInterval(bi,tu).unref())}var Zl,eu,tu,ki,Ci=w(()=>{"use strict";Zl=7,eu=Zl*24*60*60*1e3,tu=1440*60*1e3,ki=!1});async function vi(n,e){let t=e.plugins||e.Plugins||[];for(let o of t){let{name:r,enabled:s=!1,options:i={}}=o;switch(r){case"token-speed":nt.registerPlugin(hn,{enabled:s,outputHandlers:[{type:"temp-file",enabled:!0,config:{subdirectory:"claude-code-router",extension:"json",includeTimestamp:!0,prefix:"session"}}],...i});break;default:console.warn(`Unknown plugin: ${r}`);break}}await nt.enablePlugins(n)}var xi=w(()=>{"use strict";jo()});import{join as oe,isAbsolute as nu,normalize as ou,dirname as ru}from"path";import{fileURLToPath as su}from"url";import iu from"@fastify/static";import{readdirSync as Si,statSync as au,readFileSync as Ri,writeFileSync as cu,existsSync as le,unlinkSync as wi,rmSync as lu}from"fs";import{homedir as tr}from"os";import{getPresetDir as On,readManifestFromDir as nr,manifestToPresetFile as Pi,saveManifest as Ei,isPresetInstalled as Oi,extractPreset as uu,HOME_DIR as du,loadConfigFromManifest as pu,downloadPresetToTemp as fu,findMarketPresetByName as mu,getMarketPresets as gu,applyClientSelection as hu,disableClient as yu,enableClient as _u,isClientId as ku,listClientStatuses as Ai,restoreClient as bu,listProjectConfigs as Tu,readProjectConfigById as or,readProjectConfig as Cu,writeProjectConfig as Ii,deleteProjectConfig as vu,getClaudeProjectId as xu,getProjectConfigPath as Su,refreshCcrProjectTakeover as Ru,refreshProjectTakeovers as wu,syncGlobalProjectTakeovers as Pu,getProjectTakeoverClients as rr,setProjectTakeover as sr,isProjectTakeoverClient as Eu}from"@wengine-ai/claude-code-router-shared";import Ou from"@fastify/multipart";import Au from"adm-zip";function Iu(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=mt(t,e),s=mt(o,e),i=[],l=new Set;for(let a of n||[])a&&a.name&&l.add(a.name);for(let a of Object.keys(r.byProvider||{}))l.add(a);for(let a of Object.keys(s.byProvider||{}))l.add(a);for(let a of l){let c=r.byProvider[a]||{inputTokens:0,outputTokens:0},u=s.byProvider[a]||{inputTokens:0,outputTokens:0},d=(c.inputTokens||0)+(c.outputTokens||0),g=(u.inputTokens||0)+(u.outputTokens||0),m,y,p=(n||[]).find(f=>f&&f.name===a);p&&p.quota&&(m=p.quota.limit5h,y=p.quota.limit7d),i.push({provider:a,used5h:d,used7d:g,limit5h:m,limit7d:y})}return i}async function Mi(n,e){let t=n.app;Ge(),Ke(),t.register(Ou,{limits:{fileSize:50*1024*1024}}),t.get("/v1/models",async()=>{let l=Sn(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,a)=>{let c=decodeURIComponent(l.params.modelId),u=Sn(e).find(d=>d.id===c);return u||(a.status(404),{type:"error",error:{type:"not_found_error",message:`Model not found: ${c}`}})}),t.post("/v1/messages/count_tokens",async(l,a)=>{let{messages:c,tools:u,system:d,model:g}=l.body,m=t._server.tokenizerService;if(g&&g.includes(",")&&m)try{let[p,f]=g.split(",");l.log?.info(`Looking up tokenizer for provider: ${p}, model: ${f}`);let _=m.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 m.countTokens({messages:c,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 g?g.includes(",")?m||l.log?.warn("TokenizerService not available, using default tiktoken"):l.log?.info(`Model "${g}" does not contain comma, using default tiktoken`):l.log?.info("No model specified, using default tiktoken");return{input_tokens:Ot(c,d,u)}}),t.get("/api/config",async(l,a)=>await zo()),t.get("/api/transformers",async(l,a)=>{let c=t._server.transformerService.getAllTransformers();return{transformers:Array.from(c.entries()).map(([d,g])=>({name:d,endpoint:g.endPoint||null}))}}),t.post("/api/config",async(l,a)=>{let c=l.body,u=pr(c||{});if(u.length>0)return a.status(400),{success:!1,error:"Invalid proxy URL",message:u.map(m=>`${m.key}: ${m.error}`).join("; "),proxyErrors:u};let d=await kn();d&&console.log(`Backed up existing configuration file to ${d}`),await Fe(c);let g;try{g=await Pu(c),g.failed.length>0&&t.log?.warn?.({projectTakeoverSync:g},"Config saved but some global project takeovers failed to sync")}catch(m){t.log?.warn?.(`Config saved but global project takeover sync failed: ${m?.message||m}`)}try{let m=t._server;if(m?.configService){m.configService.reload();let y=c?.Providers||c?.providers;if(Array.isArray(y)&&m.configService.set("providers",y),ce&&m.transformerService&&(m.providerService=new ce(m.configService,m.transformerService,t.log)),lt(c,t.log),Ne&&fn){try{fn()}catch{}let p={enabled:m.configService.get("ACTIVE_PROBE_ENABLED")??!0,quotaProbeIntervalMinutes:m.configService.get("QUOTA_PROBE_INTERVAL_MINUTES")??10,probeTimeoutMs:m.configService.get("PROBE_TIMEOUT_MS")??15e3,slowThresholdMs:Number(m.configService.get("PROBE_SLOW_THRESHOLD_MS"))||3e3,initialDelayMs:m.configService.get("PROBE_INITIAL_DELAY_MS")??5e3,excludeProviders:m.configService.get("EXCLUDE_PROBE_PROVIDERS")??[]};m.activeProbeService=Ne(()=>m.providerService.getProviders(),p,f=>se(m.configService,f),t.log,f=>m.configService.get(f))}}}catch(m){t.log?.warn?.(`Config saved but runtime reload failed: ${m?.message||m}`)}return{success:!0,message:"Config saved successfully",projectTakeoverSync:g}}),t.get("/api/clients",async(l,a)=>{try{let c=await ne();return{clients:Ai(c)}}catch(c){console.error("Failed to get client integrations:",c),a.status(500).send({error:c.message||"Failed to get client integrations"})}}),t.post("/api/clients/apply",async(l,a)=>{try{let c=l.body,u=Array.isArray(c?.enabled)?c.enabled:[],d=await ne(),g=hu(d,u);return await Fe(g.config),g}catch(c){console.error("Failed to apply client integrations:",c),a.status(500).send({error:c.message||"Failed to apply client integrations"})}});async function o(l,a,c){try{let{id:u}=l.params;if(!ku(u)){a.status(404).send({error:`Unknown client: ${u}`});return}let d=await ne(),g=c==="enable"?_u(d,u):c==="restore"?bu(d,u):yu(d,u);return await Fe(d),{success:g.success,result:g,results:[g],clients:Ai(d),config:d}}catch(u){console.error(`Failed to ${c} client integration:`,u),a.status(500).send({error:u.message||`Failed to ${c} client integration`})}}t.post("/api/clients/:id/enable",async(l,a)=>o(l,a,"enable")),t.post("/api/clients/:id/disable",async(l,a)=>o(l,a,"disable")),t.post("/api/clients/:id/restore",async(l,a)=>o(l,a,"restore")),t.get("/api/projects",async(l,a)=>{try{let c=await Tu();return{projects:await Promise.all(c.map(async d=>{let g=await rr(d.path);return{...d,ccrTakeoverClients:g,ccrTakeover:g.length>0}}))}}catch(c){console.error("Failed to list project configs:",c),a.status(500).send({error:c.message||"Failed to list project configs"})}}),t.post("/api/projects",async(l,a)=>{try{let{path:c}=l.body||{};if(!c||typeof c!="string"||!nu(c)){a.status(400).send({error:"A valid absolute project path is required"});return}let u=ou(c).replace(/[\\/]+$/,"")||c;if(await Cu(u)){a.status(409).send({error:"Project is already configured"});return}await Ii(u,{Router:{}});try{let m=await ne();await sr(u,["claudeCode"],m)}catch(m){console.error("Failed to auto-enable ccr takeover for new project:",m)}let g=await rr(u);return{id:xu(u),path:u,configPath:Su(u),Router:{},ccrTakeoverClients:g,ccrTakeover:g.length>0}}catch(c){console.error("Failed to add project config:",c),a.status(500).send({error:c.message||"Failed to add project config"})}}),t.put("/api/projects/:id",async(l,a)=>{try{let{id:c}=l.params,{Router:u}=l.body||{};if(!u||typeof u!="object"){a.status(400).send({error:"Router must be an object"});return}let d=await or(c);if(!d){a.status(404).send({error:"Project config not found"});return}await Ii(d.path,{Router:u});let g=await ne();Object.keys(u).length===0?await wu(d.path,g):await Ru(d.path,g,u);let m=await rr(d.path);return{id:c,path:d.path,configPath:d.configPath,Router:u,ccrTakeoverClients:m,ccrTakeover:m.length>0}}catch(c){console.error("Failed to update project config:",c),a.status(500).send({error:c.message||"Failed to update project config"})}}),t.put("/api/projects/:id/takeover",async(l,a)=>{try{let{id:c}=l.params,u=l.body||{},d;if(Array.isArray(u.clients))d=u.clients.filter(Eu);else if(typeof u.enabled=="boolean")d=u.enabled?["claudeCode"]:[];else{a.status(400).send({error:"clients (array) or enabled (boolean) is required"});return}let g=await or(c);if(!g){a.status(404).send({error:"Project config not found"});return}let m=await ne(),y=await sr(g.path,d,m);return{id:c,path:g.path,ccrTakeoverClients:y,ccrTakeover:y.length>0}}catch(c){console.error("Failed to update ccr takeover status:",c),a.status(500).send({error:c.message||"Failed to update ccr takeover status"})}}),t.delete("/api/projects/:id",async(l,a)=>{try{let{id:c}=l.params,u=await or(c);if(!u){a.status(404).send({error:"Project config not found"});return}try{let d=await ne();await sr(u.path,[],d)}catch(d){console.error("Failed to remove ccr takeover while deleting project:",d)}return await vu(u.path),{success:!0}}catch(c){console.error("Failed to delete project config:",c),a.status(500).send({error:c.message||"Failed to delete project config"})}});let r=typeof __dirname=="string"?__dirname:ru(su(import.meta.url)),s=le(oe(r,"index.html"))?r:le(oe(r,"..","index.html"))?oe(r,".."):oe(r,"..","dist");t.register(iu,{root:s,prefix:"/ui/",maxAge:"1h"}),t.get("/ui",async(l,a)=>a.redirect("/ui/")),t.get("/api/logs/files",async(l,a)=>{try{let c=oe(tr(),".claude-code-router","logs"),u=[];if(le(c)){let d=Si(c);for(let g of d)if(g.endsWith(".log")){let m=oe(c,g),y=au(m);u.push({name:g,path:m,size:y.size,lastModified:y.mtime.toISOString()})}u.sort((g,m)=>new Date(m.lastModified).getTime()-new Date(g.lastModified).getTime())}return u}catch(c){console.error("Failed to get log files:",c),a.status(500).send({error:"Failed to get log files"})}}),t.get("/api/logs",async(l,a)=>{try{let c=l.query.file,u;return c?u=c:u=oe(tr(),".claude-code-router","logs","app.log"),le(u)?Ri(u,"utf8").split(`
|
|
407
|
-
`).filter(m=>m.trim()):[]}catch(c){console.error("Failed to get logs:",c),a.status(500).send({error:"Failed to get logs"})}}),t.delete("/api/logs",async(l,a)=>{try{let c=l.query.file,u;return c?u=c:u=oe(tr(),".claude-code-router","logs","app.log"),le(u)&&cu(u,"","utf8"),{success:!0,message:"Logs cleared successfully"}}catch(c){console.error("Failed to clear logs:",c),a.status(500).send({error:"Failed to clear logs"})}}),t.get("/api/debug-log",async()=>({enabled:kt()})),t.put("/api/debug-log",async l=>{let{enabled:a}=l.body;return Un(a),{enabled:kt()}}),t.get("/api/usage",async(l,a)=>{try{let c=l.query;return qo({startTime:c.startDate,endTime:c.endDate,model:c.model,provider:c.provider,scenario:c.scenario,clientType:c.clientType,sessionId:c.sessionId,status:c.status,page:c.page?parseInt(c.page,10):void 0,pageSize:c.pageSize?parseInt(c.pageSize,10):void 0})}catch(c){console.error("Failed to query usage:",c),a.status(500).send({error:"Failed to query usage"})}}),t.get("/api/usage/summary",async(l,a)=>{try{let c=l.query;return mt(c.startDate,c.endDate,c.status)}catch(c){console.error("Failed to query usage summary:",c),a.status(500).send({error:"Failed to query usage summary"})}}),t.delete("/api/usage",async(l,a)=>{try{let c=l.query;return Zo(c.beforeDate),{success:!0,message:c.beforeDate?"Usage data cleared before "+c.beforeDate:"All usage data cleared"}}catch(c){console.error("Failed to clear usage:",c),a.status(500).send({error:"Failed to clear usage data"})}}),t.get("/api/providers/health",async(l,a)=>{try{let u=F().getAllStates(),g=t._server?.activeProbeService?.getProbeTelemetry?.()||[];return{states:u.map(m=>({provider:m.provider,model:m.model,status:m.status,failureCount:m.failureCount,successCount:m.successCount,lastFailureTime:m.lastFailureTime,lastError:m.lastError,rateLimitUntil:m.rateLimitUntil??null})),probes:g,timestamp:new Date().toISOString()}}catch(c){console.error("Failed to get provider health:",c),a.status(500).send({error:"Failed to get provider health"})}}),t.post("/api/providers/probe",async(l,a)=>{try{let{providerName:c}=l.body;if(!c)return a.status(400),{error:"providerName is required"};let d=t._server?.activeProbeService;if(!d?.probeProviderManually)return a.status(503),{error:"Active probe service is not available"};let g=await d.probeProviderManually(c);return g.success&&vn(c,l.log),{provider:c,success:g.success,latencyMs:g.latencyMs,status:g.status,isSlow:g.isSlow,errorKind:g.errorKind??null,error:g.error,timestamp:new Date().toISOString()}}catch(c){console.error("Failed to probe provider:",c),a.status(500).send({error:c.message||"Failed to probe provider"})}}),t.post("/api/providers/probe-all",async(l,a)=>{try{let c=t._server,u=c?.activeProbeService;if(!u?.probeProviderManually)return a.status(503),{error:"Active probe service is not available"};let d=(c?.providerService?.getProviders?.()||[]).filter(m=>m?.name&&m.enabled!==!1),g=await Promise.all(d.map(async m=>{let y=await u.probeProviderManually(m.name);return y.success&&vn(m.name,l?.log),{provider:m.name,success:y.success,latencyMs:y.latencyMs,status:y.status,isSlow:y.isSlow,errorKind:y.errorKind??null,error:y.error}}));return{results:g,successCount:g.filter(m=>m.success).length,total:g.length,timestamp:new Date().toISOString()}}catch(c){console.error("Failed to probe all providers:",c),a.status(500).send({error:c.message||"Failed to probe all providers"})}}),t.get("/api/providers/quota",async(l,a)=>{try{let u=(await ne()).Providers||[],d=Iu(u),g=new Map(d.map(p=>[p.provider,p])),m=Vn();for(let p of d){let f=m.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=to();for(let p of y){let f=g.get(p.provider);f||(f={provider:p.provider,used5h:0,used7d:0},d.push(f),g.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(c){console.error("Failed to compute provider quota:",c),a.status(500).send({error:"Failed to compute provider quota"})}}),t.get("/api/presets",async(l,a)=>{try{let c=oe(du,"presets");if(!le(c))return{presets:[]};let d=Si(c,{withFileTypes:!0}).filter(m=>m.isDirectory()&&!m.name.startsWith(".")).map(m=>m.name),g=[];for(let m of d){let y=oe(c,m);try{let p=oe(y,"manifest.json"),f=Ri(p,"utf-8"),_=JSON.parse(f),{Providers:k,Router:h,PORT:b,HOST:T,API_TIMEOUT_MS:x,PROXY_URL:v,PROXY_GLOBAL_ENABLED:S,LOG:C,LOG_LEVEL:P,StatusLine:R,NON_INTERACTIVE_MODE:O,...E}=_;g.push({id:m,name:E.name||m,version:E.version||"1.0.0",description:E.description,author:E.author,homepage:E.homepage,repository:E.repository,license:E.license,keywords:E.keywords,ccrVersion:E.ccrVersion,source:E.source,sourceType:E.sourceType,checksum:E.checksum,installed:!0})}catch(p){console.error(`Failed to read preset ${m}:`,p)}}return{presets:g}}catch(c){console.error("Failed to get presets:",c),a.status(500).send({error:"Failed to get presets"})}}),t.get("/api/presets/:name",async(l,a)=>{try{let{name:c}=l.params,u=On(c);if(!le(u)){a.status(404).send({error:"Preset not found"});return}let d=await nr(u);return{...Pi(d),config:pu(d,u),userValues:d.userValues||{}}}catch(c){console.error("Failed to get preset:",c),a.status(500).send({error:c.message||"Failed to get preset"})}}),t.post("/api/presets/:name/apply",async(l,a)=>{try{let{name:c}=l.params,{secrets:u}=l.body,d=On(c);if(!le(d)){a.status(404).send({error:"Preset not found"});return}let m={...await nr(d)};return u&&Object.keys(u).length>0&&(m.userValues={...m.userValues,...u}),await Ei(c,m),{success:!0,message:"Preset applied successfully"}}catch(c){console.error("Failed to apply preset:",c),a.status(500).send({error:c.message||"Failed to apply preset"})}}),t.delete("/api/presets/:name",async(l,a)=>{try{let{name:c}=l.params,u=On(c);if(!le(u)){a.status(404).send({error:"Preset not found"});return}return lu(u,{recursive:!0,force:!0}),{success:!0,message:"Preset deleted successfully"}}catch(c){console.error("Failed to delete preset:",c),a.status(500).send({error:c.message||"Failed to delete preset"})}}),t.get("/api/presets/market",async(l,a)=>{try{return{presets:await gu()}}catch(c){console.error("Failed to get market presets:",c),a.status(500).send({error:c.message||"Failed to get market presets"})}}),t.post("/api/presets/install/github",async(l,a)=>{try{let{presetName:c}=l.body;if(!c){a.status(400).send({error:"Preset name is required"});return}let u=await mu(c);if(!u){a.status(400).send({error:"Preset not found in marketplace",message:`Preset '${c}' is not available in the official marketplace. Please check the available presets.`});return}if(!u.repo){a.status(400).send({error:"Invalid preset data",message:`Preset '${c}' does not have repository information`});return}let d=u.repo.match(/(?:github\.com[:/]|^)([^/]+)\/([^/\s#]+?)(?:\.git)?$/);if(!d){a.status(400).send({error:"Invalid GitHub repository URL"});return}let[,g,m]=d,y=u.name||c;if(await Oi(y)){a.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/${g}/${m}/archive/refs/heads/main.zip`,f=await fu(p),_=await i(f);if(await Oi(y)){wi(f),a.status(409).send({error:"Preset already installed",message:`Preset '${y}' was installed while downloading. Please try again.`,presetName:y});return}let k=On(y);await uu(f,k);let h=await nr(k);return h.repository=u.repo,u.url&&(h.source=u.url),await Ei(y,h),wi(f),{success:!0,presetName:y,preset:{..._.metadata,installed:!0}}}catch(c){console.error("Failed to install preset from GitHub:",c),a.status(500).send({error:c.message||"Failed to install preset from GitHub"})}});async function i(l){let a=new Au(l),c=a.getEntry("manifest.json");if(c||(c=a.getEntries().find(g=>g.entryName.includes("manifest.json"))||null),!c)throw new Error("Invalid preset file: manifest.json not found");let u=JSON.parse(c.getData().toString("utf-8"));return Pi(u)}return n}var $i=w(()=>{"use strict";Ae();ve();Re();$t();mn();Z();Je();ee();xn();bn();gt();Go()});function Mu(n,e){let t=n?.Router,{family:o}=qe(e||"");if(t?.enableFamilyRouting&&o){let r=t.families?.[o]?.image;if(r)return r}return t?.image}function Ni(n){return n?.Router?.image}function $u(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")))}function Nu(n){let e=n[n.length-1];if(e?.role!=="user"||!Array.isArray(e.content))return;let t=[];e.content.filter(o=>o.type==="tool_result").forEach(o=>{if(!Array.isArray(o.content))return;let r=o.content.filter(s=>s.type==="image"?(t.push(s),!1):!0);r.length!==o.content.length&&(o.content=r.length>0?r:"read image successfully")}),e.content.push(...t)}var ir,An,ar,Li,Di=w(()=>{"use strict";Ae();ir=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}},An=new ir;ar=class{name="image";tools;constructor(){this.tools=new Map,this.appendTools()}shouldHandle(e,t){let o=Mu(t,e.originalModel||e.body.model);if(!o||e.body.model===o||!$u(e.body.messages))return!1;let s=t.forceUseImageAgent===!0;return!s&&ro(e.body.model)?!1:(Nu(e.body.messages),s&&!!Ni(t))}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 a=An.getImage(`${t.req.id}_Image#${l}`);a&&o.push({type:"image",source:a})});else{let l=An.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(a=>a.type==="text"&&!a.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 i=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:Ni(t.config),system:[{type:"text",text:`You must interpret and analyze images strictly according to the assigned task.
|
|
406
|
+
`;Wl=200});import{existsSync as Ql}from"fs";import{homedir as Vl}from"os";import{join as Yl}from"path";import{writeFile as Xl}from"fs/promises";async function ki(){let n=Vl(),e=Yl(n,".claude.json");if(!Ql(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 Xl(e,JSON.stringify(o,null,2))}}var bi=w(()=>{"use strict"});import{existsSync as ql,readdirSync as Zl,statSync as eu,unlinkSync as tu}from"fs";import{join as Ti}from"path";import{HOME_DIR as nu}from"@wengine-ai/claude-code-router-shared";function vi(n=Ti(nu,"logs")){try{if(!ql(n))return;let e=Date.now()-ru;for(let t of Zl(n)){if(!/^ccr-.*\.log$/.test(t))continue;let o=Ti(n,t),r=eu(o);r.isFile()&&r.mtime.getTime()<e&&tu(o)}}catch(e){console.warn("Failed to prune old server log files:",e)}}function xi(){Ci||(Ci=!0,vi(),setInterval(vi,su).unref())}var ou,ru,su,Ci,Si=w(()=>{"use strict";ou=7,ru=ou*24*60*60*1e3,su=1440*60*1e3,Ci=!1});async function Ri(n,e){let t=e.plugins||e.Plugins||[];for(let o of t){let{name:r,enabled:s=!1,options:i={}}=o;switch(r){case"token-speed":rt.registerPlugin(_n,{enabled:s,outputHandlers:[{type:"temp-file",enabled:!0,config:{subdirectory:"claude-code-router",extension:"json",includeTimestamp:!0,prefix:"session"}}],...i});break;default:console.warn(`Unknown plugin: ${r}`);break}}await rt.enablePlugins(n)}var wi=w(()=>{"use strict";zo()});import{join as se,isAbsolute as iu,normalize as au,dirname as cu}from"path";import{fileURLToPath as lu}from"url";import uu from"@fastify/static";import{readdirSync as Pi,statSync as du,readFileSync as Ei,writeFileSync as pu,existsSync as de,unlinkSync as Oi,rmSync as fu}from"fs";import{homedir as or}from"os";import{getPresetDir as In,readManifestFromDir as rr,manifestToPresetFile as Ai,saveManifest as Ii,isPresetInstalled as Mi,extractPreset as mu,HOME_DIR as gu,loadConfigFromManifest as hu,downloadPresetToTemp as yu,findMarketPresetByName as _u,getMarketPresets as ku,applyClientSelection as bu,disableClient as Tu,enableClient as Cu,isClientId as vu,listClientStatuses as $i,restoreClient as xu,listProjectConfigs as Su,readProjectConfigById as sr,readProjectConfig as Ru,writeProjectConfig as Ni,deleteProjectConfig as wu,getClaudeProjectId as Pu,getProjectConfigPath as Eu,refreshCcrProjectTakeover as Ou,refreshProjectTakeovers as Au,syncGlobalProjectTakeovers as Iu,getProjectTakeoverClients as ir,setProjectTakeover as ar,isProjectTakeoverClient as Mu}from"@wengine-ai/claude-code-router-shared";import $u from"@fastify/multipart";import Nu from"adm-zip";function Lu(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),i=[],l=new Set;for(let a of n||[])a&&a.name&&l.add(a.name);for(let a of Object.keys(r.byProvider||{}))l.add(a);for(let a of Object.keys(s.byProvider||{}))l.add(a);for(let a of l){let c=r.byProvider[a]||{inputTokens:0,outputTokens:0},u=s.byProvider[a]||{inputTokens:0,outputTokens:0},d=(c.inputTokens||0)+(c.outputTokens||0),g=(u.inputTokens||0)+(u.outputTokens||0),f,y,p=(n||[]).find(m=>m&&m.name===a);p&&p.quota&&(f=p.quota.limit5h,y=p.quota.limit7d),i.push({provider:a,used5h:d,used7d:g,limit5h:f,limit7d:y})}return i}async function Li(n,e){let t=n.app;Qe(),Ve(),t.register($u,{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,a)=>{let c=decodeURIComponent(l.params.modelId),u=wn(e).find(d=>d.id===c);return u||(a.status(404),{type:"error",error:{type:"not_found_error",message:`Model not found: ${c}`}})}),t.post("/v1/messages/count_tokens",async(l,a)=>{let{messages:c,tools:u,system:d,model:g}=l.body,f=t._server.tokenizerService;if(g&&g.includes(",")&&f)try{let[p,m]=g.split(",");l.log?.info(`Looking up tokenizer for provider: ${p}, model: ${m}`);let _=f.getTokenizerConfigForModel(p,m);_?l.log?.info(`Using tokenizer config: ${JSON.stringify(_)}`):l.log?.warn(`No tokenizer config found for ${p},${m}, using default tiktoken`);let k=await f.countTokens({messages:c,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 g?g.includes(",")?f||l.log?.warn("TokenizerService not available, using default tiktoken"):l.log?.info(`Model "${g}" does not contain comma, using default tiktoken`):l.log?.info("No model specified, using default tiktoken");return{input_tokens:It(c,d,u)}}),t.get("/api/config",async(l,a)=>await Bo()),t.get("/api/transformers",async(l,a)=>{let c=t._server.transformerService.getAllTransformers();return{transformers:Array.from(c.entries()).map(([d,g])=>({name:d,endpoint:g.endPoint||null}))}}),t.post("/api/config",async(l,a)=>{let c=l.body,u=mr(c||{});if(u.length>0)return a.status(400),{success:!1,error:"Invalid proxy URL",message:u.map(f=>`${f.key}: ${f.error}`).join("; "),proxyErrors:u};let d=await Tn();d&&console.log(`Backed up existing configuration file to ${d}`),await je(c);let g;try{g=await Iu(c),g.failed.length>0&&t.log?.warn?.({projectTakeoverSync:g},"Config saved but some global project takeovers failed to sync")}catch(f){t.log?.warn?.(`Config saved but global project takeover sync failed: ${f?.message||f}`)}try{let f=t._server;if(f?.configService){f.configService.reload();let y=c?.Providers||c?.providers;if(Array.isArray(y)&&f.configService.set("providers",y),ue&&f.transformerService&&(f.providerService=new ue(f.configService,f.transformerService,t.log)),dt(c,t.log),De&&gn){try{gn()}catch{}let p={enabled:f.configService.get("ACTIVE_PROBE_ENABLED")??!0,quotaProbeIntervalMinutes:f.configService.get("QUOTA_PROBE_INTERVAL_MINUTES")??10,probeTimeoutMs:f.configService.get("PROBE_TIMEOUT_MS")??15e3,slowThresholdMs:Number(f.configService.get("PROBE_SLOW_THRESHOLD_MS"))||3e3,initialDelayMs:f.configService.get("PROBE_INITIAL_DELAY_MS")??5e3,excludeProviders:f.configService.get("EXCLUDE_PROBE_PROVIDERS")??[]};f.activeProbeService=De(()=>f.providerService.getProviders(),p,m=>ae(f.configService,m),t.log,m=>f.configService.get(m))}}}catch(f){t.log?.warn?.(`Config saved but runtime reload failed: ${f?.message||f}`)}return{success:!0,message:"Config saved successfully",projectTakeoverSync:g}}),t.get("/api/clients",async(l,a)=>{try{let c=await re();return{clients:$i(c)}}catch(c){console.error("Failed to get client integrations:",c),a.status(500).send({error:c.message||"Failed to get client integrations"})}}),t.post("/api/clients/apply",async(l,a)=>{try{let c=l.body,u=Array.isArray(c?.enabled)?c.enabled:[],d=await re(),g=bu(d,u);return await je(g.config),g}catch(c){console.error("Failed to apply client integrations:",c),a.status(500).send({error:c.message||"Failed to apply client integrations"})}});async function o(l,a,c){try{let{id:u}=l.params;if(!vu(u)){a.status(404).send({error:`Unknown client: ${u}`});return}let d=await re(),g=c==="enable"?Cu(d,u):c==="restore"?xu(d,u):Tu(d,u);return await je(d),{success:g.success,result:g,results:[g],clients:$i(d),config:d}}catch(u){console.error(`Failed to ${c} client integration:`,u),a.status(500).send({error:u.message||`Failed to ${c} client integration`})}}t.post("/api/clients/:id/enable",async(l,a)=>o(l,a,"enable")),t.post("/api/clients/:id/disable",async(l,a)=>o(l,a,"disable")),t.post("/api/clients/:id/restore",async(l,a)=>o(l,a,"restore")),t.get("/api/projects",async(l,a)=>{try{let c=await Su();return{projects:await Promise.all(c.map(async d=>{let g=await ir(d.path);return{...d,ccrTakeoverClients:g,ccrTakeover:g.length>0}}))}}catch(c){console.error("Failed to list project configs:",c),a.status(500).send({error:c.message||"Failed to list project configs"})}}),t.post("/api/projects",async(l,a)=>{try{let{path:c}=l.body||{};if(!c||typeof c!="string"||!iu(c)){a.status(400).send({error:"A valid absolute project path is required"});return}let u=au(c).replace(/[\\/]+$/,"")||c;if(await Ru(u)){a.status(409).send({error:"Project is already configured"});return}await Ni(u,{Router:{}});try{let f=await re();await ar(u,["claudeCode"],f)}catch(f){console.error("Failed to auto-enable ccr takeover for new project:",f)}let g=await ir(u);return{id:Pu(u),path:u,configPath:Eu(u),Router:{},ccrTakeoverClients:g,ccrTakeover:g.length>0}}catch(c){console.error("Failed to add project config:",c),a.status(500).send({error:c.message||"Failed to add project config"})}}),t.put("/api/projects/:id",async(l,a)=>{try{let{id:c}=l.params,{Router:u}=l.body||{};if(!u||typeof u!="object"){a.status(400).send({error:"Router must be an object"});return}let d=await sr(c);if(!d){a.status(404).send({error:"Project config not found"});return}await Ni(d.path,{Router:u});let g=await re();Object.keys(u).length===0?await Au(d.path,g):await Ou(d.path,g,u);let f=await ir(d.path);return{id:c,path:d.path,configPath:d.configPath,Router:u,ccrTakeoverClients:f,ccrTakeover:f.length>0}}catch(c){console.error("Failed to update project config:",c),a.status(500).send({error:c.message||"Failed to update project config"})}}),t.put("/api/projects/:id/takeover",async(l,a)=>{try{let{id:c}=l.params,u=l.body||{},d;if(Array.isArray(u.clients))d=u.clients.filter(Mu);else if(typeof u.enabled=="boolean")d=u.enabled?["claudeCode"]:[];else{a.status(400).send({error:"clients (array) or enabled (boolean) is required"});return}let g=await sr(c);if(!g){a.status(404).send({error:"Project config not found"});return}let f=await re(),y=await ar(g.path,d,f);return{id:c,path:g.path,ccrTakeoverClients:y,ccrTakeover:y.length>0}}catch(c){console.error("Failed to update ccr takeover status:",c),a.status(500).send({error:c.message||"Failed to update ccr takeover status"})}}),t.delete("/api/projects/:id",async(l,a)=>{try{let{id:c}=l.params,u=await sr(c);if(!u){a.status(404).send({error:"Project config not found"});return}try{let d=await re();await ar(u.path,[],d)}catch(d){console.error("Failed to remove ccr takeover while deleting project:",d)}return await wu(u.path),{success:!0}}catch(c){console.error("Failed to delete project config:",c),a.status(500).send({error:c.message||"Failed to delete project config"})}});let r=typeof __dirname=="string"?__dirname:cu(lu(import.meta.url)),s=de(se(r,"index.html"))?r:de(se(r,"..","index.html"))?se(r,".."):se(r,"..","dist");t.register(uu,{root:s,prefix:"/ui/",maxAge:"1h"}),t.get("/ui",async(l,a)=>a.redirect("/ui/")),t.get("/api/logs/files",async(l,a)=>{try{let c=se(or(),".claude-code-router","logs"),u=[];if(de(c)){let d=Pi(c);for(let g of d)if(g.endsWith(".log")){let f=se(c,g),y=du(f);u.push({name:g,path:f,size:y.size,lastModified:y.mtime.toISOString()})}u.sort((g,f)=>new Date(f.lastModified).getTime()-new Date(g.lastModified).getTime())}return u}catch(c){console.error("Failed to get log files:",c),a.status(500).send({error:"Failed to get log files"})}}),t.get("/api/logs",async(l,a)=>{try{let c=l.query.file,u;return c?u=c:u=se(or(),".claude-code-router","logs","app.log"),de(u)?Ei(u,"utf8").split(`
|
|
407
|
+
`).filter(f=>f.trim()):[]}catch(c){console.error("Failed to get logs:",c),a.status(500).send({error:"Failed to get logs"})}}),t.delete("/api/logs",async(l,a)=>{try{let c=l.query.file,u;return c?u=c:u=se(or(),".claude-code-router","logs","app.log"),de(u)&&pu(u,"","utf8"),{success:!0,message:"Logs cleared successfully"}}catch(c){console.error("Failed to clear logs:",c),a.status(500).send({error:"Failed to clear logs"})}}),t.get("/api/debug-log",async()=>({enabled:Tt()})),t.put("/api/debug-log",async l=>{let{enabled:a}=l.body;return Hn(a),{enabled:Tt()}}),t.get("/api/usage",async(l,a)=>{try{let c=l.query;return er({startTime:c.startDate,endTime:c.endDate,model:c.model,provider:c.provider,scenario:c.scenario,clientType:c.clientType,sessionId:c.sessionId,status:c.status,page:c.page?parseInt(c.page,10):void 0,pageSize:c.pageSize?parseInt(c.pageSize,10):void 0})}catch(c){console.error("Failed to query usage:",c),a.status(500).send({error:"Failed to query usage"})}}),t.get("/api/usage/summary",async(l,a)=>{try{let c=l.query;return ht(c.startDate,c.endDate,c.status)}catch(c){console.error("Failed to query usage summary:",c),a.status(500).send({error:"Failed to query usage summary"})}}),t.delete("/api/usage",async(l,a)=>{try{let c=l.query;return tr(c.beforeDate),{success:!0,message:c.beforeDate?"Usage data cleared before "+c.beforeDate:"All usage data cleared"}}catch(c){console.error("Failed to clear usage:",c),a.status(500).send({error:"Failed to clear usage data"})}}),t.get("/api/providers/health",async(l,a)=>{try{let u=U().getAllStates(),g=t._server?.activeProbeService?.getProbeTelemetry?.()||[];return{states:u.map(f=>({provider:f.provider,model:f.model,status:f.status,failureCount:f.failureCount,successCount:f.successCount,lastFailureTime:f.lastFailureTime,lastError:f.lastError,rateLimitUntil:f.rateLimitUntil??null})),probes:g,timestamp:new Date().toISOString()}}catch(c){console.error("Failed to get provider health:",c),a.status(500).send({error:"Failed to get provider health"})}}),t.post("/api/providers/probe",async(l,a)=>{try{let{providerName:c}=l.body;if(!c)return a.status(400),{error:"providerName is required"};let d=t._server?.activeProbeService;if(!d?.probeProviderManually)return a.status(503),{error:"Active probe service is not available"};let g=await d.probeProviderManually(c);return g.success&&Sn(c,l.log),{provider:c,success:g.success,latencyMs:g.latencyMs,status:g.status,isSlow:g.isSlow,errorKind:g.errorKind??null,error:g.error,timestamp:new Date().toISOString()}}catch(c){console.error("Failed to probe provider:",c),a.status(500).send({error:c.message||"Failed to probe provider"})}}),t.post("/api/providers/probe-all",async(l,a)=>{try{let c=t._server,u=c?.activeProbeService;if(!u?.probeProviderManually)return a.status(503),{error:"Active probe service is not available"};let d=(c?.providerService?.getProviders?.()||[]).filter(f=>f?.name&&f.enabled!==!1),g=await Promise.all(d.map(async f=>{let y=await u.probeProviderManually(f.name);return y.success&&Sn(f.name,l?.log),{provider:f.name,success:y.success,latencyMs:y.latencyMs,status:y.status,isSlow:y.isSlow,errorKind:y.errorKind??null,error:y.error}}));return{results:g,successCount:g.filter(f=>f.success).length,total:g.length,timestamp:new Date().toISOString()}}catch(c){console.error("Failed to probe all providers:",c),a.status(500).send({error:c.message||"Failed to probe all providers"})}}),t.get("/api/providers/quota",async(l,a)=>{try{let u=(await re()).Providers||[],d=Lu(u),g=new Map(d.map(p=>[p.provider,p])),f=Xn();for(let p of d){let m=f.find(_=>_.provider===p.provider);m&&m.limit!=null&&(p.limit5h=m.limit,p.used5h=m.limit-(m.remaining??0),m.reset&&(p.reset5h=new Date(m.reset*1e3).toISOString()))}let y=oo();for(let p of y){let m=g.get(p.provider);m||(m={provider:p.provider,used5h:0,used7d:0},d.push(m),g.set(p.provider,m)),typeof p.totalBalance=="number"?(m.limit7d=p.totalBalance,m.type7d=p.currency?"balance":"rateLimit",p.currency&&(m.currency=p.currency),typeof p.usedBalance=="number"?m.used7d=p.usedBalance:typeof p.remainingBalance=="number"?m.used7d=Math.max(0,p.totalBalance-p.remainingBalance):(m.used7d=0,m.limit7d=p.totalBalance)):typeof p.usedBalance=="number"&&(m.used7d=p.usedBalance),typeof p.usedDailyBalance=="number"&&(m.used5h=p.usedDailyBalance,m.type5h="rateLimit"),typeof p.limitDaily=="number"&&(m.limit5h=p.limitDaily,m.type5h="rateLimit"),typeof p.resetTime=="string"&&(p.limitDaily!==void 0?m.reset5h=p.resetTime:m.reset7d=p.resetTime),typeof p.resetTime7d=="string"&&(m.reset7d=p.resetTime7d)}return{quotas:d,timestamp:new Date().toISOString()}}catch(c){console.error("Failed to compute provider quota:",c),a.status(500).send({error:"Failed to compute provider quota"})}}),t.get("/api/presets",async(l,a)=>{try{let c=se(gu,"presets");if(!de(c))return{presets:[]};let d=Pi(c,{withFileTypes:!0}).filter(f=>f.isDirectory()&&!f.name.startsWith(".")).map(f=>f.name),g=[];for(let f of d){let y=se(c,f);try{let p=se(y,"manifest.json"),m=Ei(p,"utf-8"),_=JSON.parse(m),{Providers:k,Router:h,PORT:b,HOST:T,API_TIMEOUT_MS:x,PROXY_URL:v,PROXY_GLOBAL_ENABLED:S,LOG:C,LOG_LEVEL:P,StatusLine:R,NON_INTERACTIVE_MODE:O,...E}=_;g.push({id:f,name:E.name||f,version:E.version||"1.0.0",description:E.description,author:E.author,homepage:E.homepage,repository:E.repository,license:E.license,keywords:E.keywords,ccrVersion:E.ccrVersion,source:E.source,sourceType:E.sourceType,checksum:E.checksum,installed:!0})}catch(p){console.error(`Failed to read preset ${f}:`,p)}}return{presets:g}}catch(c){console.error("Failed to get presets:",c),a.status(500).send({error:"Failed to get presets"})}}),t.get("/api/presets/:name",async(l,a)=>{try{let{name:c}=l.params,u=In(c);if(!de(u)){a.status(404).send({error:"Preset not found"});return}let d=await rr(u);return{...Ai(d),config:hu(d,u),userValues:d.userValues||{}}}catch(c){console.error("Failed to get preset:",c),a.status(500).send({error:c.message||"Failed to get preset"})}}),t.post("/api/presets/:name/apply",async(l,a)=>{try{let{name:c}=l.params,{secrets:u}=l.body,d=In(c);if(!de(d)){a.status(404).send({error:"Preset not found"});return}let f={...await rr(d)};return u&&Object.keys(u).length>0&&(f.userValues={...f.userValues,...u}),await Ii(c,f),{success:!0,message:"Preset applied successfully"}}catch(c){console.error("Failed to apply preset:",c),a.status(500).send({error:c.message||"Failed to apply preset"})}}),t.delete("/api/presets/:name",async(l,a)=>{try{let{name:c}=l.params,u=In(c);if(!de(u)){a.status(404).send({error:"Preset not found"});return}return fu(u,{recursive:!0,force:!0}),{success:!0,message:"Preset deleted successfully"}}catch(c){console.error("Failed to delete preset:",c),a.status(500).send({error:c.message||"Failed to delete preset"})}}),t.get("/api/presets/market",async(l,a)=>{try{return{presets:await ku()}}catch(c){console.error("Failed to get market presets:",c),a.status(500).send({error:c.message||"Failed to get market presets"})}}),t.post("/api/presets/install/github",async(l,a)=>{try{let{presetName:c}=l.body;if(!c){a.status(400).send({error:"Preset name is required"});return}let u=await _u(c);if(!u){a.status(400).send({error:"Preset not found in marketplace",message:`Preset '${c}' is not available in the official marketplace. Please check the available presets.`});return}if(!u.repo){a.status(400).send({error:"Invalid preset data",message:`Preset '${c}' does not have repository information`});return}let d=u.repo.match(/(?:github\.com[:/]|^)([^/]+)\/([^/\s#]+?)(?:\.git)?$/);if(!d){a.status(400).send({error:"Invalid GitHub repository URL"});return}let[,g,f]=d,y=u.name||c;if(await Mi(y)){a.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/${g}/${f}/archive/refs/heads/main.zip`,m=await yu(p),_=await i(m);if(await Mi(y)){Oi(m),a.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 mu(m,k);let h=await rr(k);return h.repository=u.repo,u.url&&(h.source=u.url),await Ii(y,h),Oi(m),{success:!0,presetName:y,preset:{..._.metadata,installed:!0}}}catch(c){console.error("Failed to install preset from GitHub:",c),a.status(500).send({error:c.message||"Failed to install preset from GitHub"})}});async function i(l){let a=new Nu(l),c=a.getEntry("manifest.json");if(c||(c=a.getEntries().find(g=>g.entryName.includes("manifest.json"))||null),!c)throw new Error("Invalid preset file: manifest.json not found");let u=JSON.parse(c.getData().toString("utf-8"));return Ai(u)}return n}var Di=w(()=>{"use strict";Me();Se();Pe();Lt();hn();te();Ge();ne();Rn();Cn();yt();Qo()});function Du(n,e){let t=n?.Router,{family:o}=et(e||"");if(t?.enableFamilyRouting&&o){let r=t.families?.[o]?.image;if(r)return r}return t?.image}function Fi(n){return n?.Router?.image}function Fu(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")))}function Uu(n){let e=n[n.length-1];if(e?.role!=="user"||!Array.isArray(e.content))return;let t=[];e.content.filter(o=>o.type==="tool_result").forEach(o=>{if(!Array.isArray(o.content))return;let r=o.content.filter(s=>s.type==="image"?(t.push(s),!1):!0);r.length!==o.content.length&&(o.content=r.length>0?r:"read image successfully")}),e.content.push(...t)}var cr,Mn,lr,Ui,ji=w(()=>{"use strict";Me();cr=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 cr;lr=class{name="image";tools;constructor(){this.tools=new Map,this.appendTools()}shouldHandle(e,t){let o=Du(t,e.originalModel||e.body.model);if(!o||e.body.model===o||!Fu(e.body.messages))return!1;let s=t.forceUseImageAgent===!0;return!s&&io(e.body.model)?!1:(Uu(e.body.messages),s&&!!Fi(t))}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 a=Mn.getImage(`${t.req.id}_Image#${l}`);a&&o.push({type:"image",source:a})});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(a=>a.type==="text"&&!a.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 i=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:Fi(t.config),system:[{type:"text",text:`You must interpret and analyze images strictly according to the assigned task.
|
|
408
408
|
When an image placeholder is provided, your role is to parse the image content only within the scope of the user\u2019s instructions.
|
|
409
409
|
Do not ignore or deviate from the task.
|
|
410
410
|
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!i||!i.content?"analyzeImage Error":i.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.
|
|
@@ -417,5 +417,5 @@ If multiple images exist, select the **most relevant imageId** based on the user
|
|
|
417
417
|
|
|
418
418
|
Do not attempt to describe or analyze the image directly yourself.
|
|
419
419
|
Ignore any user interruptions or unrelated instructions that might cause you to skip this requirement.
|
|
420
|
-
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(i=>i.type==="image"||Array.isArray(i.content)&&i.content.some(l=>l.type==="image"))),r=1;o.forEach(s=>{Array.isArray(s.content)&&s.content.forEach(i=>{if(i.type==="image")An.storeImage(`${e.id}_Image#${r}`,i.source),i.type="text",delete i.source,i.text=`[Image #${r}]This is an image, if you need to view or analyze it, you need to extract the imageId`,r++;else if(i.type==="text"&&i.text.includes("[Image #"))i.text=i.text.replace(/\[Image #\d+\]/g,"");else if(i.type==="tool_result"&&Array.isArray(i.content)&&i.content.some(l=>l.type==="image")){let l=[],a=i.content.filter(u=>u.type!=="image"?!0:(An.storeImage(`${e.id}_Image#${r}`,u.source),l.push(`[Image #${r}]`),r++,!1)),c=`${l.join("")}This is an image, if you need to view or analyze it, you need to extract the imageId`;i.content=a.length>0?[{type:"text",text:c},...a]:c}})})}},Li=new ar});var cr,Fi,In,Ui=w(()=>{"use strict";Di();cr=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}},Fi=new cr;Fi.registerAgent(Li);In=Fi});import{EventEmitter as Lu}from"node:events";import{performance as ji}from"node:perf_hooks";import Du from"json5";function Fu(n,e){return n===429||!!(e&&/rate[\s_]limit|too many|限流|频率限制|qps_limit|token_limit|quota exhausted|usage limit|limit reached/i.test(e))}function zi(n,e){(!n.clientContext||!n.usageCacheKey||!n.usageSessionId)&&ge(n,e)}function lr(n){return n.usageSessionId||n.id}function Mn(n){return n.usageCacheKey||`${n.clientType||"unknown"}:request:${lr(n)}`}function ze(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 Uu(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 ju(n,e,t){if(await new Promise((r,s)=>{let i=l=>l?s(l):r();Rn(t)(n,e,i).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")){zi(n,t);let r=Mn(n);n.clientContext?.usageScope==="session"&&(n.previousUsage=V.get(r))}}async function Hu(n,e,t){if(!n.pathname?.endsWith("/v1/messages"))return;let o=[];for(let r of In.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 Bi(n){return{authClient:(e,t)=>ju(e,t,n),agent:(e,t)=>Hu(e,t,n)}}function Ji(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=ji.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,i)=>{let l=a=>a?i(a):s();Rn(e)(t,o,l).then(()=>s(),i)})}),n.addHook("onError",async(t,o,r)=>{t.errorMessage=r?.message||r?.toString?.()||"Unknown error",Hi.emit("onError",t,o,r)}),n.addHook("onSend",(t,o,r,s)=>{(t.ccrHookOrder||=[]).push("onSend");let i=t.pathname?.endsWith("/v1/messages"),l=t.pathname?.endsWith("/v1/responses");if(i||l){zi(t,e);let a=lr(t),c=Mn(t);if(r instanceof ReadableStream){if(i&&t.agents){let y=new AbortController,p=r.pipeThrough(new re),f,_=-1,k="",h="",b="",T=[],x=[];return s(null,gn(p,async(v,S)=>{try{if(v.event==="content_block_start"&&v?.data?.content_block?.name){let C=t.agents.find(P=>In.getAgent(P)?.tools.get(v.data.content_block.name));if(C){f=In.getAgent(C),_=v.data.index,k=v.data.content_block.name,b=v.data.content_block.id;return}}if(_>-1&&v.data.index===_&&v.data?.delta?.type==="input_json_delta"){h+=v.data?.delta?.partial_json;return}if(_>-1&&v.data.index===_&&v.data?.type==="content_block_stop"){try{let C=Du.parse(h);x.push({type:"tool_use",id:b,name:k,input:C});let P=await f?.tools.get(k)?.handler(C,{req:t,config:e});T.push({tool_use_id:b,type:"tool_result",content:P}),f=void 0,_=-1,k="",h="",b=""}catch(C){console.log(C)}return}if(v.event==="message_delta"&&T.length){t.body.messages.push({role:"assistant",content:x}),t.body.messages.push({role:"user",content:T});let C=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(!C.ok)return;let R=C.body.pipeThrough(new re).getReader();for(;;)try{let{value:O,done:E}=await R.read();if(E)break;let A=O;if(["message_start","message_stop"].includes(A.event))continue;if(!S.desiredSize)break;S.enqueue(A)}catch(O){if(O.name==="AbortError"||O.code==="ERR_STREAM_PREMATURE_CLOSE"){y.abort();break}throw O}return}return v}catch(C){if(console.error("Unexpected error in stream processing:",C),C.code==="ERR_STREAM_PREMATURE_CLOSE"){y.abort();return}throw C}}).pipeThrough(new Le))}let[d,g]=r.tee(),m=async y=>{let f=y.pipeThrough(new TextDecoderStream).pipeThrough(new re).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 T=V.get(c)||{},x=Ue(b.usage),v=Tn(T,x,h==="message_start");t.log?.info?.({debug_log:!0,reqId:t.id,phase:"usage_capture_anthropic_sse",event:h,provider:t.provider,model:ze(t),usageSessionId:a,capturedUsage:x,mergedUsage:v}),(x?.cache_read_input_tokens||x?.cache_creation_input_tokens)&&console.log("[Usage] Cache tokens:",{cache_read:x?.cache_read_input_tokens,cache_creation:x?.cache_creation_input_tokens}),V.put(c,v)}if(b?.response?.usage){let T=Ue(b.response.usage),x=V.get(c)||{},v=Tn(x,T,!1);t.log?.info?.({debug_log:!0,reqId:t.id,phase:"usage_capture_responses_sse",event:h,provider:t.provider,model:ze(t),usageSessionId:a,capturedUsage:T,mergedUsage:v}),V.put(c,v)}}}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=m(g),s(null,d)}let u=Uu(r);if(u?.usage&&V.put(c,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(Hi.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=lr(t),s=o.statusCode>=400,i=s?void 0:V.get(Mn(t)),l=er(r),a=F(),c,u,d=t.sseError,g=d&&(d.type||d.code||d.message),m=i?.output_tokens&&i.output_tokens>0,y=s||g&&!m;if(y){c=t.errorMessage||o.errorMessage||t.error?.message||t.error?.toString?.()||void 0,g&&(c=c||JSON.stringify(d),u=JSON.stringify(d)),u=u||t.errorResponseBody;let h=ze(t);Fu(o.statusCode,c)?a.markRateLimited(t.provider||"",h,120,c):a.recordFailure(t.provider||"",h,c)}else{let h=ze(t);a.recordSuccess(t.provider||"",h)}let p=i?.cache_read_input_tokens??0,_=i?.input_tokens||0||t.tokenCount||0;!p&&t.tokenCount&&i?.input_tokens&&i.input_tokens<t.tokenCount&&(p=t.tokenCount-i.input_tokens,p&&console.log("[Usage] Inferred cache tokens:",{tokenCount:t.tokenCount,netInput:i.input_tokens,impliedCache:p}));let k=y?0:i?.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:ze(t),usageSessionId:r,tokenCount:t.tokenCount,cachedUsage:i,note:"Successful streaming request ended with zero usage. Check provider_stream_chunk usage_monitor and usage_capture_* logs."}),ft({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:ze(t),upstreamModel:t.upstreamModel,modelFamily:t.modelFamily||"",scenarioType:t.scenarioType||"default",clientType:t.clientType||Pe(t),stream:t.body?.stream??!1,inputTokens:_,outputTokens:k,cacheReadInputTokens:p,cacheCreationInputTokens:i?.cache_creation_input_tokens||0,ttft:y||!t.body?.stream?null:l.ttft,tokensPerSecond:y?null:l.tokensPerSecond,durationMs:t.requestStartTime?Math.round(ji.now()-t.requestStartTime):0,status:y?"error":"success",errorMessage:c,responseBody:u}),t.clientContext?.usageScope!=="session"&&V.delete(Mn(t))}catch(r){console.error("Usage tracking error:",r)}})}var Hi,Wi=w(()=>{"use strict";Ee();Rt();ee();Oo();Ao();Io();gt();Jo();Ui();Ko();Mt();Hi=new Lu});var Gi={};Nn(Gi,{createCcrServer:()=>Qu});import{homedir as zu}from"os";import{join as Bu}from"path";import{createStream as Ju}from"rotating-file-stream";import{CONFIG_FILE as Wu,HOME_DIR as Gu,listPresets as Ku}from"@wengine-ai/claude-code-router-shared";async function Qu(n={}){await hi(),await _n();let e=await Bo(),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,i=process.env.SERVICE_PORT?parseInt(process.env.SERVICE_PORT):s,l=p=>(p>9?"":"0")+p,a=(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()),T=l(_.getMinutes());return`./logs/ccr-${k}${h}${b}${T}${l(_.getSeconds())}${f?`_${f}`:""}.log`},c;n.logger!==void 0?c=n.logger:(Ti(),e.LOG!==!1?(e.LOG===void 0&&(e.LOG=!0),c={level:e.LOG_LEVEL||"error",stream:Ju(a,{path:Gu,interval:"1d",size:"50M",compress:!1})}):c=!1);let u=await Ku(),d=new Qi({jsonPath:Wu,initialConfig:{providers:e.Providers||e.providers,HOST:r,PORT:i,LOG_FILE:Bu(zu(),".claude-code-router","claude-code-router.log")},logger:c});await d.ready(),await Mi(d,e),d.recordUsage=p=>{try{let f=p.req?p.req.clientType||Pe(p.req):"unknown";ft({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,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)}},Ji(d,e),d.ccrPreHandlerCallbacks=Bi(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 vi(d,e),lt(e,d.app?.log);let m=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",m),process.on("unhandledRejection",y),d.app.addHook("onClose",async()=>{process.off("uncaughtException",m),process.off("unhandledRejection",y)}),d}var Ki=w(()=>{"use strict";Vi();yi();bn();Ci();xi();$i();Wi();xn();gt();Ee()});import Vu from"fastify";import Yu from"@fastify/cors";function Xu(n={}){let e=Vu({bodyLimit:52428800,...n});return e.setErrorHandler(hr),e.register(Yu),e}async function qu(n={}){return(await Promise.resolve().then(()=>(Ki(),Gi))).createCcrServer(n)}var ur,Qi,qh,Vi=w(()=>{Dn();_t();Mt();$t();lo();po();Ae();Rt();mn();ee();ve();Re();Z();Ee();Mt();Ve();Ee();Ae();Dn();$t();lo();po();jo();Mo();ee();ve();Ro();Re();ee();mn();Je();Z();bn();Jo();xn();Go();Ko();gt();ur=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:i,useEnvironmentVariables:l,...a}=e;this.app=Xu({...a,logger:a.logger??!0}),this.app._server=this;let c={initialConfig:t};o!==void 0&&(c.jsonPath=o),r!==void 0&&(c.envPath=r),s!==void 0&&(c.useEnvFile=s),i!==void 0&&(c.useJsonFile=i),l!==void 0&&(c.useEnvironmentVariables=l),this.configService=new ke(c),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,i=this.tokenizerService;if(e!=="/"){if(!t)throw new Error("options is required");o=new ke({initialConfig:{...t,providers:t.Providers||t.providers}}),r=new Me(o,this.app.log),i=new $e(o,this.app.log),await Promise.all([r.initialize(),i.initialize()]),s=new ce(o,r,this.app.log)}let l=async a=>{a.decorate("configService",o),a.decorate("transformerService",r),a.decorate("providerService",s),a.decorate("tokenizerService",i),a.decorate("recordUsage",this.recordUsage||(()=>{})),a.addHook("preHandler",async(c,u)=>{let d=new URL(`http://127.0.0.1${c.url}`);c.pathname=d.pathname;let g=d.pathname.endsWith("/v1/messages"),m=d.pathname.endsWith("/v1/responses");if(!g&&!m||!c.body||typeof c.body!="object")return;let y=c.ccrHookOrder||=[];if(y.push("request-normalize"),m&&c.body.input&&!c.body.messages&&Ze(c.body),c.body.stream===void 0&&(c.body.stream=!1),c.log.info({data:c.body,type:"request body"}),y.push("adapter"),!c.originalModel&&c.body.model&&(c.originalModel=c.body.model),ge(c,o.getAll()),y.push("auth-client"),!(this.ccrPreHandlerCallbacks&&(await this.ccrPreHandlerCallbacks.authClient(c,u),u.sent))&&(y.push("agent"),!(this.ccrPreHandlerCallbacks&&(await this.ccrPreHandlerCallbacks.agent(c,u),u.sent)))){y.push("router"),c.body?.model&&await At(c,u,{configService:o,tokenizerService:i}),c.usageCacheKey&&V.put(c.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=c.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=_,c.provider=k}c.model=_}catch(p){return c.log.error({error:p},"Error in modelProviderMiddleware:"),u.code(500).send({error:"Internal server error"})}}}),await as(a)};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 Ln()})}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{Ge()}catch{}try{Ke()}catch{}try{Wn()}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,slowThresholdMs:Number(this.configService.get("PROBE_SLOW_THRESHOLD_MS"))||3e3,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)}}},Qi=ur;qh=qu});Vi();export{pn as ActiveProbeService,ke as ConfigService,ae as ProjectRoutingError,St as ProviderHealthStore,ce as ProviderService,re as SSEParserTransform,Le as SSESerializerTransform,$e as TokenizerService,Me as TransformerService,Rn as apiKeyAuth,ge as applyClientAdapter,kn as backupConfigFile,zr as builtinClientAdapterRegistry,Ot as calculateTokenCount,qa as clearClientAdapterCaches,vn as clearProviderHealth,Ln as closeProxyDispatchers,ai as collectReachableModelKeys,qu as createCcrServer,Qi as default,Pe as detectClientType,Xr as diagnoseResolutionFailure,Qe as extractSessionIdFromUserId,Ys as getActiveProbeService,to as getAllQuotaResults,Vn as getAllRateLimitInfo,Jr as getClientAdapter,yt as getConfiguredProxyUrl,F as getHealthStore,W as getProxyDispatcher,xo as getQuotaAdapter,wt as getQuotaResult,Oa as getRateLimitInfo,kt as getRuntimeDebugLog,qh as getServer,Bo as initConfig,_n as initDir,Wn as initProviderHealthPersistence,Ke as initQuotaStorePersistence,Ge as initRateLimitPersistence,Br as isClientType,fr as isGlobalProxyEnabled,Sn as listAnthropicCompatibleModels,Tn as mergeUsageCapture,we as normalizeSessionId,Ue as normalizeUsagePayload,nt as pluginManager,ne as readConfigFile,zo as readConfigFileRaw,lt as reconcileHealthStore,fn as resetActiveProbeService,se as resolveProviderProxyUrl,gn as rewriteStream,At as router,es as searchProjectBySession,V as sessionUsageCache,Un as setRuntimeDebugLog,Ne as startActiveProbe,Po as stopActiveProbe,eo as storeQuotaResult,hn as tokenSpeedPlugin,gi as usageStore,Fe as writeConfigFile};
|
|
420
|
+
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(i=>i.type==="image"||Array.isArray(i.content)&&i.content.some(l=>l.type==="image"))),r=1;o.forEach(s=>{Array.isArray(s.content)&&s.content.forEach(i=>{if(i.type==="image")Mn.storeImage(`${e.id}_Image#${r}`,i.source),i.type="text",delete i.source,i.text=`[Image #${r}]This is an image, if you need to view or analyze it, you need to extract the imageId`,r++;else if(i.type==="text"&&i.text.includes("[Image #"))i.text=i.text.replace(/\[Image #\d+\]/g,"");else if(i.type==="tool_result"&&Array.isArray(i.content)&&i.content.some(l=>l.type==="image")){let l=[],a=i.content.filter(u=>u.type!=="image"?!0:(Mn.storeImage(`${e.id}_Image#${r}`,u.source),l.push(`[Image #${r}]`),r++,!1)),c=`${l.join("")}This is an image, if you need to view or analyze it, you need to extract the imageId`;i.content=a.length>0?[{type:"text",text:c},...a]:c}})})}},Ui=new lr});var ur,Hi,$n,zi=w(()=>{"use strict";ji();ur=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}},Hi=new ur;Hi.registerAgent(Ui);$n=Hi});import{EventEmitter as ju}from"node:events";import{performance as Ji}from"node:perf_hooks";import Hu from"json5";function zu(n,e){return n===429||!!(e&&/rate[\s_]limit|too many|限流|频率限制|qps_limit|token_limit|quota exhausted|usage limit|limit reached/i.test(e))}function Wi(n,e){(!n.clientContext||!n.usageCacheKey||!n.usageSessionId)&&ye(n,e)}function dr(n){return n.usageSessionId||n.id}function Nn(n){return n.usageCacheKey||`${n.clientType||"unknown"}:request:${dr(n)}`}function Be(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 Ju(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?He(e.usage):e.response?.usage?He(e.response.usage):void 0,o=e.model||e.response?.model;if(!(!t&&!o))return{usage:t,model:o}}async function Bu(n,e,t){if(await new Promise((r,s)=>{let i=l=>l?s(l):r();Pn(t)(n,e,i).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")){Wi(n,t);let r=Nn(n);n.clientContext?.usageScope==="session"&&(n.previousUsage=X.get(r))}}async function Wu(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 Gi(n){return{authClient:(e,t)=>Bu(e,t,n),agent:(e,t)=>Wu(e,t,n)}}function Ki(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=Ji.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,i)=>{let l=a=>a?i(a):s();Pn(e)(t,o,l).then(()=>s(),i)})}),n.addHook("onError",async(t,o,r)=>{t.errorMessage=r?.message||r?.toString?.()||"Unknown error",Bi.emit("onError",t,o,r)}),n.addHook("onSend",(t,o,r,s)=>{(t.ccrHookOrder||=[]).push("onSend");let i=t.pathname?.endsWith("/v1/messages"),l=t.pathname?.endsWith("/v1/responses");if(i||l){Wi(t,e);let a=dr(t),c=Nn(t);if(r instanceof ReadableStream){if(i&&t.agents){let y=new AbortController,p=r.pipeThrough(new ie),m,_=-1,k="",h="",b="",T=[],x=[];return s(null,yn(p,async(v,S)=>{try{if(v.event==="content_block_start"&&v?.data?.content_block?.name){let C=t.agents.find(P=>$n.getAgent(P)?.tools.get(v.data.content_block.name));if(C){m=$n.getAgent(C),_=v.data.index,k=v.data.content_block.name,b=v.data.content_block.id;return}}if(_>-1&&v.data.index===_&&v.data?.delta?.type==="input_json_delta"){h+=v.data?.delta?.partial_json;return}if(_>-1&&v.data.index===_&&v.data?.type==="content_block_stop"){try{let C=Hu.parse(h);x.push({type:"tool_use",id:b,name:k,input:C});let P=await m?.tools.get(k)?.handler(C,{req:t,config:e});T.push({tool_use_id:b,type:"tool_result",content:P}),m=void 0,_=-1,k="",h="",b=""}catch(C){console.log(C)}return}if(v.event==="message_delta"&&T.length){t.body.messages.push({role:"assistant",content:x}),t.body.messages.push({role:"user",content:T});let C=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(!C.ok)return;let R=C.body.pipeThrough(new ie).getReader();for(;;)try{let{value:O,done:E}=await R.read();if(E)break;let A=O;if(["message_start","message_stop"].includes(A.event))continue;if(!S.desiredSize)break;S.enqueue(A)}catch(O){if(O.name==="AbortError"||O.code==="ERR_STREAM_PREMATURE_CLOSE"){y.abort();break}throw O}return}return v}catch(C){if(console.error("Unexpected error in stream processing:",C),C.code==="ERR_STREAM_PREMATURE_CLOSE"){y.abort();return}throw C}}).pipeThrough(new Fe))}let[d,g]=r.tee(),f=async y=>{let m=y.pipeThrough(new TextDecoderStream).pipeThrough(new ie).getReader();try{for(;;){let{done:_,value:k}=await m.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 T=X.get(c)||{},x=He(b.usage),v=vn(T,x,h==="message_start");t.log?.info?.({debug_log:!0,reqId:t.id,phase:"usage_capture_anthropic_sse",event:h,provider:t.provider,model:Be(t),usageSessionId:a,capturedUsage:x,mergedUsage:v}),(x?.cache_read_input_tokens||x?.cache_creation_input_tokens)&&console.log("[Usage] Cache tokens:",{cache_read:x?.cache_read_input_tokens,cache_creation:x?.cache_creation_input_tokens}),X.put(c,v)}if(b?.response?.usage){let T=He(b.response.usage),x=X.get(c)||{},v=vn(x,T,!1);t.log?.info?.({debug_log:!0,reqId:t.id,phase:"usage_capture_responses_sse",event:h,provider:t.provider,model:Be(t),usageSessionId:a,capturedUsage:T,mergedUsage:v}),X.put(c,v)}}}catch(_){_.name==="AbortError"||_.code==="ERR_STREAM_PREMATURE_CLOSE"?console.error("Background read stream closed prematurely"):console.error("Error in background stream reading:",_)}finally{m.releaseLock()}};return t.usageCapturePromise=f(g),s(null,d)}let u=Ju(r);if(u?.usage&&X.put(c,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(Bi.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=dr(t),s=o.statusCode>=400,i=s?void 0:X.get(Nn(t)),l=nr(r),a=U(),c,u,d=t.sseError,g=d&&(d.type||d.code||d.message),f=i?.output_tokens&&i.output_tokens>0,y=s||g&&!f;if(y){c=t.errorMessage||o.errorMessage||t.error?.message||t.error?.toString?.()||void 0,g&&(c=c||JSON.stringify(d),u=JSON.stringify(d)),u=u||t.errorResponseBody;let h=Be(t);zu(o.statusCode,c)?a.markRateLimited(t.provider||"",h,120,c):a.recordFailure(t.provider||"",h,c)}else{let h=Be(t);a.recordSuccess(t.provider||"",h)}let p=i?.cache_read_input_tokens??0,_=i?.input_tokens||0||t.tokenCount||0;!p&&t.tokenCount&&i?.input_tokens&&i.input_tokens<t.tokenCount&&(p=t.tokenCount-i.input_tokens,p&&console.log("[Usage] Inferred cache tokens:",{tokenCount:t.tokenCount,netInput:i.input_tokens,impliedCache:p}));let k=y?0:i?.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:Be(t),usageSessionId:r,tokenCount:t.tokenCount,cachedUsage:i,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:Be(t),upstreamModel:t.upstreamModel,modelFamily:t.modelFamily||"",scenarioType:t.scenarioType||"default",clientType:t.clientType||Oe(t),stream:t.body?.stream??!1,inputTokens:_,outputTokens:k,cacheReadInputTokens:p,cacheCreationInputTokens:i?.cache_creation_input_tokens||0,ttft:y||!t.body?.stream?null:l.ttft,tokensPerSecond:y?null:l.tokensPerSecond,durationMs:t.requestStartTime?Math.round(Ji.now()-t.requestStartTime):0,status:y?"error":"success",errorMessage:c,responseBody:u}),t.clientContext?.usageScope!=="session"&&X.delete(Nn(t))}catch(r){console.error("Usage tracking error:",r)}})}var Bi,Qi=w(()=>{"use strict";Ae();Pt();ne();Io();Mo();$o();yt();Go();zi();Vo();Nt();Bi=new ju});var Vi={};Dn(Vi,{createCcrServer:()=>qu});import{homedir as Gu}from"os";import{join as Ku}from"path";import{createStream as Qu}from"rotating-file-stream";import{CONFIG_FILE as Vu,HOME_DIR as Yu,listPresets as Xu}from"@wengine-ai/claude-code-router-shared";async function qu(n={}){await ki(),await bn();let e=await Wo(),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,i=process.env.SERVICE_PORT?parseInt(process.env.SERVICE_PORT):s,l=p=>(p>9?"":"0")+p,a=(p,m)=>{let _;p?typeof p=="number"?_=new Date(p):_=p:_=new Date;let k=_.getFullYear()+""+l(_.getMonth()+1),h=l(_.getDate()),b=l(_.getHours()),T=l(_.getMinutes());return`./logs/ccr-${k}${h}${b}${T}${l(_.getSeconds())}${m?`_${m}`:""}.log`},c;n.logger!==void 0?c=n.logger:(xi(),e.LOG!==!1?(e.LOG===void 0&&(e.LOG=!0),c={level:e.LOG_LEVEL||"error",stream:Qu(a,{path:Yu,interval:"1d",size:"50M",compress:!1})}):c=!1);let u=await Xu(),d=new Xi({jsonPath:Vu,initialConfig:{providers:e.Providers||e.providers,HOST:r,PORT:i,LOG_FILE:Ku(Gu(),".claude-code-router","claude-code-router.log")},logger:c});await d.ready(),await Li(d,e),d.recordUsage=p=>{try{let m=p.req?p.req.clientType||Oe(p.req):"unknown";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:m,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(m){console.error("Fallback usage tracking error:",m)}},Ki(d,e),d.ccrPreHandlerCallbacks=Gi(e),(await Promise.allSettled(u.map(async p=>await d.registerNamespace(`/preset/${p.name}`,p.config)))).forEach((p,m)=>{if(p.status==="rejected"){let _=u[m],k=p.reason instanceof Error?p.reason.message:String(p.reason);d.app?.log?.error?.(`Failed to register preset "${_?.name}": ${k}`)}}),await Ri(d,e),dt(e,d.app?.log);let f=p=>{d.app.log.error({err:p},"Uncaught exception")},y=(p,m)=>{d.app.log.error({reason:p,promise:m},"Unhandled rejection")};return process.on("uncaughtException",f),process.on("unhandledRejection",y),d.app.addHook("onClose",async()=>{process.off("uncaughtException",f),process.off("unhandledRejection",y)}),d}var Yi=w(()=>{"use strict";qi();bi();Cn();Si();wi();Di();Qi();Rn();yt();Ae()});import Zu from"fastify";import ed from"@fastify/cors";function td(n={}){let e=Zu({bodyLimit:52428800,...n});return e.setErrorHandler(_r),e.register(ed),e}async function nd(n={}){return(await Promise.resolve().then(()=>(Yi(),Vi))).createCcrServer(n)}var pr,Xi,hy,qi=w(()=>{Un();bt();Nt();Lt();po();mo();Me();Pt();hn();ne();Se();Pe();te();Ae();Nt();Xe();Ae();Me();Un();Lt();po();mo();zo();No();ne();Se();Po();Pe();ne();hn();Ge();te();Cn();Go();Rn();Qo();Vo();yt();pr=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:i,useEnvironmentVariables:l,...a}=e;this.app=td({...a,logger:a.logger??!0}),this.app._server=this;let c={initialConfig:t};o!==void 0&&(c.jsonPath=o),r!==void 0&&(c.envPath=r),s!==void 0&&(c.useEnvFile=s),i!==void 0&&(c.useJsonFile=i),l!==void 0&&(c.useEnvironmentVariables=l),this.configService=new Te(c),this.transformerService=new Ne(this.configService,this.app.log),this.tokenizerService=new Le(this.configService,this.app.log),this.readiness=(async()=>{await Promise.all([this.transformerService.initialize(),this.tokenizerService.initialize()]),this.providerService=new ue(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,i=this.tokenizerService;if(e!=="/"){if(!t)throw new Error("options is required");o=new Te({initialConfig:{...t,providers:t.Providers||t.providers}}),r=new Ne(o,this.app.log),i=new Le(o,this.app.log),await Promise.all([r.initialize(),i.initialize()]),s=new ue(o,r,this.app.log)}let l=async a=>{a.decorate("configService",o),a.decorate("transformerService",r),a.decorate("providerService",s),a.decorate("tokenizerService",i),a.decorate("recordUsage",this.recordUsage||(()=>{})),a.addHook("preHandler",async(c,u)=>{let d=new URL(`http://127.0.0.1${c.url}`);c.pathname=d.pathname;let g=d.pathname.endsWith("/v1/messages"),f=d.pathname.endsWith("/v1/responses");if(!g&&!f||!c.body||typeof c.body!="object")return;let y=c.ccrHookOrder||=[];if(y.push("request-normalize"),f&&c.body.input&&!c.body.messages&&tt(c.body),c.body.stream===void 0&&(c.body.stream=!1),c.log.info({data:c.body,type:"request body"}),y.push("adapter"),!c.originalModel&&c.body.model&&(c.originalModel=c.body.model),ye(c,o.getAll()),y.push("auth-client"),!(this.ccrPreHandlerCallbacks&&(await this.ccrPreHandlerCallbacks.authClient(c,u),u.sent))&&(y.push("agent"),!(this.ccrPreHandlerCallbacks&&(await this.ccrPreHandlerCallbacks.agent(c,u),u.sent)))){y.push("router"),c.body?.model&&await Mt(c,u,{configService:o,tokenizerService:i}),c.usageCacheKey&&X.put(c.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=c.body;if(!p||!p.model)return u.code(400).send({error:"Missing model in request body"});let m=p.model.split(","),_=p.model;if(m.length>1){let[k,...h]=m;_=h.join(","),p.model=_,c.provider=k}c.model=_}catch(p){return c.log.error({error:p},"Error in modelProviderMiddleware:"),u.code(500).send({error:"Internal server error"})}}}),await us(a)};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{Oo()}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 Fn()})}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{Qe()}catch{}try{Ve()}catch{}try{Kn()}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,slowThresholdMs:Number(this.configService.get("PROBE_SLOW_THRESHOLD_MS"))||3e3,initialDelayMs:this.configService.get("PROBE_INITIAL_DELAY_MS")??5e3,excludeProviders:this.configService.get("EXCLUDE_PROBE_PROVIDERS")??[]};this.activeProbeService=De(()=>this.providerService.getProviders(),t,o=>ae(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)}}},Xi=pr;hy=nd});qi();export{mn as ActiveProbeService,Te as ConfigService,le as ProjectRoutingError,wt as ProviderHealthStore,ue as ProviderService,ie as SSEParserTransform,Fe as SSESerializerTransform,Le as TokenizerService,Ne as TransformerService,Pn as apiKeyAuth,ye as applyClientAdapter,Tn as backupConfigFile,Wr as builtinClientAdapterRegistry,It as calculateTokenCount,nc as clearClientAdapterCaches,Sn as clearProviderHealth,Fn as closeProxyDispatchers,ui as collectReachableModelKeys,nd as createCcrServer,Xi as default,Oe as detectClientType,es as diagnoseResolutionFailure,Ye as extractSessionIdFromUserId,Zs as getActiveProbeService,oo as getAllQuotaResults,Xn as getAllRateLimitInfo,Kr as getClientAdapter,kt as getConfiguredProxyUrl,U as getHealthStore,G as getProxyDispatcher,Ro as getQuotaAdapter,Et as getQuotaResult,Ma as getRateLimitInfo,Tt as getRuntimeDebugLog,hy as getServer,Wo as initConfig,bn as initDir,Kn as initProviderHealthPersistence,Ve as initQuotaStorePersistence,Qe as initRateLimitPersistence,Gr as isClientType,gr as isGlobalProxyEnabled,wn as listAnthropicCompatibleModels,vn as mergeUsageCapture,Ee as normalizeSessionId,He as normalizeUsagePayload,rt as pluginManager,re as readConfigFile,Bo as readConfigFileRaw,dt as reconcileHealthStore,gn as resetActiveProbeService,ae as resolveProviderProxyUrl,yn as rewriteStream,Mt as router,os as searchProjectBySession,X as sessionUsageCache,Hn as setRuntimeDebugLog,De as startActiveProbe,Oo as stopActiveProbe,no as storeQuotaResult,_n as tokenSpeedPlugin,_i as usageStore,je as writeConfigFile};
|
|
421
421
|
//# sourceMappingURL=server.mjs.map
|