@wengine-ai/llms 2.3.2413 → 2.3.2414

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 CHANGED
@@ -93,6 +93,7 @@ npm install -g @wengine-ai/claude-code-router-next@latest && ccr restart
93
93
 
94
94
  | 版本 | 发布内容 |
95
95
  | --- | --- |
96
+ | **v2.3.2414** | <ul><li>**CCR Desktop(可选 Tauri 客户端)与 Pi 配置生命周期修复**: 新增可选 Tauri 桌面壳(托盘快速切换全局默认模型、quota 摘要、单实例;生命周期伴侣化、退出不杀 gateway);修复 `ccr restart` 的 disable→enable 与 legacy 项目 provider 改名迁移丢失 Pi 自定义模型字段(thinkingLevelMap/modelOverrides)。</li></ul> |
96
97
  | **v2.3.2413** | <ul><li>**修复 TTFT 永久为空**: #65(pi 会话粘连)与 #67(temp-file 重写)合并冲突解决时丢失了 #65 的 \`statsKey\` 文件名优先逻辑,handler 用会话 UUID 命名临时文件而 reader 用 requestId 查找 → 永久不匹配 → 所有流式请求的 TTFT 都是 null、tokens_per_second 退化为按完整时长重算。修复后 handler 优先用 \`metadata.statsKey\` 命名文件(对齐 reader),TTFT 与真实速度恢复。</li></ul> |
97
98
  | **v2.3.2412** | <ul><li>**修复用量/套餐接口在 node 版本不匹配时全部失效**: 当运行时 Node 的 ABI 与安装 better-sqlite3 时不同(如桌面应用注入自带 node),`ERR_DLOPEN_FAILED` 导致 `/api/usage*`、`/api/providers/quota` 全部 500,UI 用量页与套餐限额条消失。现在优先加载 better-sqlite3,加载失败自动回退 Node 内置 `node:sqlite`(Node ≥ 22.5),任意 node 版本下均可工作;CLI statusline 同步受益;回退时输出一次性显眼日志。</li><li>**修复 pi 模型条目自定义字段被刷新抹除**: `ensurePiCcrProvider` 此前整组替换 `models[]`,pi 的 `thinkingLevelMap` 等条目级自定义字段每次 CCR 启动/项目接管都被静默清掉(#69)。现在模型集合仍由 CCR 管理,但每个生成条目按同 id 与旧条目合并——受管字段以 CCR 为准,条目级自定义字段跨刷新保留。</li></ul> |
98
99
  | **v2.3.2411** | <ul><li>**AMD Radeon Cloud 转换器**: 新增 `amd` 转换器:统一 reasoning 意图按目标模型族映射为 AMD 端点支持的 `reasoning_effort` 档位(GLM/Qwen/DeepSeek 分别适配,禁用拼写正确透传),响应侧把 `reasoning` 内容提升为 `thinking`(含 SSE 误标 JSON 边界处理);推荐 provider 链 `use:["OpenAI","amd"]`。</li><li>**Pi 会话粘连**: 识别 `x-session-affinity` 等会话标识头生成稳定会话 ID:并发优先模式的会话槽位跨请求稳定粘附,token-speed 统计与用量记录按稳定会话 ID 分组,兼容 LiteLLM `x-litellm-session-id`,接管刷新后自动写入 pi 配置。</li><li>**修复 token-speed 临时文件堆积导致服务卡死**: 修复按请求写时间戳临时文件且永不清理的问题(单机曾累积 323 万文件,每次请求全目录扫描阻塞事件循环约 33 秒)。写入改为精确文件名原子覆盖并迁移到 `token-speed-v2` 子目录(新旧版本可并存),读取 O(1);新增默认 1 小时保留期自动清理;升级后服务启动自愈,仅清理旧目录中文件名时间戳与修改时间均超过 1 小时的历史文件,不触碰用量库与配置。</li></ul> |
@@ -102,7 +103,6 @@ npm install -g @wengine-ai/claude-code-router-next@latest && ccr restart
102
103
  | **v2.3.2407** | <ul><li>**ZCode 会话发现器**: ZCode 请求不带任何项目标识,项目级 Router 对 ZCode 无效;现在按会话回查 ZCode 本地任务索引(`~/.zcode/v2/tasks-index.sqlite`,会话 JSON 的 `meta.workspacePath` 兜底)得到运行目录并映射到项目 id,`ccr model --project`/UI 配置的项目 Router 对 ZCode 生效;索引晚写有一次短重试,异常一律退化为全局 Router。</li><li>**ZCode 项目接管开关(opt-in)**: 项目「接管的客户端」下拉新增 ZCode,且接管状态就是路由开关——只有勾选 ZCode 的项目走项目 Router,未勾选的项目保持全局 Router,避免会话发现把个人项目改道到项目/公司模型。ZCode 无可写的项目级配置文件,标记记录在 `~/.claude-code-router/<project-id>/takeover-clients.json`,取消勾选或删除项目时清除。</li></ul> |
103
104
  | **v2.3.2406** | <ul><li>**默认思考等级支持自定义值**: 除枚举外可填 token 预算或供应商私有字符串(如 `minimal`/`off`);数字在 Anthropic 端点按精确预算注入、OpenAI 系端点折叠为最接近档位,非枚举字符串在 OpenAI 系端点原样透传、Anthropic 端点按别名归一(min/minimal/light→low、xhigh/maximum/ultra→max);UI 新增「自定义」自由输入。</li><li>**思考深度按 effort 下发**: `convertToAnthropic` 现在同时下发 `output_config.effort`(当前 Anthropic 模型与 GLM 等兼容端点真正读取的字段),`thinking.budget_tokens` 保留以兼容旧模型与中转;客户端原始 effort 不再被丢弃、`thinking.type=adaptive` 不再被误判为关闭思考、预算不再被四舍五入到档位。</li><li>**ZCode 独立客户端归属**: 此前 ZCode 用 `ccr-*` 别名 + Claude Code 兼容 metadata 调用,日志一律记为 claude-code;现按请求头(`User-Agent: ZCode/…`、`X-ZCode-*`)识别并单独计入用量。</li><li>**release.sh 发布中断可续跑**: 重跑自动跳过已发布的包,只发剩余包。</li></ul> |
104
105
  | **v2.3.2405** | <ul><li>**供应商级默认思考等级**: 客户端未携带思考配置时按供应商配置的默认等级注入,并按端点类型自动转义——Anthropic `/v1/messages` → `thinking.budget_tokens`、OpenAI `/v1/responses` → `reasoning.effort`、OpenAI 兼容 chat → `reasoning_effort`;客户端显式设置始终优先。附带修复客户端显式 thinking 在 Anthropic 端点被丢弃的问题。</li><li>**预置自引用 `ccr` 供应商(免接管)**: ZCode 等自配端点客户端不再需要接管——CCR 启动/保存配置时自动确保存在指向自身的 `ccr` 供应商(ccr-opus/sonnet/haiku);删除后记 tombstone 不复活。</li><li>**pi 项目 provider 命名可读化**: `ccr-project-<hash>` → `ccr-project-<项目名>-<hash>`,旧格式无需迁移。</li></ul> |
105
- | **v2.3.2404** | <ul><li>**opencode provider 默认携带 x-opencode-session 会话头**: OpenCode Go 端点强制要求 `x-opencode-session`(缺失直接 400),而 CCR 非透传模式重建上游请求时只带 `Authorization`,客户端会话头全部丢弃,导致 opencode go 供应商(如 `omen-alpha`)全部 400。opencode transformer 现按优先级复用稳定会话 ID:客户端原生 `x-opencode-session` 头 → client adapter 提取的 Claude Code 会话 ID(`metadata.user_id`)→ 请求体兜底提取 → Codex 原生 `session_id` 头 → 回退每请求 UUID;同一会话内值稳定,命中 Go 的路由与 prompt cache 优化。</li></ul> |
106
106
 
107
107
  > 仅保留最近 10 个版本,更早版本的发布摘要见 [CHANGELOG-archive.md](./CHANGELOG-archive.md),完整详细变更记录见 [CHANGELOG.md](./CHANGELOG.md)。
108
108
 
@@ -1,6 +1,6 @@
1
1
  "use strict";var Fc=Object.create;var sn=Object.defineProperty;var Uc=Object.getOwnPropertyDescriptor;var jc=Object.getOwnPropertyNames;var Hc=Object.getPrototypeOf,zc=Object.prototype.hasOwnProperty;var E=(n,e)=>()=>(n&&(e=n(n=0)),e);var an=(n,e)=>{for(var t in e)sn(n,t,{get:e[t],enumerable:!0})},hs=(n,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of jc(e))!zc.call(n,r)&&r!==t&&sn(n,r,{get:()=>e[r],enumerable:!(o=Uc(e,r))||o.enumerable});return n};var Z=(n,e,t)=>(t=n!=null?Fc(Hc(n)):{},hs(e||!n||!n.__esModule?sn(t,"default",{value:n,enumerable:!0}):t,n)),ys=n=>hs(sn({},"__esModule",{value:!0}),n);function Jc(n){if(n==null)return{ok:!0};let e=String(n).trim();if(!e)return{ok:!0};if(Bc.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 bs(n){let e=[];for(let t of ks){let o=n[t];if(o==null)continue;let r=Jc(o);r.ok||e.push({key:t,error:r.error})}return e}function yt(n){for(let e of ks){let t=n.get(e);if(t==null)continue;let o=String(t).trim();if(o)return o}}function Mo(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 pe(n,e){let t=yt(n);if(t)return Mo(n.get("PROXY_GLOBAL_ENABLED"))||e?.proxyEnabled===!0||e?.proxy_enabled===!0?t:void 0}function Q(n){let e=Wc(n),t=cn.get(e);if(t)return t;let o=new _s.ProxyAgent(e);return cn.set(e,o),o}async function ln(){let n=Array.from(cn.values());cn.clear(),await Promise.allSettled(n.map(e=>e.close()))}function Wc(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 _s,ks,Bc,cn,ae=E(()=>{"use strict";_s=require("undici"),ks=["HTTPS_PROXY","https_proxy","httpsProxy","PROXY_URL"],Bc=/\$\{[^}]+\}|\$[A-Z_][A-Z0-9_]*/;cn=new Map});var _t,No,Ts,vs,De,$o=E(()=>{"use strict";_t=require("fs"),No=require("path"),Ts=require("dotenv"),vs=Z(require("json5"),1);ae();De=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:(0,No.join)(process.cwd(),this.options.jsonPath);if((0,_t.existsSync)(e))try{let t=(0,_t.readFileSync)(e,"utf-8"),o=vs.default.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:(0,No.join)(process.cwd(),this.options.envPath);if((0,_t.existsSync)(e))try{let t=(0,Ts.config)({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 yt(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 G(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 xs(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 un=E(()=>{"use strict"});function dn(n){Lo=n}function kt(){return Lo}function pn(n){return Lo||n.get("DEBUG_LOG")===!0}function Rs(n){let e=n.get("DEBUG_LOG_OPTIONS");return!e||typeof e!="object"?Ge:{maxBodyLength:e.maxBodyLength??Ge.maxBodyLength,maxStreamChunks:e.maxStreamChunks??Ge.maxStreamChunks}}function fn(n){let e={};for(let[t,o]of Object.entries(n))Kc.has(t.toLowerCase())?e[t]="***MASKED***":e[t]=o;return e}function mn(n,e){return n.length<=e?n:n.slice(0,e)+`...[truncated, total ${n.length} bytes]`}function ws(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:fn(t.headers),body:mn(o,Ge.maxBodyLength)})}function Es(n,e,t){n.info({debug_log:!0,reqId:e,phase:"provider_response",status:t.status,headers:fn(t.headers),...t.body!==void 0?{body:mn(t.body,Ge.maxBodyLength)}:{}})}function Cs(n,e,t,o){let r=Gc(o);n.info({debug_log:!0,reqId:e,phase:"provider_stream_chunk",chunkIndex:t,...r?{usage_monitor:r}:{},data:mn(o,Ge.maxBodyLength)})}function Gc(n){let e=[];for(let t of n.split(/\r?\n/)){if(!t.startsWith("data:"))continue;let o=t.slice(5).trim();if(!(!o||o==="[DONE]"))try{let r=JSON.parse(o),s=r?.usage||r?.response?.usage;s&&e.push({path:r?.usage?"usage":"response.usage",usage:s,choicesLength:Array.isArray(r?.choices)?r.choices.length:void 0,finishReason:r?.choices?.[0]?.finish_reason})}catch{e.push({parseError:!0,data:mn(o,512)})}}if(e.length)return e.length===1?e[0]:e}function Ss(n,e,t){n.info({debug_log:!0,reqId:e,phase:"provider_stream_end",totalChunks:t})}function Ps(n,e,t,o){(async()=>{let r=n.pipeThrough(new TextDecoderStream).getReader(),s=0;try{let i="";for(;;){let{done:a,value:l}=await r.read();if(a)break;i+=l;let c=i.split(`
2
2
 
3
- `);i=c.pop()||"";for(let u of c)u.trim()&&(s<o.maxStreamChunks?Cs(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&&Cs(e,t,s,i.trim()),s++),Ss(e,t,s)}catch(i){console.error(`[debug_log] Error reading debug stream for reqId=${t}:`,i),Ss(e,t,s)}finally{r.releaseLock()}})()}var Kc,Ge,Lo,bt=E(()=>{"use strict";Kc=new Set(["authorization","x-api-key","x-goog-api-key","cookie","set-cookie"]),Ge={maxBodyLength:4096,maxStreamChunks:100},Lo=!1});function Os(n,e,t,o,r){let s=new Headers({"Content-Type":"application/json"});t.headers&&Object.entries(t.headers).forEach(([c,u])=>{u&&s.set(c,u)});let i,a=AbortSignal.timeout(t.TIMEOUT??60*1e3*60);if(t.signal){let c=new AbortController,u=()=>c.abort();t.signal.addEventListener("abort",u),a.addEventListener("abort",u),i=c.signal}else i=a;let l={method:"POST",headers:s,body:JSON.stringify(e),signal:i};return t.httpsProxy&&(l.dispatcher=Q(t.httpsProxy)),r?.debug({reqId:o.req.id,method:"POST",headers:fn(Object.fromEntries(s.entries())),requestUrl:typeof n=="string"?n:n.toString(),useProxy:Vc(t.httpsProxy)},"final request"),fetch(typeof n=="string"?n:n.toString(),l)}function Vc(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 As=E(()=>{ae();bt()});var gn,Do=E(()=>{gn="2.3.2413"});var Is={};an(Is,{getFallbackPromotionStore:()=>Ve,resetFallbackPromotionStore:()=>Xc});function Ve(n){return Fe||(Fe=new Fo,n&&Fe.configure(n)),Fe}function Xc(){Fe&&(Fe.clearAll(),Fe=null)}var Yc,Fo,Fe,hn=E(()=>{"use strict";ce();Yc=600*1e3,Fo=class{promotions=new Map;enabled=!0;ttlMs=Yc;configure(e){e?.enabled!==void 0&&(this.enabled=e.enabled),e?.ttlMinutes!==void 0&&(this.ttlMs=e.ttlMinutes*60*1e3)}getKey(e,t,o){return`${e},${t}:${o}`}promote(e,t,o,r,s,i){if(!this.enabled)return;let a=this.getKey(e,t,o),l=`${r},${s}`;this.promotions.set(a,{promotedModel:l,timestamp:Date.now(),ttlMs:i??this.ttlMs})}getPromotion(e,t,o,r){if(!this.enabled)return null;let s=this.getKey(e,t,o),i=this.promotions.get(s);if(!i)return null;if(Date.now()-i.timestamp>=i.ttlMs)return this.promotions.delete(s),null;let[l,...c]=i.promotedModel.split(","),u=c.join(",");if(!j().isAvailable(l,u))return this.promotions.delete(s),null;let p=r.find(h=>h.name.toLowerCase()===l.toLowerCase()),m=p?.models?.find(h=>String(h).toLowerCase()===u.toLowerCase());return!p||!m||p.enabled===!1?(this.promotions.delete(s),null):`${p.name},${m}`}clear(e,t,o){let r=this.getKey(e,t,o);this.promotions.delete(r)}clearByPrimary(e,t){let o=`${e},${t}:`,r=0;for(let s of this.promotions.keys())s.startsWith(o)&&(this.promotions.delete(s),r++);return r}clearAll(){this.promotions.clear()}clearExpired(){let e=Date.now();for(let[t,o]of this.promotions)e-o.timestamp>=o.ttlMs&&this.promotions.delete(t)}getAllPromotions(){let e=Date.now(),t=[];for(let[o,r]of this.promotions){let s=r.ttlMs-(e-r.timestamp);s>0&&t.push({key:o,promotedModel:r.promotedModel,remainingMs:s})}return t}},Fe=null});function tl(n){try{if(!(0,he.existsSync)(Ho))return;let e=JSON.parse((0,he.readFileSync)(Ho,"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 Ns(n){try{let e=n.getAllStates();if(e.length===0)return;(0,he.existsSync)(jo)||(0,he.mkdirSync)(jo,{recursive:!0});let t=e.map(o=>({...o,updatedAt:Date.now()}));(0,he.writeFileSync)(Ho,JSON.stringify(t,null,2),"utf-8")}catch{}}function yn(){if(Ms)return;Ms=!0;let n=j();tl(n),el=setInterval(()=>Ns(n),6e4),process.on("exit",()=>Ns(n))}function j(n){return Uo||(Uo=new Tt(n)),Uo}var he,zo,$s,Zc,qc,Tt,jo,Ho,Ms,el,Uo,ce=E(()=>{"use strict";he=require("fs"),zo=require("path"),$s=require("@wengine-ai/claude-code-router-shared"),Zc=120,qc={enabled:!0,failureThreshold:3,probeIntervalMinutes:5,halfOpenSuccessThreshold:2},Tt=class{states=new Map;config;probeTimer;constructor(e){this.config={...qc,...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}=(hn(),ys(Is));o().clearByPrimary(e,t)}catch{}}recordFailure(e,t,o){if(!this.config.enabled)return;let r=this.getKey(e,t);if(!r)return;let s=this.states.get(r);s||(s={provider:e,model:t,status:"closed",failureCount:0,successCount:0,lastFailureTime:0,lastProbeTime:0},this.states.set(r,s)),s.failureCount++,s.lastFailureTime=Date.now(),s.lastError=o,s.status==="half-open"?(s.status="open",s.successCount=0,s.lastProbeTime=0):s.status==="closed"&&s.failureCount>=this.config.failureThreshold&&(s.status="open",s.lastProbeTime=0)}getState(e,t){let o=this.getKey(e,t);if(o)return this.states.get(o)}isAvailable(e,t){if(!this.config.enabled)return!0;if(!this.getKey(e,t))return!1;let r=this.getState(e,t);return r?r.status==="open"&&r.rateLimitUntil?!(Date.now()<r.rateLimitUntil):r.status!=="open":!0}getPriority(e,t){if(!this.config.enabled)return 0;if(!this.getKey(e,t))return 2;let r=this.getState(e,t);if(!r)return 0;switch(r.status){case"closed":return 0;case"half-open":return 1;case"open":return 2}}getHealthyModels(){return[]}getFailPoolModels(){let e=[];for(let[t,o]of this.states)o.status==="open"&&e.push(t);return e}getHalfOpenModels(){let e=[];for(let[t,o]of this.states)o.status==="half-open"&&e.push(t);return e}forceOpen(e,t,o){if(!this.config.enabled)return;let r=this.getKey(e,t);if(!r)return;let s=this.states.get(r);s?(s.status="open",s.failureCount=Math.max(s.failureCount,this.config.failureThreshold),s.lastFailureTime=Date.now(),s.lastError=o,s.lastProbeTime=0):(s={provider:e,model:t,status:"open",failureCount:this.config.failureThreshold,successCount:0,lastFailureTime:Date.now(),lastProbeTime:0,lastError:o},this.states.set(r,s))}markRateLimited(e,t,o,r){if(!this.config.enabled)return;let s=this.getKey(e,t);if(!s)return;let i=this.states.get(s);i?(i.status="open",i.lastFailureTime=Date.now(),i.lastError=r||"rate-limited",i.lastProbeTime=0):(i={provider:e,model:t,status:"open",failureCount:0,successCount:0,lastFailureTime:Date.now(),lastProbeTime:0,lastError:r||"rate-limited"},this.states.set(s,i));let a=(o??Zc)*1e3;i.rateLimitUntil=Date.now()+a}getRateLimitedModels(){let e=[];for(let[t,o]of this.states)o.status==="open"&&o.rateLimitUntil&&e.push(t);return e}needsProbe(e){return Date.now()-e.lastProbeTime>=this.config.probeIntervalMinutes*60*1e3}markProbeAttempt(e,t){let o=this.getKey(e,t);if(!o)return;let r=this.states.get(o);r&&r.status==="open"&&(r.lastProbeTime=Date.now())}clear(){this.states.clear()}recover(e,t){let o=this.getKey(e,t);o&&this.states.delete(o)}getAllStates(){return Array.from(this.states.values())}restore(e){let t=this.getKey(e.provider,e.model);t&&this.states.set(t,{...e})}stopProbeTimer(){this.probeTimer&&(clearInterval(this.probeTimer),this.probeTimer=void 0)}},jo=(0,zo.join)($s.HOME_DIR,"runtime"),Ho=(0,zo.join)(jo,"provider-health.json"),Ms=!1,el=null;Uo=null});function vt(n,e,t){let o=a=>{if(t instanceof Headers)return t.get(a);let l=Object.keys(t).find(c=>c.toLowerCase()===a);return l?t[l]:null},r=Bo(o,nl),s=Bo(o,ol),i=Bo(o,rl);(r||s||i)&&Qe.set(n,{provider:n,remaining:Fs(r),limit:Fs(s),reset:sl(i),capturedAt:Date.now()})}function Hs(n){return Qe.get(n)}function _n(){return Array.from(Qe.values())}function Bo(n,e){for(let t of e){let o=n(t);if(o)return o}return null}function Fs(n){if(!n)return null;let e=Number(n.trim().replace(/,/g,""));return Number.isFinite(e)?e:null}function sl(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=il(e);return r===null?null:Math.floor((Date.now()+r)/1e3)}function il(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 al(){try{if(!(0,ye.existsSync)(Wo))return;let n=JSON.parse((0,ye.readFileSync)(Wo,"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;Qe.set(t.provider,t)}}catch{}}function Us(){try{if(Qe.size===0)return;(0,ye.existsSync)(Jo)||(0,ye.mkdirSync)(Jo,{recursive:!0}),(0,ye.writeFileSync)(Wo,JSON.stringify(Array.from(Qe.values()),null,2),"utf-8")}catch{}}function Ye(){Ls||(Ls=!0,al(),Ds=setInterval(Us,6e4),Ds.unref?.(),process.on("exit",Us))}var ye,Ko,js,Jo,Wo,Qe,Ls,Ds,nl,ol,rl,Xe=E(()=>{"use strict";ye=require("fs"),Ko=require("path"),js=require("@wengine-ai/claude-code-router-shared"),Jo=(0,Ko.join)(js.HOME_DIR,"runtime"),Wo=(0,Ko.join)(Jo,"rate-limit.json"),Qe=new Map,Ls=!1,Ds=null,nl=["x-ratelimit-remaining-tokens","x-ratelimit-remaining-requests","x-ratelimit-remaining"],ol=["x-ratelimit-limit-tokens","x-ratelimit-limit-requests","x-ratelimit-limit"],rl=["x-ratelimit-reset-tokens","x-ratelimit-reset-requests","x-ratelimit-reset"]});function bn(){return Go||(Go=new Qo),Go}function Xo(){return Vo||(Vo=new Yo),Vo}function cl(n){return n?.sessionId||n?.clientContext?.stableSessionId||void 0}function zs(n){let e=cl(n);if(!e)return"";let t=typeof n?.modelFamily=="string"?n.modelFamily:"",o=typeof n?.scenarioType=="string"&&n.scenarioType?n.scenarioType:"default";return`${e}:${t}:${o}`}function Bs(n,e){let t=bn(),o=n?.[kn];if(o&&!o.released){if(o.key===e)return;t.release(o)}n[kn]=t.acquire(e)}function Zo(n){let e=n?.[kn];e&&bn().release(e)}function Js(n,e){let t=zs(n),o=n?.[kn],r=t?Xo().get(t)!==void 0:!1;!o&&!r||(t&&Xo().bind(t,e),Bs(n,e))}function ll(n,e,t){let o=bn(),r=null,s=1/0;for(let i of e){if(!i||typeof i!="string")continue;let a=t(i);if(!a||a===n)continue;let l=o.count(a);l<s&&(r=a,s=l)}return r}function Ws(n,e,t){let o=zs(n),r=Xo(),s=bn(),i=Number.isFinite(t.threshold)&&t.threshold>0?Math.floor(t.threshold):3,a;if(o){let l=r.get(o);if(l&&l!==e){let c=t.resolve(l);c?(a=c,t.log?.(`Concurrency priority: session slot ${o} sticking to bound model ${c}`)):r.unbind(o)}else l&&(a=e)}if(!a){let l=s.count(e);if(l>=i){let c=ll(e,t.fallbackModels,t.resolve);c&&(a=c,t.log?.(`Concurrency priority: model ${e} has ${l} in-flight request(s) (>= ${i}); assigning ${o?`session slot ${o} `:"request "}to overflow model ${c}`))}a=a||e,o&&r.bind(o,a)}return Bs(n,a),a}var Qo,Yo,Go,Vo,kn,Tn=E(()=>{"use strict";Qo=class{leases=new Map;nextId=1;acquire(e){let t={id:this.nextId++,key:e,createdAt:Date.now(),released:!1};return this.leases.set(t.id,t),t}release(e){!e||e.released||(e.released=!0,this.leases.delete(e.id))}prune(){let e=Date.now();for(let[t,o]of this.leases)e-o.createdAt>18e5&&this.leases.delete(t)}count(e){this.prune();let t=0;for(let o of this.leases.values())o.key===e&&t++;return t}clear(){this.leases.clear()}},Yo=class{bindings=new Map;get(e){let t=this.bindings.get(e);if(t){if(Date.now()-t.updatedAt>864e5){this.bindings.delete(e);return}return t.updatedAt=Date.now(),this.bindings.delete(e),this.bindings.set(e,t),t.modelKey}}bind(e,t){for(this.bindings.delete(e),this.bindings.set(e,{modelKey:t,updatedAt:Date.now()});this.bindings.size>2e3;){let o=this.bindings.keys().next().value;if(o===void 0)break;this.bindings.delete(o)}}unbind(e){this.bindings.delete(e)}clear(){this.bindings.clear()}},Go=null,Vo=null;kn="__concurrencyLease"});async function U(n){let e=await n.text();return ul(e,n.status)}function ul(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 Ks(n){return(n.headers.get("Content-Type")||"").includes("text/event-stream")}function xt(n){return/^\s*(event:|data:|:\s*[A-Z])/m.test(n)||n.startsWith("data:")}async function Ce(n){if(!n.body||n.body.locked)return null;let[e,t]=n.body.tee(),o=e.getReader(),r=new TextDecoder,s="";try{for(let i=0;i<8;i++){let{value:a,done:l}=await o.read();if(l||(a&&(s+=r.decode(a,{stream:!0})),xt(s))||/^\s*[\[{]/.test(s))break}s+=r.decode()}finally{o.releaseLock()}return e.cancel().catch(()=>{}),{body:t,isSSE:xt(s)}}async function Se(n){try{let e=await n.text();if(xt(e)){let o=new TextEncoder,r=new ReadableStream({start(s){s.enqueue(o.encode(e)),s.close()}});return{response:new Response(r,{status:n.status,statusText:n.statusText,headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}}),isSSE:!0}}return{response:new Response(e,{status:n.status,statusText:n.statusText,headers:n.headers}),isSSE:!1}}catch{return{response:n,isSSE:!1}}}var q=E(()=>{"use strict"});var Ze,qo=E(()=>{"use strict";q();Ze=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 Ce(e);if(o?.isSSE&&o.body){let r=new Response(o.body,{status:e.status,statusText:e.statusText,headers:new Headers({...Object.fromEntries(e.headers.entries()),"content-type":"text/event-stream"})});return this.transformResponseOut(r)}if(o?.body)e=new Response(o.body,{status:e.status,statusText:e.statusText,headers:e.headers});else if(o===null){let r=await Se(e);if(r.isSSE)return this.transformResponseOut(r.response);e=r.response}}if(t.includes("application/json")){let o=await U(e);if(o.object==="response"&&o.output){let r=this.convertResponseToChat(o);return new Response(JSON.stringify(r),{status:e.status,statusText:e.statusText,headers:e.headers})}return o.type==="message"&&Array.isArray(o.content)?new Response(JSON.stringify(o),{status:e.status,statusText:e.statusText,headers:e.headers}):new Response(JSON.stringify(o),{status:e.status,statusText:e.statusText,headers:e.headers})}else if(t.includes("text/event-stream")){if(!e.body)return e;let[o,r]=e.body.tee(),s=o.getReader(),i="";try{let{value:f,done:_}=await s.read();!_&&f&&(i=new TextDecoder().decode(f))}finally{s.releaseLock()}if(o.cancel().catch(()=>{}),i.includes("message_start")||i.includes("content_block_start")){let f=this.prependToStream(i,r);return new Response(f,{status:e.status,statusText:e.statusText,headers:e.headers})}if(i.includes("response.created")||i.includes("response.output_text.delta")||i.includes("response.in_progress")||i.includes("response.output_item.added")){let f=this.prependToStream(i,r);return new Response(f,{status:e.status,statusText:e.statusText,headers:e.headers})}let c=this.prependToStream(i,r),u=new TextDecoder,d=new TextEncoder,p="",m=!1,h=this,g=new ReadableStream({async start(f){let _=c.getReader(),k=-1,y="",b=T=>(T!==y&&(k++,y=T),k);try{for(;;){let{done:T,value:C}=await _.read();if(T){m||f.enqueue(d.encode(`data: [DONE]
3
+ `);i=c.pop()||"";for(let u of c)u.trim()&&(s<o.maxStreamChunks?Cs(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&&Cs(e,t,s,i.trim()),s++),Ss(e,t,s)}catch(i){console.error(`[debug_log] Error reading debug stream for reqId=${t}:`,i),Ss(e,t,s)}finally{r.releaseLock()}})()}var Kc,Ge,Lo,bt=E(()=>{"use strict";Kc=new Set(["authorization","x-api-key","x-goog-api-key","cookie","set-cookie"]),Ge={maxBodyLength:4096,maxStreamChunks:100},Lo=!1});function Os(n,e,t,o,r){let s=new Headers({"Content-Type":"application/json"});t.headers&&Object.entries(t.headers).forEach(([c,u])=>{u&&s.set(c,u)});let i,a=AbortSignal.timeout(t.TIMEOUT??60*1e3*60);if(t.signal){let c=new AbortController,u=()=>c.abort();t.signal.addEventListener("abort",u),a.addEventListener("abort",u),i=c.signal}else i=a;let l={method:"POST",headers:s,body:JSON.stringify(e),signal:i};return t.httpsProxy&&(l.dispatcher=Q(t.httpsProxy)),r?.debug({reqId:o.req.id,method:"POST",headers:fn(Object.fromEntries(s.entries())),requestUrl:typeof n=="string"?n:n.toString(),useProxy:Vc(t.httpsProxy)},"final request"),fetch(typeof n=="string"?n:n.toString(),l)}function Vc(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 As=E(()=>{ae();bt()});var gn,Do=E(()=>{gn="2.3.2414"});var Is={};an(Is,{getFallbackPromotionStore:()=>Ve,resetFallbackPromotionStore:()=>Xc});function Ve(n){return Fe||(Fe=new Fo,n&&Fe.configure(n)),Fe}function Xc(){Fe&&(Fe.clearAll(),Fe=null)}var Yc,Fo,Fe,hn=E(()=>{"use strict";ce();Yc=600*1e3,Fo=class{promotions=new Map;enabled=!0;ttlMs=Yc;configure(e){e?.enabled!==void 0&&(this.enabled=e.enabled),e?.ttlMinutes!==void 0&&(this.ttlMs=e.ttlMinutes*60*1e3)}getKey(e,t,o){return`${e},${t}:${o}`}promote(e,t,o,r,s,i){if(!this.enabled)return;let a=this.getKey(e,t,o),l=`${r},${s}`;this.promotions.set(a,{promotedModel:l,timestamp:Date.now(),ttlMs:i??this.ttlMs})}getPromotion(e,t,o,r){if(!this.enabled)return null;let s=this.getKey(e,t,o),i=this.promotions.get(s);if(!i)return null;if(Date.now()-i.timestamp>=i.ttlMs)return this.promotions.delete(s),null;let[l,...c]=i.promotedModel.split(","),u=c.join(",");if(!j().isAvailable(l,u))return this.promotions.delete(s),null;let p=r.find(h=>h.name.toLowerCase()===l.toLowerCase()),m=p?.models?.find(h=>String(h).toLowerCase()===u.toLowerCase());return!p||!m||p.enabled===!1?(this.promotions.delete(s),null):`${p.name},${m}`}clear(e,t,o){let r=this.getKey(e,t,o);this.promotions.delete(r)}clearByPrimary(e,t){let o=`${e},${t}:`,r=0;for(let s of this.promotions.keys())s.startsWith(o)&&(this.promotions.delete(s),r++);return r}clearAll(){this.promotions.clear()}clearExpired(){let e=Date.now();for(let[t,o]of this.promotions)e-o.timestamp>=o.ttlMs&&this.promotions.delete(t)}getAllPromotions(){let e=Date.now(),t=[];for(let[o,r]of this.promotions){let s=r.ttlMs-(e-r.timestamp);s>0&&t.push({key:o,promotedModel:r.promotedModel,remainingMs:s})}return t}},Fe=null});function tl(n){try{if(!(0,he.existsSync)(Ho))return;let e=JSON.parse((0,he.readFileSync)(Ho,"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 Ns(n){try{let e=n.getAllStates();if(e.length===0)return;(0,he.existsSync)(jo)||(0,he.mkdirSync)(jo,{recursive:!0});let t=e.map(o=>({...o,updatedAt:Date.now()}));(0,he.writeFileSync)(Ho,JSON.stringify(t,null,2),"utf-8")}catch{}}function yn(){if(Ms)return;Ms=!0;let n=j();tl(n),el=setInterval(()=>Ns(n),6e4),process.on("exit",()=>Ns(n))}function j(n){return Uo||(Uo=new Tt(n)),Uo}var he,zo,$s,Zc,qc,Tt,jo,Ho,Ms,el,Uo,ce=E(()=>{"use strict";he=require("fs"),zo=require("path"),$s=require("@wengine-ai/claude-code-router-shared"),Zc=120,qc={enabled:!0,failureThreshold:3,probeIntervalMinutes:5,halfOpenSuccessThreshold:2},Tt=class{states=new Map;config;probeTimer;constructor(e){this.config={...qc,...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}=(hn(),ys(Is));o().clearByPrimary(e,t)}catch{}}recordFailure(e,t,o){if(!this.config.enabled)return;let r=this.getKey(e,t);if(!r)return;let s=this.states.get(r);s||(s={provider:e,model:t,status:"closed",failureCount:0,successCount:0,lastFailureTime:0,lastProbeTime:0},this.states.set(r,s)),s.failureCount++,s.lastFailureTime=Date.now(),s.lastError=o,s.status==="half-open"?(s.status="open",s.successCount=0,s.lastProbeTime=0):s.status==="closed"&&s.failureCount>=this.config.failureThreshold&&(s.status="open",s.lastProbeTime=0)}getState(e,t){let o=this.getKey(e,t);if(o)return this.states.get(o)}isAvailable(e,t){if(!this.config.enabled)return!0;if(!this.getKey(e,t))return!1;let r=this.getState(e,t);return r?r.status==="open"&&r.rateLimitUntil?!(Date.now()<r.rateLimitUntil):r.status!=="open":!0}getPriority(e,t){if(!this.config.enabled)return 0;if(!this.getKey(e,t))return 2;let r=this.getState(e,t);if(!r)return 0;switch(r.status){case"closed":return 0;case"half-open":return 1;case"open":return 2}}getHealthyModels(){return[]}getFailPoolModels(){let e=[];for(let[t,o]of this.states)o.status==="open"&&e.push(t);return e}getHalfOpenModels(){let e=[];for(let[t,o]of this.states)o.status==="half-open"&&e.push(t);return e}forceOpen(e,t,o){if(!this.config.enabled)return;let r=this.getKey(e,t);if(!r)return;let s=this.states.get(r);s?(s.status="open",s.failureCount=Math.max(s.failureCount,this.config.failureThreshold),s.lastFailureTime=Date.now(),s.lastError=o,s.lastProbeTime=0):(s={provider:e,model:t,status:"open",failureCount:this.config.failureThreshold,successCount:0,lastFailureTime:Date.now(),lastProbeTime:0,lastError:o},this.states.set(r,s))}markRateLimited(e,t,o,r){if(!this.config.enabled)return;let s=this.getKey(e,t);if(!s)return;let i=this.states.get(s);i?(i.status="open",i.lastFailureTime=Date.now(),i.lastError=r||"rate-limited",i.lastProbeTime=0):(i={provider:e,model:t,status:"open",failureCount:0,successCount:0,lastFailureTime:Date.now(),lastProbeTime:0,lastError:r||"rate-limited"},this.states.set(s,i));let a=(o??Zc)*1e3;i.rateLimitUntil=Date.now()+a}getRateLimitedModels(){let e=[];for(let[t,o]of this.states)o.status==="open"&&o.rateLimitUntil&&e.push(t);return e}needsProbe(e){return Date.now()-e.lastProbeTime>=this.config.probeIntervalMinutes*60*1e3}markProbeAttempt(e,t){let o=this.getKey(e,t);if(!o)return;let r=this.states.get(o);r&&r.status==="open"&&(r.lastProbeTime=Date.now())}clear(){this.states.clear()}recover(e,t){let o=this.getKey(e,t);o&&this.states.delete(o)}getAllStates(){return Array.from(this.states.values())}restore(e){let t=this.getKey(e.provider,e.model);t&&this.states.set(t,{...e})}stopProbeTimer(){this.probeTimer&&(clearInterval(this.probeTimer),this.probeTimer=void 0)}},jo=(0,zo.join)($s.HOME_DIR,"runtime"),Ho=(0,zo.join)(jo,"provider-health.json"),Ms=!1,el=null;Uo=null});function vt(n,e,t){let o=a=>{if(t instanceof Headers)return t.get(a);let l=Object.keys(t).find(c=>c.toLowerCase()===a);return l?t[l]:null},r=Bo(o,nl),s=Bo(o,ol),i=Bo(o,rl);(r||s||i)&&Qe.set(n,{provider:n,remaining:Fs(r),limit:Fs(s),reset:sl(i),capturedAt:Date.now()})}function Hs(n){return Qe.get(n)}function _n(){return Array.from(Qe.values())}function Bo(n,e){for(let t of e){let o=n(t);if(o)return o}return null}function Fs(n){if(!n)return null;let e=Number(n.trim().replace(/,/g,""));return Number.isFinite(e)?e:null}function sl(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=il(e);return r===null?null:Math.floor((Date.now()+r)/1e3)}function il(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 al(){try{if(!(0,ye.existsSync)(Wo))return;let n=JSON.parse((0,ye.readFileSync)(Wo,"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;Qe.set(t.provider,t)}}catch{}}function Us(){try{if(Qe.size===0)return;(0,ye.existsSync)(Jo)||(0,ye.mkdirSync)(Jo,{recursive:!0}),(0,ye.writeFileSync)(Wo,JSON.stringify(Array.from(Qe.values()),null,2),"utf-8")}catch{}}function Ye(){Ls||(Ls=!0,al(),Ds=setInterval(Us,6e4),Ds.unref?.(),process.on("exit",Us))}var ye,Ko,js,Jo,Wo,Qe,Ls,Ds,nl,ol,rl,Xe=E(()=>{"use strict";ye=require("fs"),Ko=require("path"),js=require("@wengine-ai/claude-code-router-shared"),Jo=(0,Ko.join)(js.HOME_DIR,"runtime"),Wo=(0,Ko.join)(Jo,"rate-limit.json"),Qe=new Map,Ls=!1,Ds=null,nl=["x-ratelimit-remaining-tokens","x-ratelimit-remaining-requests","x-ratelimit-remaining"],ol=["x-ratelimit-limit-tokens","x-ratelimit-limit-requests","x-ratelimit-limit"],rl=["x-ratelimit-reset-tokens","x-ratelimit-reset-requests","x-ratelimit-reset"]});function bn(){return Go||(Go=new Qo),Go}function Xo(){return Vo||(Vo=new Yo),Vo}function cl(n){return n?.sessionId||n?.clientContext?.stableSessionId||void 0}function zs(n){let e=cl(n);if(!e)return"";let t=typeof n?.modelFamily=="string"?n.modelFamily:"",o=typeof n?.scenarioType=="string"&&n.scenarioType?n.scenarioType:"default";return`${e}:${t}:${o}`}function Bs(n,e){let t=bn(),o=n?.[kn];if(o&&!o.released){if(o.key===e)return;t.release(o)}n[kn]=t.acquire(e)}function Zo(n){let e=n?.[kn];e&&bn().release(e)}function Js(n,e){let t=zs(n),o=n?.[kn],r=t?Xo().get(t)!==void 0:!1;!o&&!r||(t&&Xo().bind(t,e),Bs(n,e))}function ll(n,e,t){let o=bn(),r=null,s=1/0;for(let i of e){if(!i||typeof i!="string")continue;let a=t(i);if(!a||a===n)continue;let l=o.count(a);l<s&&(r=a,s=l)}return r}function Ws(n,e,t){let o=zs(n),r=Xo(),s=bn(),i=Number.isFinite(t.threshold)&&t.threshold>0?Math.floor(t.threshold):3,a;if(o){let l=r.get(o);if(l&&l!==e){let c=t.resolve(l);c?(a=c,t.log?.(`Concurrency priority: session slot ${o} sticking to bound model ${c}`)):r.unbind(o)}else l&&(a=e)}if(!a){let l=s.count(e);if(l>=i){let c=ll(e,t.fallbackModels,t.resolve);c&&(a=c,t.log?.(`Concurrency priority: model ${e} has ${l} in-flight request(s) (>= ${i}); assigning ${o?`session slot ${o} `:"request "}to overflow model ${c}`))}a=a||e,o&&r.bind(o,a)}return Bs(n,a),a}var Qo,Yo,Go,Vo,kn,Tn=E(()=>{"use strict";Qo=class{leases=new Map;nextId=1;acquire(e){let t={id:this.nextId++,key:e,createdAt:Date.now(),released:!1};return this.leases.set(t.id,t),t}release(e){!e||e.released||(e.released=!0,this.leases.delete(e.id))}prune(){let e=Date.now();for(let[t,o]of this.leases)e-o.createdAt>18e5&&this.leases.delete(t)}count(e){this.prune();let t=0;for(let o of this.leases.values())o.key===e&&t++;return t}clear(){this.leases.clear()}},Yo=class{bindings=new Map;get(e){let t=this.bindings.get(e);if(t){if(Date.now()-t.updatedAt>864e5){this.bindings.delete(e);return}return t.updatedAt=Date.now(),this.bindings.delete(e),this.bindings.set(e,t),t.modelKey}}bind(e,t){for(this.bindings.delete(e),this.bindings.set(e,{modelKey:t,updatedAt:Date.now()});this.bindings.size>2e3;){let o=this.bindings.keys().next().value;if(o===void 0)break;this.bindings.delete(o)}}unbind(e){this.bindings.delete(e)}clear(){this.bindings.clear()}},Go=null,Vo=null;kn="__concurrencyLease"});async function U(n){let e=await n.text();return ul(e,n.status)}function ul(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 Ks(n){return(n.headers.get("Content-Type")||"").includes("text/event-stream")}function xt(n){return/^\s*(event:|data:|:\s*[A-Z])/m.test(n)||n.startsWith("data:")}async function Ce(n){if(!n.body||n.body.locked)return null;let[e,t]=n.body.tee(),o=e.getReader(),r=new TextDecoder,s="";try{for(let i=0;i<8;i++){let{value:a,done:l}=await o.read();if(l||(a&&(s+=r.decode(a,{stream:!0})),xt(s))||/^\s*[\[{]/.test(s))break}s+=r.decode()}finally{o.releaseLock()}return e.cancel().catch(()=>{}),{body:t,isSSE:xt(s)}}async function Se(n){try{let e=await n.text();if(xt(e)){let o=new TextEncoder,r=new ReadableStream({start(s){s.enqueue(o.encode(e)),s.close()}});return{response:new Response(r,{status:n.status,statusText:n.statusText,headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}}),isSSE:!0}}return{response:new Response(e,{status:n.status,statusText:n.statusText,headers:n.headers}),isSSE:!1}}catch{return{response:n,isSSE:!1}}}var q=E(()=>{"use strict"});var Ze,qo=E(()=>{"use strict";q();Ze=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 Ce(e);if(o?.isSSE&&o.body){let r=new Response(o.body,{status:e.status,statusText:e.statusText,headers:new Headers({...Object.fromEntries(e.headers.entries()),"content-type":"text/event-stream"})});return this.transformResponseOut(r)}if(o?.body)e=new Response(o.body,{status:e.status,statusText:e.statusText,headers:e.headers});else if(o===null){let r=await Se(e);if(r.isSSE)return this.transformResponseOut(r.response);e=r.response}}if(t.includes("application/json")){let o=await U(e);if(o.object==="response"&&o.output){let r=this.convertResponseToChat(o);return new Response(JSON.stringify(r),{status:e.status,statusText:e.statusText,headers:e.headers})}return o.type==="message"&&Array.isArray(o.content)?new Response(JSON.stringify(o),{status:e.status,statusText:e.statusText,headers:e.headers}):new Response(JSON.stringify(o),{status:e.status,statusText:e.statusText,headers:e.headers})}else if(t.includes("text/event-stream")){if(!e.body)return e;let[o,r]=e.body.tee(),s=o.getReader(),i="";try{let{value:f,done:_}=await s.read();!_&&f&&(i=new TextDecoder().decode(f))}finally{s.releaseLock()}if(o.cancel().catch(()=>{}),i.includes("message_start")||i.includes("content_block_start")){let f=this.prependToStream(i,r);return new Response(f,{status:e.status,statusText:e.statusText,headers:e.headers})}if(i.includes("response.created")||i.includes("response.output_text.delta")||i.includes("response.in_progress")||i.includes("response.output_item.added")){let f=this.prependToStream(i,r);return new Response(f,{status:e.status,statusText:e.statusText,headers:e.headers})}let c=this.prependToStream(i,r),u=new TextDecoder,d=new TextEncoder,p="",m=!1,h=this,g=new ReadableStream({async start(f){let _=c.getReader(),k=-1,y="",b=T=>(T!==y&&(k++,y=T),k);try{for(;;){let{done:T,value:C}=await _.read();if(T){m||f.enqueue(d.encode(`data: [DONE]
4
4
 
5
5
  `));break}let v=u.decode(C,{stream:!0});p+=v;let S=p.split(/\r?\n/);p=S.pop()||"";for(let x of S)if(x.trim())try{if(x.startsWith("event: "))continue;if(x.startsWith("data: ")){let w=x.slice(5).trim();if(w==="[DONE]"){m=!0,f.enqueue(d.encode(`data: [DONE]
6
6