@wengine-ai/llms 2.1.11 → 2.1.27
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 +11 -0
- package/dist/cjs/server.cjs +3 -3
- package/dist/cjs/server.cjs.map +3 -3
- package/dist/esm/server.mjs +3 -3
- package/dist/esm/server.mjs.map +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -88,6 +88,17 @@ npm install -g @wengine-ai/claude-code-router-next
|
|
|
88
88
|
npm install -g @wengine-ai/claude-code-router-next@latest && ccr restart
|
|
89
89
|
```
|
|
90
90
|
|
|
91
|
+
### 📅 升级功能列表 (Changelog)
|
|
92
|
+
|
|
93
|
+
| 版本 | 发布内容 |
|
|
94
|
+
| --- | --- |
|
|
95
|
+
| **v2.1.26** | <ul><li>**修复 Anthropic Transformer URI 覆盖问题**:当 `Anthropic` 与 DeepSeek/OpenAI 兼容提供商组合使用时,不再把 `chat/completions` 端点错误改写为 `/v1/messages`,避免 DeepSeek 返回 404。</li><li>**协议转换边界收紧**:仅当 provider 的 `api_base_url` 明确指向 `/messages` 端点时,才将请求体转换为 Anthropic messages 结构。</li></ul> |
|
|
96
|
+
| **v2.1.25** | <ul><li>**修复新版 Claude Code (v2.1.154+) 422 报错**:完美解决请求 `/v1/messages` 兼容提供商时因 messages 数组中包含 `role: "system"` 造成的 400/422 报错。</li><li>**动态 Passthrough 绕过自愈**:强制拦截带有 system 消息的 Anthropic 兼容提供商透传,自动进行双向协议规范化与 system 字段合并。</li><li>**响应无损透传修复**:支持目标为 Anthropic 协议响应的原样直出,解决了第三方接口转发时“请求成功但无数据返回”的重大漏洞。</li></ul> |
|
|
97
|
+
| **v2.1.22** | <ul><li>**提供商定时唤醒功能 (定时唤醒)**:新增通用及提供商级别的清晨定时自动重置/唤醒机制,通过发送 dummy 消息提前激活额度。</li><li>**对称用量展示面板**:将 Web 控制台的用量统计网格从 8 张卡片升级为更美观对称的 10 卡片布局。</li><li>**高级用量指标统计**:新增对缓存命中率 (Cache Hit Rate) 及生成速度 (Average Speed) 的多维度计算与动态展示。</li></ul> |
|
|
98
|
+
| **v2.1.7** | <ul><li>**Gemini 思考模式签名支持**:完美支持 Gemini 思考模式 (thinking mode) 及思维链签名 (thought_signature),防止转发时出现 400 校验异常并拦截 API Key 泄露。</li><li>**系统级调试日志面板**:引入运行时一键切换的系统调试日志,与 Web 控制台深度集成,提供实时请求响应细节。</li></ul> |
|
|
99
|
+
| **v2.1.2** | <ul><li>**状态栏 Token 缓存计数**:支持 CLI 状态栏 (statusline) 中的 Token 计数正确显示缓存命中详情,并在响应速度及文字格式上完成多项优化。</li></ul> |
|
|
100
|
+
| **v2.0.87** | <ul><li>**Web 控制台额度支持**:正式打通并适配智谱 GLM 与百炼 Qwen 等主流渠道的额度使用详情实时分析。</li><li>**健康失败记录优化**:修复 HTTP 429 速率限制请求在健康监测系统中未被记录为失败并导致熔断延迟的 Bug。</li></ul> |
|
|
101
|
+
|
|
91
102
|
### 2. 配置
|
|
92
103
|
|
|
93
104
|
创建并配置您的 `~/.claude-code-router/config.json` 文件。有关更多详细信息,您可以参考 `config.example.json`。
|
package/dist/cjs/server.cjs
CHANGED
|
@@ -71,10 +71,10 @@ ${this.toMarkdown(o,r+1)}`:`${n}- ${o}`).join(`
|
|
|
71
71
|
${this.toMarkdown(s,r+1)}`:`${n}${o}: ${s}`).join(`
|
|
72
72
|
`):`${n}${e}`}async output(e,r={}){try{let n=this.formatData(e,r);switch(this.config.level||"log"){case"info":console.info(n);break;case"warn":console.warn(n);break;case"error":console.error(n);break;case"debug":console.debug(n);break;case"log":default:console.log(n);break}return!0}catch(n){return console.error("[ConsoleOutputHandler] Output failed:",n),!1}}}});var Ds,_f=Me(()=>{"use strict";Ds=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 r=Buffer.from(`${this.config.auth.username}:${this.config.auth.password}`).toString("base64");e.Authorization=`Basic ${r}`}break;case"custom":this.config.auth.custom&&(e[this.config.auth.custom.header]=this.config.auth.custom.value);break}return e}buildBody(e,r){let{format:n="json",timestamp:o=!0,prefix:s,metadata:a}=r||{},c={data:e};return o&&(c.timestamp=new Date().toISOString()),s&&(c.prefix=s),a&&Object.keys(a).length>0&&(c.metadata=a),c}async sendRequest(e,r,n,o,s){let a=new AbortController,c=setTimeout(()=>a.abort(),s);try{let l=await fetch(e,{method:r,headers:n,body:JSON.stringify(o),signal:a.signal});if(clearTimeout(c),!l.ok)throw new Error(`HTTP ${l.status}: ${l.statusText}`);return l}catch(l){throw clearTimeout(c),l}}delay(e){return new Promise(r=>setTimeout(r,e))}async sendWithRetry(e,r,n,o,s,a){let c=null;for(let l=1;l<=a.maxAttempts;l++)try{return await this.sendRequest(e,r,n,o,s)}catch(d){if(c=d,l===a.maxAttempts)break;let f=a.backoffMs*Math.pow(2,l-1);console.warn(`[WebhookOutputHandler] Request failed (attempt ${l}/${a.maxAttempts}), retrying in ${f}ms...`,d.message),await this.delay(f)}throw c}async output(e,r={}){let n=r.timeout||this.defaultTimeout;try{let o=this.buildHeaders(),s=this.buildBody(e,r),a=await this.sendWithRetry(this.config.url,this.config.method,o,s,n,this.config.retry);return!0}catch(o){let s=o instanceof Error?o.message:String(o);if(this.config.silent)return console.error(`[WebhookOutputHandler] Failed to send data: ${s}`),!1;throw new Error(`Webhook output failed: ${s}`)}}}});var So,bf,m_,Rs,Cf=Me(()=>{"use strict";So=require("fs"),bf=require("path"),m_=require("os"),Rs=class{type="temp-file";config;baseDir;constructor(e={}){this.config={subdirectory:"claude-code-router",extension:"json",includeTimestamp:!1,prefix:"session",...e};let r=(0,m_.tmpdir)();this.baseDir=(0,bf.join)(r,this.config.subdirectory),this.ensureDir()}ensureDir(){try{(0,So.existsSync)(this.baseDir)||(0,So.mkdirSync)(this.baseDir,{recursive:!0})}catch{}}extractSessionId(e){try{let r=e.match(/_session_([a-f0-9-]+)/i);return r?r[1]:null}catch{return null}}getFilePath(e){let r=this.config.prefix||"session",n=this.config.extension?`.${this.config.extension}`:"",o;if(this.config.includeTimestamp){let s=Date.now();o=`${r}-${e}-${s}${n}`}else o=`${r}-${e}${n}`;return(0,bf.join)(this.baseDir,o)}async output(e,r={}){try{let n=r.metadata?.sessionId;if(!n)return!1;let o={...e,timestamp:Date.now(),sessionId:n},s=this.getFilePath(n);return(0,So.writeFileSync)(s,JSON.stringify(o,null,2),"utf-8"),!0}catch{return!1}}getBaseDir(){return this.baseDir}}});var wf,ko,g_=Me(()=>{"use strict";yf();_f();Cf();wf=class{handlers=new Map;defaultOptions={};registerHandler(e,r){this.handlers.set(e,r)}registerHandlers(e){for(let r of e)if(r.enabled!==!1)try{let n=this.createHandler(r),o=r.type+"_"+Date.now();this.registerHandler(o,n)}catch(n){console.error(`[OutputManager] Failed to register ${r.type} handler:`,n)}}createHandler(e){switch(e.type){case"console":return new Ts(e.config);case"webhook":return new Ds(e.config);case"temp-file":return new Rs(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,r){let n={...this.defaultOptions,...r},o={success:[],failed:[]},s=Array.from(this.handlers.entries()).map(async([a,c])=>{try{await c.output(e,n)?o.success.push(a):o.failed.push(a)}catch(l){console.error(`[OutputManager] Handler ${a} failed:`,l),o.failed.push(a)}});return await Promise.all(s),o}async outputTo(e,r,n){let o={...this.defaultOptions,...n},s={success:[],failed:[]},a=e.map(async c=>{let l=this.handlers.get(c);if(!l){console.warn(`[OutputManager] Handler ${c} not found`),s.failed.push(c);return}try{await l.output(r,o)?s.success.push(c):s.failed.push(c)}catch(d){console.error(`[OutputManager] Handler ${c} failed:`,d),s.failed.push(c)}});return await Promise.all(a),s}async outputToType(e,r,n){let o=Array.from(this.handlers.entries()).filter(([s,a])=>a.type===e).map(([s])=>s);return this.outputTo(o,r,n)}},ko=new wf});var JD={};ii(JD,{ActiveProbeService:()=>ks,ConfigService:()=>fn,ProviderHealthStore:()=>jo,ProviderService:()=>pn,SSEParserTransform:()=>Dn,SSESerializerTransform:()=>vs,TokenizerService:()=>Tn,TransformerService:()=>vn,calculateTokenCount:()=>Zd,default:()=>GD,getActiveProbeService:()=>df,getAllQuotaResults:()=>t_,getAllRateLimitInfo:()=>ip,getHealthStore:()=>Xe,getQuotaAdapter:()=>gu,getQuotaResult:()=>lu,getRateLimitInfo:()=>sp,getRuntimeDebugLog:()=>Jh,initQuotaStorePersistence:()=>r_,initRateLimitPersistence:()=>ap,pluginManager:()=>hf,resetActiveProbeService:()=>c_,rewriteStream:()=>gf,router:()=>mu,searchProjectBySession:()=>ef,sessionUsageCache:()=>uu,setRuntimeDebugLog:()=>Gh,startActiveProbe:()=>yu,stopActiveProbe:()=>_u,storeQuotaResult:()=>cu,tokenSpeedPlugin:()=>Af});module.exports=Dh(JD);var C_=Oe(require("fastify"),1),w_=Oe(require("@fastify/cors"),1);var No=require("fs"),rc=require("path"),Lh=require("dotenv"),Uh=Oe(tc(),1),fn=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,rc.join)(process.cwd(),this.options.jsonPath);if((0,No.existsSync)(e))try{let r=(0,No.readFileSync)(e,"utf-8"),n=Uh.default.parse(r);this.config={...this.config,...n},console.log(`Loaded JSON config from: ${e}`)}catch(r){console.warn(`Failed to load JSON config from ${e}:`,r)}else console.warn(`JSON config file not found: ${e}`)}loadEnvConfig(){let e=this.isAbsolutePath(this.options.envPath)?this.options.envPath:(0,rc.join)(process.cwd(),this.options.envPath);if((0,No.existsSync)(e))try{let r=(0,Lh.config)({path:e});r.parsed&&(this.config={...this.config,...this.parseEnvConfig(r.parsed)})}catch(r){console.warn(`Failed to load .env config from ${e}:`,r)}}loadEnvironmentVariables(){let e=this.parseEnvConfig(process.env);this.config={...this.config,...e}}parseEnvConfig(e){let r={};return Object.assign(r,e),r}isAbsolutePath(e){return e.startsWith("/")||e.includes(":")}get(e,r){let n=this.config[e];return n!==void 0?n:r}getAll(){return{...this.config}}getHttpsProxy(){return this.get("HTTPS_PROXY")||this.get("https_proxy")||this.get("httpsProxy")||this.get("PROXY_URL")}has(e){return this.config[e]!==void 0}set(e,r){this.config[e]=r}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 rt(t,e=500,r="internal_error",n="api_error"){let o=new Error(t);return o.statusCode=e,o.code=r,o.type=n,o}async function $h(t,e,r){e.log.error(t);let n=t.statusCode||500;if(t.rawBody)try{let s=JSON.parse(t.rawBody);return r.code(n).send(s)}catch{return r.code(n).send(t.rawBody)}let o={error:{message:t.message+(t.stack||"Internal Server Error"),type:t.type||"api_error",code:t.code||"internal_error"}};return r.code(n).send(o)}var qh=require("undici");function zh(t,e,r,n,o){let s=new Headers({"Content-Type":"application/json"});r.headers&&Object.entries(r.headers).forEach(([d,f])=>{f&&s.set(d,f)});let a,c=AbortSignal.timeout(r.TIMEOUT??60*1e3*60);if(r.signal){let d=new AbortController,f=()=>d.abort();r.signal.addEventListener("abort",f),c.addEventListener("abort",f),a=d.signal}else a=c;let l={method:"POST",headers:s,body:JSON.stringify(e),signal:a};return r.httpsProxy&&(l.dispatcher=new qh.ProxyAgent(new URL(r.httpsProxy).toString())),o?.debug({reqId:n.req.id,request:l,headers:Object.fromEntries(s.entries()),requestUrl:typeof t=="string"?t:t.toString(),useProxy:r.httpsProxy},"final request"),fetch(typeof t=="string"?t:t.toString(),l)}var gC=new Set(["authorization","x-api-key","x-goog-api-key","cookie","set-cookie"]),zn={maxBodyLength:4096,maxStreamChunks:100},nc=!1;function Gh(t){nc=t}function Jh(){return nc}function di(t){return nc||t.get("DEBUG_LOG")===!0}function Vh(t){let e=t.get("DEBUG_LOG_OPTIONS");return!e||typeof e!="object"?zn:{maxBodyLength:e.maxBodyLength??zn.maxBodyLength,maxStreamChunks:e.maxStreamChunks??zn.maxStreamChunks}}function Kh(t){let e={};for(let[r,n]of Object.entries(t))gC.has(r.toLowerCase())?e[r]="***MASKED***":e[r]=n;return e}function oc(t,e){return t.length<=e?t:t.slice(0,e)+`...[truncated, total ${t.length} bytes]`}function Yh(t,e,r){let n=typeof r.body=="string"?r.body:JSON.stringify(r.body);t.info({debug_log:!0,reqId:e,phase:"provider_request",url:r.url,headers:Kh(r.headers),body:oc(n,zn.maxBodyLength)})}function Qh(t,e,r){t.info({debug_log:!0,reqId:e,phase:"provider_response",status:r.status,headers:Kh(r.headers),...r.body!==void 0?{body:oc(r.body,zn.maxBodyLength)}:{}})}function Hh(t,e,r,n){t.info({debug_log:!0,reqId:e,phase:"provider_stream_chunk",chunkIndex:r,data:oc(n,zn.maxBodyLength)})}function Wh(t,e,r){t.info({debug_log:!0,reqId:e,phase:"provider_stream_end",totalChunks:r})}function Xh(t,e,r,n){(async()=>{let o=t.pipeThrough(new TextDecoderStream).getReader(),s=0;try{let a="";for(;;){let{done:c,value:l}=await o.read();if(c)break;a+=l;let d=a.split(`
|
|
73
73
|
|
|
74
|
-
`);a=d.pop()||"";for(let f of d)f.trim()&&(s<n.maxStreamChunks?Hh(e,r,s,f):s===n.maxStreamChunks&&e.info({debug_log:!0,reqId:r,phase:"provider_stream_chunk_omitted",message:`[chunks after #${s} omitted, maxStreamChunks=${n.maxStreamChunks}]`}),s++)}a.trim()&&(s<n.maxStreamChunks&&Hh(e,r,s,a.trim()),s++),Wh(e,r,s)}catch(a){console.error(`[debug_log] Error reading debug stream for reqId=${r}:`,a),Wh(e,r,s)}finally{o.releaseLock()}})()}var Zh="2.1.11";Hn();var Er=require("fs"),lc=require("path"),op=require("@wengine-ai/claude-code-router-shared"),uc=(0,lc.join)(op.HOME_DIR,"runtime"),cc=(0,lc.join)(uc,"rate-limit.json"),Wn=new Map,tp=!1,wC=null,EC=["x-ratelimit-remaining-tokens","x-ratelimit-remaining-requests","x-ratelimit-remaining"],AC=["x-ratelimit-limit-tokens","x-ratelimit-limit-requests","x-ratelimit-limit"],SC=["x-ratelimit-reset-tokens","x-ratelimit-reset-requests","x-ratelimit-reset"];function Lo(t,e,r){let n=c=>{if(r instanceof Headers)return r.get(c);let l=Object.keys(r).find(d=>d.toLowerCase()===c);return l?r[l]:null},o=ac(n,EC),s=ac(n,AC),a=ac(n,SC);(o||s||a)&&Wn.set(t,{provider:t,remaining:rp(o),limit:rp(s),reset:kC(a),capturedAt:Date.now()})}function sp(t){return Wn.get(t)}function ip(){return Array.from(Wn.values())}function ac(t,e){for(let r of e){let n=t(r);if(n)return n}return null}function rp(t){if(!t)return null;let e=Number(t.trim().replace(/,/g,""));return Number.isFinite(e)?e:null}function kC(t){if(!t)return null;let e=t.trim();if(!e)return null;let r=Number(e);if(Number.isFinite(r))return r>1e12?Math.floor(r/1e3):r>1e9?Math.floor(r):Math.floor(Date.now()/1e3+r);let n=Date.parse(e);if(Number.isFinite(n))return Math.floor(n/1e3);let o=vC(e);return o===null?null:Math.floor((Date.now()+o)/1e3)}function vC(t){let e=/(\d+(?:\.\d+)?)(ms|s|m|h|d)/gi,r=0,n=!1;for(let o of t.matchAll(e)){n=!0;let s=Number(o[1]),a=o[2].toLowerCase();if(Number.isFinite(s))switch(a){case"ms":r+=s;break;case"s":r+=s*1e3;break;case"m":r+=s*60*1e3;break;case"h":r+=s*60*60*1e3;break;case"d":r+=s*24*60*60*1e3;break}}return n?r:null}function TC(){try{if(!(0,Er.existsSync)(cc))return;let t=JSON.parse((0,Er.readFileSync)(cc,"utf-8"));if(!Array.isArray(t))return;let e=Date.now();for(let r of t)if(r&&r.provider){if(r.capturedAt&&e-r.capturedAt>3600*1e3)continue;Wn.set(r.provider,r)}}catch{}}function np(){try{if(Wn.size===0)return;(0,Er.existsSync)(uc)||(0,Er.mkdirSync)(uc,{recursive:!0}),(0,Er.writeFileSync)(cc,JSON.stringify(Array.from(Wn.values()),null,2),"utf-8")}catch{}}function ap(){tp||(tp=!0,TC(),wC=setInterval(np,6e4),process.on("exit",np))}fi();async function DC(t,e,r,n){let o=t.body,s=t.provider,a=r.providerService.getProvider(s);if(!a)throw rt(`Provider '${s}' not found`,404,"provider_not_found");try{let{requestBody:c,config:l,bypass:d}=await up(o,a,n,t.headers,{req:t}),f=await cp(c,l,a,r,d,n,{req:t});try{a?.baseUrl&&f?.headers&&Lo(s,a.baseUrl,f.headers)}catch{}let p=await lp(c,f,a,n,d,{req:t}),g=dp(p,e,o,r);try{let A=o.model||t.originalModel;s&&A&&Xe().recordSuccess(s,A)}catch{}return g}catch(c){let l=await RC(t,e,r,n,c);if(l)return l;throw c}}async function RC(t,e,r,n,o){let s=t.scenarioType||"default",a=t.familyFallback,c=t.modelFamily,l=r.configService.get("fallback"),d=Xe(),f=t.provider||"",p=t.body.model||"",g=new Set;if(f&&p&&(d.recordFailure(f,p,o?.message),g.add(`${f},${p}`),r.recordUsage?.({provider:f,model:p,originalModel:t.originalModel||p,scenarioType:s,modelFamily:t.modelFamily,errorMessage:o?.message||String(o),sessionId:t.usageSessionId||t.id,stream:t.body.stream,inputTokens:t.tokenCount||0})),!r.configService.get("Router")?.enableFallback)return t.log.info("Fallback disabled by configuration, skipping fallback attempts"),null;let w=m=>{let[v,...b]=m.split(","),S=v?.trim(),D=b.join(",").trim();return!S||!D?null:{provider:S,model:D,key:`${S},${D}`}},y=[];if(c){let m=a?.[s];Array.isArray(m)&&m.length>0?y.push({name:`${c}/${s}`,models:m}):t.log.warn(`No ${c} fallback configured for ${s}; will try global ${s} fallback`)}if(Array.isArray(l?.[s])&&l[s].length>0&&y.push({name:`global/${s}`,models:l[s]}),y.length===0)return null;let _=y.reduce((m,v)=>m+v.models.length,0);t.log.warn(`Request failed for ${s}, trying ${_} fallback models across ${y.length} fallback stage(s)`);for(let m of y){t.log.info(`Trying ${m.name} fallback stage with ${m.models.length} models`);for(let v of m.models){let b=w(v);if(!b){t.log.warn(`Fallback model '${v}' is invalid, skipping`);continue}if(g.has(b.key))continue;g.add(b.key);let S=b.provider,D=b.model;try{if(!d.isAvailable(S,D)){t.log.warn(`Fallback model ${v} unavailable (fail pool), skipping`);continue}t.log.info(`Trying fallback model: ${v}`);let O={...t.body};O.model=D;let q={...t,provider:S,body:O},J=r.providerService.getProvider(S);if(!J){t.log.warn(`Fallback provider '${S}' not found, skipping`);continue}if(J.enabled===!1){t.log.warn(`Fallback provider '${S}' is disabled, skipping`);continue}let{requestBody:B,config:Y,bypass:te}=await up(O,J,n,t.headers,{req:q}),Z=await cp(B,Y,J,r,te,n,{req:q});try{J?.baseUrl&&Z?.headers&&Lo(S,J.baseUrl,Z.headers)}catch{}let ae=await lp(B,Z,J,n,te,{req:q});return t.log.info(`Fallback model ${v} succeeded`),d.recordSuccess(S,D),f&&p&&(Mo().promote(f,p,s,S,D),t.log.info(`Promoted fallback model ${S},${D} for ${f},${p}:${s}`),d.forceOpen(f,p,o?.message),t.log.info(`Marked original model ${f},${p} as unavailable`)),t.provider=S,t.body=O,dp(ae,e,O,r)}catch(O){d.recordFailure(S,D,O.message),t.log.warn(`Fallback model ${b.key} failed: ${O.message}`),r.recordUsage?.({provider:S,model:D,originalModel:t.body.model,scenarioType:s,modelFamily:t.modelFamily,errorMessage:O.message,sessionId:t.usageSessionId||t.id,stream:t.body.stream});continue}}}return t.log.error(`All fallback models failed for ${s}`),null}async function up(t,e,r,n,o){let s=JSON.parse(JSON.stringify(t)),a={},c=!1;if(c=xC(e,r,t),c&&(n instanceof Headers?n.delete("content-length"):delete n["content-length"],a.headers=n),!c&&typeof r.transformRequestOut=="function"){let l=await r.transformRequestOut(s);l.body?(s=l.body,a=l.config||{}):s=l}if(!c&&e.transformer?.use?.length)for(let l of e.transformer.use){if(!l||typeof l.transformRequestIn!="function")continue;let d=await l.transformRequestIn(s,e,o);d.body?(s=d.body,a={...a,...d.config}):s=d}if(!c&&e.transformer?.[t.model]?.use?.length)for(let l of e.transformer[t.model].use)!l||typeof l.transformRequestIn!="function"||(s=await l.transformRequestIn(s,e,o));return{requestBody:s,config:a,bypass:c}}function xC(t,e,r){return r?.messages?.some(o=>o.role==="system")?!1:t.transformer?.use?.length===1&&t.transformer.use[0].name===e.name&&(!t.transformer?.[r.model]?.use.length||t.transformer?.[r.model]?.use.length===1&&t.transformer?.[r.model]?.use[0].name===e.name)}async function cp(t,e,r,n,o,s,a){let c=e.url||new URL(r.baseUrl);if(!e.TIMEOUT){let f=n.configService.get("API_TIMEOUT_MS");f&&(e.TIMEOUT=typeof f=="string"?parseInt(f,10):f)}if(o&&typeof s.auth=="function"){let f=await s.auth(t,r);if(f.body){t=f.body;let p=e.headers||{};f.config?.headers&&(p={...p,...f.config.headers},delete p.host,delete f.config.headers),e={...e,...f.config,headers:p}}else t=f}let l={Authorization:`Bearer ${r.apiKey}`,...e?.headers||{}};for(let f in l)(l[f]==="undefined"||["authorization","Authorization"].includes(f)&&l[f]?.includes("undefined"))&&delete l[f];di(n.configService)&&Yh(n.log,a.req.id,{url:String(c),headers:l,body:t});let d=await zh(c,t,{httpsProxy:n.configService.getHttpsProxy(),...e,headers:JSON.parse(JSON.stringify(l))},a,n.log);if(!d.ok){let f=await d.text();n.log.error(`[provider_response_error] Error from provider(${r.name},${t.model}: ${d.status}): ${f}`);let p=rt(`Error from provider(${r.name},${t.model}: ${d.status}): ${f}`,d.status,"provider_response_error");throw p.rawBody=f,p}if(d.ok&&(d.headers.get("content-type")||"").includes("application/json")){let p=d.clone();try{let g=await p.text(),A=JSON.parse(g);if(A&&typeof A=="object"&&A.error&&(typeof A.error=="string"||typeof A.error=="object"&&Object.keys(A.error).length>0)){n.log.error(`[provider_response_error] Hidden error from provider(${r.name},${t.model}: ${d.status}): ${g}`);let y=rt(`Error from provider(${r.name},${t.model}: ${d.status}): ${g}`,400,"provider_response_error");throw y.rawBody=g,y}}catch{}}if(!t.stream&&di(n.configService)){let p=await d.clone().text();Qh(n.log,a.req.id,{status:d.status,headers:Object.fromEntries(d.headers.entries()),body:p})}return d}async function lp(t,e,r,n,o,s){let a=e;if(!o&&r.transformer?.use?.length)for(let c of Array.from(r.transformer.use).reverse())!c||typeof c.transformResponseOut!="function"||(a=await c.transformResponseOut(a,s));if(!o&&r.transformer?.[t.model]?.use?.length)for(let c of Array.from(r.transformer[t.model].use).reverse())!c||typeof c.transformResponseOut!="function"||(a=await c.transformResponseOut(a,s));return!o&&n.transformResponseIn&&(a=await n.transformResponseIn(a,s)),a}function dp(t,e,r,n){if(t.ok||e.code(t.status),r.stream===!0){if(e.header("Content-Type","text/event-stream"),e.header("Cache-Control","no-cache"),e.header("Connection","keep-alive"),n&&di(n.configService)){let[s,a]=t.body.tee(),c=Vh(n.configService);return Xh(s,n.log,e.request.id,c),e.send(a)}return e.send(t.body)}else return t.json()}var dc=async t=>{t.get("/",async()=>({message:"LLMs API",version:Zh})),t.get("/health",async()=>({status:"ok",timestamp:new Date().toISOString()})),t.get("/providers/health",async()=>({states:Xe().getAllStates().map(o=>({provider:o.provider,model:o.model,status:o.status,failureCount:o.failureCount,successCount:o.successCount,lastFailureTime:o.lastFailureTime,lastError:o.lastError})),timestamp:new Date().toISOString()}));let e=t.transformerService.getTransformersWithEndpoint();for(let{transformer:r}of e)r.endPoint&&t.post(r.endPoint,async(n,o)=>DC(n,o,t,r));t.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"}}},required:["id","name","type","baseUrl","apiKey","models"]}}},async(r,n)=>{let{name:o,baseUrl:s,apiKey:a,models:c}=r.body;if(!o?.trim())throw rt("Provider name is required",400,"invalid_request");if(!s||!OC(s))throw rt("Valid base URL is required",400,"invalid_request");if(!a?.trim())throw rt("API key is required",400,"invalid_request");if(!c||!Array.isArray(c)||c.length===0)throw rt("At least one model is required",400,"invalid_request");if(t.providerService.getProvider(r.body.name))throw rt(`Provider with name '${r.body.name}' already exists`,400,"provider_exists");return t.providerService.registerProvider(r.body)}),t.get("/providers",async()=>t.providerService.getProviders()),t.get("/providers/:id",{schema:{params:{type:"object",properties:{id:{type:"string"}},required:["id"]}}},async r=>{let n=t.providerService.getProvider(r.params.id);if(!n)throw rt("Provider not found",404,"provider_not_found");return n}),t.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"}},enabled:{type:"boolean"}}}}},async(r,n)=>{let o=t.providerService.updateProvider(r.params.id,r.body);if(!o)throw rt("Provider not found",404,"provider_not_found");return o}),t.delete("/providers/:id",{schema:{params:{type:"object",properties:{id:{type:"string"}},required:["id"]}}},async r=>{if(!t.providerService.deleteProvider(r.params.id))throw rt("Provider not found",404,"provider_not_found");return{message:"Provider deleted successfully"}}),t.patch("/providers/:id/toggle",{schema:{params:{type:"object",properties:{id:{type:"string"}},required:["id"]},body:{type:"object",properties:{enabled:{type:"boolean"}},required:["enabled"]}}},async(r,n)=>{if(!t.providerService.toggleProvider(r.params.id,r.body.enabled))throw rt("Provider not found",404,"provider_not_found");return{message:`Provider ${r.body.enabled?"enabled":"disabled"} successfully`}})};function OC(t){try{return new URL(t),!0}catch{return!1}}var pn=class{constructor(e,r,n){this.configService=e;this.transformerService=r;this.logger=n;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(r=>{try{if(!r.name||!r.api_base_url||!r.api_key)return;let n={};r.transformer&&Object.keys(r.transformer).forEach(o=>{o==="use"?Array.isArray(r.transformer.use)&&(n.use=r.transformer.use.map(s=>{if(Array.isArray(s)&&typeof s[0]=="string"){let a=this.transformerService.getTransformer(s[0]);if(a)return new a(s[1])}if(typeof s=="string"){let a=this.transformerService.getTransformer(s);return typeof a=="function"?new a:a}}).filter(s=>typeof s<"u")):Array.isArray(r.transformer[o]?.use)&&(n[o]={use:r.transformer[o].use.map(s=>{if(Array.isArray(s)&&typeof s[0]=="string"){let a=this.transformerService.getTransformer(s[0]);if(a)return new a(s[1])}if(typeof s=="string"){let a=this.transformerService.getTransformer(s);return typeof a=="function"?new a:a}}).filter(s=>typeof s<"u")})}),this.registerProvider({name:r.name,baseUrl:r.api_base_url,apiKey:r.api_key,models:r.models||[],quotaToken:r.quota_token,transformer:r.transformer?n:void 0,enabled:r.enabled!==!1,wakeupEnabled:r.wakeup_enabled===!0,wakeupTime:r.wakeup_time||"06:00",wakeupModel:r.wakeup_model||""}),this.logger.info(`${r.name} provider registered`)}catch(n){this.logger.error(`${r.name} provider registered error: ${n}`)}})}registerProvider(e){let r={...e,enabled:e.enabled!==!1,wakeupEnabled:e.wakeupEnabled===!0,wakeupTime:e.wakeupTime||"06:00",wakeupModel:e.wakeupModel||""};return this.providers.set(r.name,r),e.models.forEach(n=>{let o=`${r.name},${n}`,s={provider:r.name,model:n,fullModel:o};this.modelRoutes.set(o,s),this.modelRoutes.has(n)||this.modelRoutes.set(n,s)}),r}getProviders(){return Array.from(this.providers.values())}getProvider(e){return this.providers.get(e)}updateProvider(e,r){let n=this.providers.get(e);if(!n)return null;let o={...n,...r,updatedAt:new Date};return this.providers.set(e,o),r.models&&(n.models.forEach(s=>{let a=`${n.name},${s}`;this.modelRoutes.delete(a),this.modelRoutes.delete(s)}),r.models.forEach(s=>{let a=`${n.name},${s}`,c={provider:n.name,model:s,fullModel:a};this.modelRoutes.set(a,c),this.modelRoutes.has(s)||this.modelRoutes.set(s,c)})),o}deleteProvider(e){let r=this.providers.get(e);return r?(r.models.forEach(n=>{let o=`${r.name},${n}`;this.modelRoutes.delete(o),this.modelRoutes.delete(n)}),this.providers.delete(e),!0):!1}toggleProvider(e,r){let n=this.providers.get(e);if(!n)return!1;n.enabled=r;let o=this.configService.get("providers");if(o&&Array.isArray(o)){let s=o.find(a=>a.name===e);s&&(s.enabled=r)}return!0}resolveModelRoute(e){let r=this.modelRoutes.get(e);if(!r)return null;let n=this.providers.get(r.provider);return n?{provider:n,originalModel:e,targetModel:r.model}:null}getAvailableModelNames(){let e=[];return this.providers.forEach(r=>{r.enabled!==!1&&r.models.forEach(n=>{e.push(n),e.push(`${r.name},${n}`)})}),e}getModelRoutes(){return Array.from(this.modelRoutes.values())}parseTransformerConfig(e){return e?Array.isArray(e)?e.reduce((r,n)=>{if(Array.isArray(n)){let[o,s={}]=n;r[o]=s}else r[n]={};return r},{}):e:{}}async getAvailableModels(){let e=[];return this.providers.forEach(r=>{r.enabled!==!1&&r.models.forEach(n=>{e.push({id:n,object:"model",owned_by:r.name,provider:r.name}),e.push({id:`${r.name},${n}`,object:"model",owned_by:r.name,provider:r.name})})}),{object:"list",data:e}}};var Ve=[];for(let t=0;t<256;++t)Ve.push((t+256).toString(16).slice(1));function fp(t,e=0){return(Ve[t[e+0]]+Ve[t[e+1]]+Ve[t[e+2]]+Ve[t[e+3]]+"-"+Ve[t[e+4]]+Ve[t[e+5]]+"-"+Ve[t[e+6]]+Ve[t[e+7]]+"-"+Ve[t[e+8]]+Ve[t[e+9]]+"-"+Ve[t[e+10]]+Ve[t[e+11]]+Ve[t[e+12]]+Ve[t[e+13]]+Ve[t[e+14]]+Ve[t[e+15]]).toLowerCase()}var hp=require("crypto"),pi=new Uint8Array(256),hi=pi.length;function fc(){return hi>pi.length-16&&((0,hp.randomFillSync)(pi),hi=0),pi.slice(hi,hi+=16)}var pp=require("crypto"),hc={randomUUID:pp.randomUUID};function PC(t,e,r){if(hc.randomUUID&&!e&&!t)return hc.randomUUID();t=t||{};let n=t.random??t.rng?.()??fc();if(n.length<16)throw new Error("Random bytes length must be >= 16");if(n[6]=n[6]&15|64,n[8]=n[8]&63|128,e){if(r=r||0,r<0||r+16>e.length)throw new RangeError(`UUID byte range ${r}:${r+15} is out of buffer bounds`);for(let o=0;o<16;++o)e[r+o]=n[o];return e}return fp(n)}var Xt=PC;var mp=t=>t<=0?"none":t<=1024?"low":t<=8192?"medium":"high";var gp=(t,e)=>(t.includes("base64")&&(t=t.split("base64").pop(),t.startsWith(",")&&(t=t.slice(1))),`data:${e};base64,${t}`);function FC(t){return t.map(e=>({name:e.function.name,description:e.function.description,input_schema:e.function.parameters}))}function yp(t){let e=[],r=[];t.messages.forEach(s=>{s.role==="system"?typeof s.content=="string"?r.push(s.content):Array.isArray(s.content)&&s.content.forEach(a=>{a&&typeof a=="object"&&a.type==="text"&&a.text?r.push(a.text):typeof a=="string"&&r.push(a)}):e.push(s)});let n=[];for(let s=0;s<e.length;s++){let a=e[s];if(a.role==="tool"){let c=a.content;try{typeof a.content=="string"&&(c=JSON.parse(a.content))}catch{}let l={type:"tool_result",tool_use_id:a.tool_call_id,content:c};a.cache_control&&(l.cache_control=a.cache_control);let d=n[n.length-1];d&&d.role==="user"&&Array.isArray(d.content)?d.content.push(l):n.push({role:"user",content:[l]})}else if(a.role==="user"){let c=[];typeof a.content=="string"?c.push({type:"text",text:a.content}):Array.isArray(a.content)&&a.content.forEach(d=>{d&&typeof d=="object"&&d.type==="image_url"&&d.image_url?.url?c.push({type:"image",source:{type:"base64",media_type:d.media_type||"image/jpeg",data:d.image_url.url.split(",")[1]||d.image_url.url}}):c.push(d)});let l=n[n.length-1];l&&l.role==="user"&&Array.isArray(l.content)?l.content.push(...c):n.push({role:"user",content:c.length>0?c:[{type:"text",text:" "}]})}else if(a.role==="assistant"){let c=[];a.content&&(typeof a.content=="string"?c.push({type:"text",text:a.content}):Array.isArray(a.content)&&c.push(...a.content)),a.tool_calls&&a.tool_calls.length>0&&a.tool_calls.forEach(d=>{let f={};try{f=JSON.parse(d.function.arguments)}catch{f=d.function.arguments}c.push({type:"tool_use",id:d.id,name:d.function.name,input:f})}),a.thinking&&c.unshift({type:"thinking",thinking:a.thinking.content,signature:a.thinking.signature});let l=n[n.length-1];l&&l.role==="assistant"&&Array.isArray(l.content)?l.content.push(...c):n.push({role:"assistant",content:c.length>0?c:[{type:"text",text:" "}]})}}let o={messages:n,model:t.model,max_tokens:t.max_tokens||4096,temperature:t.temperature,stream:t.stream};return r.length>0&&(o.system=r.join(`
|
|
74
|
+
`);a=d.pop()||"";for(let f of d)f.trim()&&(s<n.maxStreamChunks?Hh(e,r,s,f):s===n.maxStreamChunks&&e.info({debug_log:!0,reqId:r,phase:"provider_stream_chunk_omitted",message:`[chunks after #${s} omitted, maxStreamChunks=${n.maxStreamChunks}]`}),s++)}a.trim()&&(s<n.maxStreamChunks&&Hh(e,r,s,a.trim()),s++),Wh(e,r,s)}catch(a){console.error(`[debug_log] Error reading debug stream for reqId=${r}:`,a),Wh(e,r,s)}finally{o.releaseLock()}})()}var Zh="2.1.27";Hn();var Er=require("fs"),lc=require("path"),op=require("@wengine-ai/claude-code-router-shared"),uc=(0,lc.join)(op.HOME_DIR,"runtime"),cc=(0,lc.join)(uc,"rate-limit.json"),Wn=new Map,tp=!1,wC=null,EC=["x-ratelimit-remaining-tokens","x-ratelimit-remaining-requests","x-ratelimit-remaining"],AC=["x-ratelimit-limit-tokens","x-ratelimit-limit-requests","x-ratelimit-limit"],SC=["x-ratelimit-reset-tokens","x-ratelimit-reset-requests","x-ratelimit-reset"];function Lo(t,e,r){let n=c=>{if(r instanceof Headers)return r.get(c);let l=Object.keys(r).find(d=>d.toLowerCase()===c);return l?r[l]:null},o=ac(n,EC),s=ac(n,AC),a=ac(n,SC);(o||s||a)&&Wn.set(t,{provider:t,remaining:rp(o),limit:rp(s),reset:kC(a),capturedAt:Date.now()})}function sp(t){return Wn.get(t)}function ip(){return Array.from(Wn.values())}function ac(t,e){for(let r of e){let n=t(r);if(n)return n}return null}function rp(t){if(!t)return null;let e=Number(t.trim().replace(/,/g,""));return Number.isFinite(e)?e:null}function kC(t){if(!t)return null;let e=t.trim();if(!e)return null;let r=Number(e);if(Number.isFinite(r))return r>1e12?Math.floor(r/1e3):r>1e9?Math.floor(r):Math.floor(Date.now()/1e3+r);let n=Date.parse(e);if(Number.isFinite(n))return Math.floor(n/1e3);let o=vC(e);return o===null?null:Math.floor((Date.now()+o)/1e3)}function vC(t){let e=/(\d+(?:\.\d+)?)(ms|s|m|h|d)/gi,r=0,n=!1;for(let o of t.matchAll(e)){n=!0;let s=Number(o[1]),a=o[2].toLowerCase();if(Number.isFinite(s))switch(a){case"ms":r+=s;break;case"s":r+=s*1e3;break;case"m":r+=s*60*1e3;break;case"h":r+=s*60*60*1e3;break;case"d":r+=s*24*60*60*1e3;break}}return n?r:null}function TC(){try{if(!(0,Er.existsSync)(cc))return;let t=JSON.parse((0,Er.readFileSync)(cc,"utf-8"));if(!Array.isArray(t))return;let e=Date.now();for(let r of t)if(r&&r.provider){if(r.capturedAt&&e-r.capturedAt>3600*1e3)continue;Wn.set(r.provider,r)}}catch{}}function np(){try{if(Wn.size===0)return;(0,Er.existsSync)(uc)||(0,Er.mkdirSync)(uc,{recursive:!0}),(0,Er.writeFileSync)(cc,JSON.stringify(Array.from(Wn.values()),null,2),"utf-8")}catch{}}function ap(){tp||(tp=!0,TC(),wC=setInterval(np,6e4),process.on("exit",np))}fi();async function DC(t,e,r,n){let o=t.body,s=t.provider,a=r.providerService.getProvider(s);if(!a)throw rt(`Provider '${s}' not found`,404,"provider_not_found");try{let{requestBody:c,config:l,bypass:d}=await up(o,a,n,t.headers,{req:t}),f=await cp(c,l,a,r,d,n,{req:t});try{a?.baseUrl&&f?.headers&&Lo(s,a.baseUrl,f.headers)}catch{}let p=await lp(c,f,a,n,d,{req:t}),g=dp(p,e,o,r);try{let A=o.model||t.originalModel;s&&A&&Xe().recordSuccess(s,A)}catch{}return g}catch(c){let l=await RC(t,e,r,n,c);if(l)return l;throw c}}async function RC(t,e,r,n,o){let s=t.scenarioType||"default",a=t.familyFallback,c=t.modelFamily,l=r.configService.get("fallback"),d=Xe(),f=t.provider||"",p=t.body.model||"",g=new Set;if(f&&p&&(d.recordFailure(f,p,o?.message),g.add(`${f},${p}`),r.recordUsage?.({provider:f,model:p,originalModel:t.originalModel||p,scenarioType:s,modelFamily:t.modelFamily,errorMessage:o?.message||String(o),sessionId:t.usageSessionId||t.id,stream:t.body.stream,inputTokens:t.tokenCount||0,req:t})),!r.configService.get("Router")?.enableFallback)return t.log.info("Fallback disabled by configuration, skipping fallback attempts"),null;let w=m=>{let[v,...b]=m.split(","),S=v?.trim(),D=b.join(",").trim();return!S||!D?null:{provider:S,model:D,key:`${S},${D}`}},y=[];if(c){let m=a?.[s];Array.isArray(m)&&m.length>0?y.push({name:`${c}/${s}`,models:m}):t.log.warn(`No ${c} fallback configured for ${s}; will try global ${s} fallback`)}if(Array.isArray(l?.[s])&&l[s].length>0&&y.push({name:`global/${s}`,models:l[s]}),y.length===0)return null;let _=y.reduce((m,v)=>m+v.models.length,0);t.log.warn(`Request failed for ${s}, trying ${_} fallback models across ${y.length} fallback stage(s)`);for(let m of y){t.log.info(`Trying ${m.name} fallback stage with ${m.models.length} models`);for(let v of m.models){let b=w(v);if(!b){t.log.warn(`Fallback model '${v}' is invalid, skipping`);continue}if(g.has(b.key))continue;g.add(b.key);let S=b.provider,D=b.model;try{if(!d.isAvailable(S,D)){t.log.warn(`Fallback model ${v} unavailable (fail pool), skipping`);continue}t.log.info(`Trying fallback model: ${v}`);let O={...t.body};O.model=D;let q={...t,provider:S,body:O},J=r.providerService.getProvider(S);if(!J){t.log.warn(`Fallback provider '${S}' not found, skipping`);continue}if(J.enabled===!1){t.log.warn(`Fallback provider '${S}' is disabled, skipping`);continue}let{requestBody:B,config:Y,bypass:te}=await up(O,J,n,t.headers,{req:q}),Z=await cp(B,Y,J,r,te,n,{req:q});try{J?.baseUrl&&Z?.headers&&Lo(S,J.baseUrl,Z.headers)}catch{}let ae=await lp(B,Z,J,n,te,{req:q});return t.log.info(`Fallback model ${v} succeeded`),d.recordSuccess(S,D),f&&p&&(Mo().promote(f,p,s,S,D),t.log.info(`Promoted fallback model ${S},${D} for ${f},${p}:${s}`),d.forceOpen(f,p,o?.message),t.log.info(`Marked original model ${f},${p} as unavailable`)),t.provider=S,t.body=O,dp(ae,e,O,r)}catch(O){d.recordFailure(S,D,O.message),t.log.warn(`Fallback model ${b.key} failed: ${O.message}`),r.recordUsage?.({provider:S,model:D,originalModel:t.body.model,scenarioType:s,modelFamily:t.modelFamily,errorMessage:O.message,sessionId:t.usageSessionId||t.id,stream:t.body.stream,req:t});continue}}}return t.log.error(`All fallback models failed for ${s}`),null}async function up(t,e,r,n,o){let s=JSON.parse(JSON.stringify(t)),a={},c=!1;if(c=xC(e,r,t),c&&(n instanceof Headers?n.delete("content-length"):delete n["content-length"],a.headers=n),!c&&typeof r.transformRequestOut=="function"){let l=await r.transformRequestOut(s);l.body?(s=l.body,a=l.config||{}):s=l}if(!c&&e.transformer?.use?.length)for(let l of e.transformer.use){if(!l||typeof l.transformRequestIn!="function")continue;let d=await l.transformRequestIn(s,e,o);d.body?(s=d.body,a={...a,...d.config}):s=d}if(!c&&e.transformer?.[t.model]?.use?.length)for(let l of e.transformer[t.model].use)!l||typeof l.transformRequestIn!="function"||(s=await l.transformRequestIn(s,e,o));return{requestBody:s,config:a,bypass:c}}function xC(t,e,r){return r?.messages?.some(o=>o.role==="system")?!1:t.transformer?.use?.length===1&&t.transformer.use[0].name===e.name&&(!t.transformer?.[r.model]?.use.length||t.transformer?.[r.model]?.use.length===1&&t.transformer?.[r.model]?.use[0].name===e.name)}async function cp(t,e,r,n,o,s,a){let c=e.url||new URL(r.baseUrl);if(!e.TIMEOUT){let f=n.configService.get("API_TIMEOUT_MS");f&&(e.TIMEOUT=typeof f=="string"?parseInt(f,10):f)}if(o&&typeof s.auth=="function"){let f=await s.auth(t,r);if(f.body){t=f.body;let p=e.headers||{};f.config?.headers&&(p={...p,...f.config.headers},delete p.host,delete f.config.headers),e={...e,...f.config,headers:p}}else t=f}let l={Authorization:`Bearer ${r.apiKey}`,...e?.headers||{}};for(let f in l)(l[f]==="undefined"||["authorization","Authorization"].includes(f)&&l[f]?.includes("undefined"))&&delete l[f];di(n.configService)&&Yh(n.log,a.req.id,{url:String(c),headers:l,body:t});let d=await zh(c,t,{httpsProxy:n.configService.getHttpsProxy(),...e,headers:JSON.parse(JSON.stringify(l))},a,n.log);if(!d.ok){let f=await d.text();n.log.error(`[provider_response_error] Error from provider(${r.name},${t.model}: ${d.status}): ${f}`);let p=rt(`Error from provider(${r.name},${t.model}: ${d.status}): ${f}`,d.status,"provider_response_error");throw p.rawBody=f,p}if(d.ok&&(d.headers.get("content-type")||"").includes("application/json")){let p=d.clone();try{let g=await p.text(),A=JSON.parse(g);if(A&&typeof A=="object"&&A.error&&(typeof A.error=="string"||typeof A.error=="object"&&Object.keys(A.error).length>0)){n.log.error(`[provider_response_error] Hidden error from provider(${r.name},${t.model}: ${d.status}): ${g}`);let y=rt(`Error from provider(${r.name},${t.model}: ${d.status}): ${g}`,400,"provider_response_error");throw y.rawBody=g,y}}catch{}}if(!t.stream&&di(n.configService)){let p=await d.clone().text();Qh(n.log,a.req.id,{status:d.status,headers:Object.fromEntries(d.headers.entries()),body:p})}return d}async function lp(t,e,r,n,o,s){let a=e;if(!o&&r.transformer?.use?.length)for(let c of Array.from(r.transformer.use).reverse())!c||typeof c.transformResponseOut!="function"||(a=await c.transformResponseOut(a,s));if(!o&&r.transformer?.[t.model]?.use?.length)for(let c of Array.from(r.transformer[t.model].use).reverse())!c||typeof c.transformResponseOut!="function"||(a=await c.transformResponseOut(a,s));return!o&&n.transformResponseIn&&(a=await n.transformResponseIn(a,s)),a}function dp(t,e,r,n){if(t.ok||e.code(t.status),r.stream===!0){if(e.header("Content-Type","text/event-stream"),e.header("Cache-Control","no-cache"),e.header("Connection","keep-alive"),n&&di(n.configService)){let[s,a]=t.body.tee(),c=Vh(n.configService);return Xh(s,n.log,e.request.id,c),e.send(a)}return e.send(t.body)}else return t.json()}var dc=async t=>{t.get("/",async()=>({message:"LLMs API",version:Zh})),t.get("/health",async()=>({status:"ok",timestamp:new Date().toISOString()})),t.get("/providers/health",async()=>({states:Xe().getAllStates().map(o=>({provider:o.provider,model:o.model,status:o.status,failureCount:o.failureCount,successCount:o.successCount,lastFailureTime:o.lastFailureTime,lastError:o.lastError})),timestamp:new Date().toISOString()}));let e=t.transformerService.getTransformersWithEndpoint();for(let{transformer:r}of e)r.endPoint&&t.post(r.endPoint,async(n,o)=>DC(n,o,t,r));t.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"}}},required:["id","name","type","baseUrl","apiKey","models"]}}},async(r,n)=>{let{name:o,baseUrl:s,apiKey:a,models:c}=r.body;if(!o?.trim())throw rt("Provider name is required",400,"invalid_request");if(!s||!OC(s))throw rt("Valid base URL is required",400,"invalid_request");if(!a?.trim())throw rt("API key is required",400,"invalid_request");if(!c||!Array.isArray(c)||c.length===0)throw rt("At least one model is required",400,"invalid_request");if(t.providerService.getProvider(r.body.name))throw rt(`Provider with name '${r.body.name}' already exists`,400,"provider_exists");return t.providerService.registerProvider(r.body)}),t.get("/providers",async()=>t.providerService.getProviders()),t.get("/providers/:id",{schema:{params:{type:"object",properties:{id:{type:"string"}},required:["id"]}}},async r=>{let n=t.providerService.getProvider(r.params.id);if(!n)throw rt("Provider not found",404,"provider_not_found");return n}),t.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"}},enabled:{type:"boolean"}}}}},async(r,n)=>{let o=t.providerService.updateProvider(r.params.id,r.body);if(!o)throw rt("Provider not found",404,"provider_not_found");return o}),t.delete("/providers/:id",{schema:{params:{type:"object",properties:{id:{type:"string"}},required:["id"]}}},async r=>{if(!t.providerService.deleteProvider(r.params.id))throw rt("Provider not found",404,"provider_not_found");return{message:"Provider deleted successfully"}}),t.patch("/providers/:id/toggle",{schema:{params:{type:"object",properties:{id:{type:"string"}},required:["id"]},body:{type:"object",properties:{enabled:{type:"boolean"}},required:["enabled"]}}},async(r,n)=>{if(!t.providerService.toggleProvider(r.params.id,r.body.enabled))throw rt("Provider not found",404,"provider_not_found");return{message:`Provider ${r.body.enabled?"enabled":"disabled"} successfully`}})};function OC(t){try{return new URL(t),!0}catch{return!1}}var pn=class{constructor(e,r,n){this.configService=e;this.transformerService=r;this.logger=n;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(r=>{try{if(!r.name||!r.api_base_url||!r.api_key)return;let n={};r.transformer&&Object.keys(r.transformer).forEach(o=>{o==="use"?Array.isArray(r.transformer.use)&&(n.use=r.transformer.use.map(s=>{if(Array.isArray(s)&&typeof s[0]=="string"){let a=this.transformerService.getTransformer(s[0]);if(a)return new a(s[1])}if(typeof s=="string"){let a=this.transformerService.getTransformer(s);return typeof a=="function"?new a:a}}).filter(s=>typeof s<"u")):Array.isArray(r.transformer[o]?.use)&&(n[o]={use:r.transformer[o].use.map(s=>{if(Array.isArray(s)&&typeof s[0]=="string"){let a=this.transformerService.getTransformer(s[0]);if(a)return new a(s[1])}if(typeof s=="string"){let a=this.transformerService.getTransformer(s);return typeof a=="function"?new a:a}}).filter(s=>typeof s<"u")})}),this.registerProvider({name:r.name,baseUrl:r.api_base_url,apiKey:r.api_key,models:r.models||[],quotaToken:r.quota_token,transformer:r.transformer?n:void 0,enabled:r.enabled!==!1,wakeupEnabled:r.wakeup_enabled===!0,wakeupTime:r.wakeup_time||"06:00",wakeupModel:r.wakeup_model||""}),this.logger.info(`${r.name} provider registered`)}catch(n){this.logger.error(`${r.name} provider registered error: ${n}`)}})}registerProvider(e){let r={...e,enabled:e.enabled!==!1,wakeupEnabled:e.wakeupEnabled===!0,wakeupTime:e.wakeupTime||"06:00",wakeupModel:e.wakeupModel||""};return this.providers.set(r.name,r),e.models.forEach(n=>{let o=`${r.name},${n}`,s={provider:r.name,model:n,fullModel:o};this.modelRoutes.set(o,s),this.modelRoutes.has(n)||this.modelRoutes.set(n,s)}),r}getProviders(){return Array.from(this.providers.values())}getProvider(e){return this.providers.get(e)}updateProvider(e,r){let n=this.providers.get(e);if(!n)return null;let o={...n,...r,updatedAt:new Date};return this.providers.set(e,o),r.models&&(n.models.forEach(s=>{let a=`${n.name},${s}`;this.modelRoutes.delete(a),this.modelRoutes.delete(s)}),r.models.forEach(s=>{let a=`${n.name},${s}`,c={provider:n.name,model:s,fullModel:a};this.modelRoutes.set(a,c),this.modelRoutes.has(s)||this.modelRoutes.set(s,c)})),o}deleteProvider(e){let r=this.providers.get(e);return r?(r.models.forEach(n=>{let o=`${r.name},${n}`;this.modelRoutes.delete(o),this.modelRoutes.delete(n)}),this.providers.delete(e),!0):!1}toggleProvider(e,r){let n=this.providers.get(e);if(!n)return!1;n.enabled=r;let o=this.configService.get("providers");if(o&&Array.isArray(o)){let s=o.find(a=>a.name===e);s&&(s.enabled=r)}return!0}resolveModelRoute(e){let r=this.modelRoutes.get(e);if(!r)return null;let n=this.providers.get(r.provider);return n?{provider:n,originalModel:e,targetModel:r.model}:null}getAvailableModelNames(){let e=[];return this.providers.forEach(r=>{r.enabled!==!1&&r.models.forEach(n=>{e.push(n),e.push(`${r.name},${n}`)})}),e}getModelRoutes(){return Array.from(this.modelRoutes.values())}parseTransformerConfig(e){return e?Array.isArray(e)?e.reduce((r,n)=>{if(Array.isArray(n)){let[o,s={}]=n;r[o]=s}else r[n]={};return r},{}):e:{}}async getAvailableModels(){let e=[];return this.providers.forEach(r=>{r.enabled!==!1&&r.models.forEach(n=>{e.push({id:n,object:"model",owned_by:r.name,provider:r.name}),e.push({id:`${r.name},${n}`,object:"model",owned_by:r.name,provider:r.name})})}),{object:"list",data:e}}};var Ve=[];for(let t=0;t<256;++t)Ve.push((t+256).toString(16).slice(1));function fp(t,e=0){return(Ve[t[e+0]]+Ve[t[e+1]]+Ve[t[e+2]]+Ve[t[e+3]]+"-"+Ve[t[e+4]]+Ve[t[e+5]]+"-"+Ve[t[e+6]]+Ve[t[e+7]]+"-"+Ve[t[e+8]]+Ve[t[e+9]]+"-"+Ve[t[e+10]]+Ve[t[e+11]]+Ve[t[e+12]]+Ve[t[e+13]]+Ve[t[e+14]]+Ve[t[e+15]]).toLowerCase()}var hp=require("crypto"),pi=new Uint8Array(256),hi=pi.length;function fc(){return hi>pi.length-16&&((0,hp.randomFillSync)(pi),hi=0),pi.slice(hi,hi+=16)}var pp=require("crypto"),hc={randomUUID:pp.randomUUID};function PC(t,e,r){if(hc.randomUUID&&!e&&!t)return hc.randomUUID();t=t||{};let n=t.random??t.rng?.()??fc();if(n.length<16)throw new Error("Random bytes length must be >= 16");if(n[6]=n[6]&15|64,n[8]=n[8]&63|128,e){if(r=r||0,r<0||r+16>e.length)throw new RangeError(`UUID byte range ${r}:${r+15} is out of buffer bounds`);for(let o=0;o<16;++o)e[r+o]=n[o];return e}return fp(n)}var Xt=PC;var mp=t=>t<=0?"none":t<=1024?"low":t<=8192?"medium":"high";var gp=(t,e)=>(t.includes("base64")&&(t=t.split("base64").pop(),t.startsWith(",")&&(t=t.slice(1))),`data:${e};base64,${t}`);function FC(t){return t.map(e=>({name:e.function.name,description:e.function.description,input_schema:e.function.parameters}))}function yp(t){let e=[],r=[];t.messages.forEach(s=>{s.role==="system"?typeof s.content=="string"?r.push(s.content):Array.isArray(s.content)&&s.content.forEach(a=>{a&&typeof a=="object"&&a.type==="text"&&a.text?r.push(a.text):typeof a=="string"&&r.push(a)}):e.push(s)});let n=[];for(let s=0;s<e.length;s++){let a=e[s];if(a.role==="tool"){let c=a.content;try{typeof a.content=="string"&&(c=JSON.parse(a.content))}catch{}c!=null&&typeof c!="object"&&typeof c!="string"&&(c=String(c));let l={type:"tool_result",tool_use_id:a.tool_call_id,content:c};a.cache_control&&(l.cache_control=a.cache_control);let d=n[n.length-1];d&&d.role==="user"&&Array.isArray(d.content)?d.content.push(l):n.push({role:"user",content:[l]})}else if(a.role==="user"){let c=[];typeof a.content=="string"?c.push({type:"text",text:a.content}):Array.isArray(a.content)&&a.content.forEach(d=>{d&&typeof d=="object"&&d.type==="image_url"&&d.image_url?.url?c.push({type:"image",source:{type:"base64",media_type:d.media_type||"image/jpeg",data:d.image_url.url.split(",")[1]||d.image_url.url}}):c.push(d)});let l=n[n.length-1];l&&l.role==="user"&&Array.isArray(l.content)?l.content.push(...c):n.push({role:"user",content:c.length>0?c:[{type:"text",text:" "}]})}else if(a.role==="assistant"){let c=[];a.content&&(typeof a.content=="string"?c.push({type:"text",text:a.content}):Array.isArray(a.content)&&c.push(...a.content)),a.tool_calls&&a.tool_calls.length>0&&a.tool_calls.forEach(d=>{let f={};try{f=JSON.parse(d.function.arguments)}catch{f=d.function.arguments}c.push({type:"tool_use",id:d.id,name:d.function.name,input:f})}),a.thinking&&c.unshift({type:"thinking",thinking:a.thinking.content,signature:a.thinking.signature});let l=n[n.length-1];l&&l.role==="assistant"&&Array.isArray(l.content)?l.content.push(...c):n.push({role:"assistant",content:c.length>0?c:[{type:"text",text:" "}]})}}let o={messages:n,model:t.model,max_tokens:t.max_tokens||4096,temperature:t.temperature,stream:t.stream};return r.length>0&&(o.system=r.join(`
|
|
75
75
|
|
|
76
76
|
`)),t.tools&&t.tools.length>0&&(o.tools=FC(t.tools),t.tool_choice&&(t.tool_choice==="auto"?o.tool_choice={type:"auto"}:t.tool_choice==="any"||t.tool_choice==="required"?o.tool_choice={type:"any"}:typeof t.tool_choice=="string"?o.tool_choice={type:"tool",name:t.tool_choice}:typeof t.tool_choice=="object"&&t.tool_choice.type==="function"&&(o.tool_choice={type:"tool",name:t.tool_choice.function.name}))),o}var mi=class{constructor(e){this.options=e;this.useBearer=this.options?.UseBearer??!1}name="Anthropic";endPoint="/v1/messages";useBearer;logger;async auth(e,r){let n={};return this.useBearer?(n.authorization=`Bearer ${r.apiKey}`,n["x-api-key"]=void 0):(n["x-api-key"]=r.apiKey,n.authorization=void 0),{body:e,config:{headers:n}}}async transformRequestOut(e){let r=[];if(e.system){if(typeof e.system=="string")r.push({role:"system",content:e.system});else if(Array.isArray(e.system)&&e.system.length){let s=e.system.filter(a=>a.type==="text"&&a.text).map(a=>({type:"text",text:a.text,cache_control:a.cache_control}));r.push({role:"system",content:s})}}JSON.parse(JSON.stringify(e.messages||[]))?.forEach(s=>{if(s.role==="system"){r.push({role:"system",content:s.content});return}if(s.role==="user"||s.role==="assistant"){if(typeof s.content=="string"){r.push({role:s.role,content:s.content});return}if(Array.isArray(s.content)){if(s.role==="user"){let a=s.content.filter(l=>l.type==="tool_result"&&l.tool_use_id);a.length&&a.forEach(l=>{let d={role:"tool",content:typeof l.content=="string"?l.content:JSON.stringify(l.content),tool_call_id:l.tool_use_id,cache_control:l.cache_control};r.push(d)});let c=s.content.filter(l=>l.type==="text"&&l.text||l.type==="image"&&l.source);c.length&&r.push({role:"user",content:c.map(l=>l?.type==="image"?{type:"image_url",image_url:{url:l.source?.type==="base64"?gp(l.source.data,l.source.media_type):l.source.url},media_type:l.source.media_type}:l)})}else if(s.role==="assistant"){let a={role:"assistant",content:""},c=s.content.filter(f=>f.type==="text"&&f.text);c.length&&(a.content=c.map(f=>f.text).join(`
|
|
77
|
-
`));let l=s.content.filter(f=>f.type==="tool_use"&&f.id);l.length&&(a.tool_calls=l.map(f=>({id:f.id,type:"function",function:{name:f.name,arguments:JSON.stringify(f.input||{})}})));let d=s.content.find(f=>f.type==="thinking");d&&(a.thinking={content:d.thinking,signature:d.signature}),r.push(a)}return}}});let o={messages:r,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&&(o.reasoning={effort:mp(e.thinking.budget_tokens),enabled:e.thinking.type==="enabled"}),e.tool_choice&&(e.tool_choice.type==="tool"?o.tool_choice={type:"function",function:{name:e.tool_choice.name}}:o.tool_choice=e.tool_choice.type),o}async transformRequestIn(e,r,n){let o=yp(e),s={};return this.useBearer?(s.authorization=`Bearer ${r.apiKey}`,s["x-api-key"]=void 0):(s["x-api-key"]=r.apiKey,s.authorization=void 0),s["anthropic-version"]="2023-06-01",s["content-type"]="application/json",{body:o,config:{
|
|
77
|
+
`));let l=s.content.filter(f=>f.type==="tool_use"&&f.id);l.length&&(a.tool_calls=l.map(f=>({id:f.id,type:"function",function:{name:f.name,arguments:JSON.stringify(f.input||{})}})));let d=s.content.find(f=>f.type==="thinking");d&&(a.thinking={content:d.thinking,signature:d.signature}),r.push(a)}return}}});let o={messages:r,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&&(o.reasoning={effort:mp(e.thinking.budget_tokens),enabled:e.thinking.type==="enabled"}),e.tool_choice&&(e.tool_choice.type==="tool"?o.tool_choice={type:"function",function:{name:e.tool_choice.name}}:o.tool_choice=e.tool_choice.type),o}async transformRequestIn(e,r,n){if(!this.isAnthropicMessagesEndpoint(r.baseUrl))return e;n&&n.req&&(n.req.isTargetAnthropic=!0);let o=yp(e),s={};return this.useBearer?(s.authorization=`Bearer ${r.apiKey}`,s["x-api-key"]=void 0):(s["x-api-key"]=r.apiKey,s.authorization=void 0),s["anthropic-version"]="2023-06-01",s["content-type"]="application/json",{body:o,config:{headers:s}}}isAnthropicMessagesEndpoint(e){try{return new URL(e.trim()).pathname.replace(/\/+$/,"").endsWith("/messages")}catch{return!1}}async transformResponseIn(e,r){if(r?.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 o=await this.convertOpenAIStreamToAnthropic(e.body,r);return new Response(o,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}else{let o=await e.json(),s=this.convertOpenAIResponseToAnthropic(o,r);return new Response(JSON.stringify(s),{headers:{"Content-Type":"application/json"}})}}convertAnthropicToolsToUnified(e){return e.map(r=>({type:"function",function:{name:r.name,description:r.description||"",parameters:r.input_schema}}))}async convertOpenAIStreamToAnthropic(e,r){return new ReadableStream({start:async o=>{let s=new TextEncoder,a=`msg_${Date.now()}`,c=null,l="unknown",d=!1,f=!1,p=!1,g=new Map,A=new Map,w=0,y=0,_=0,m=!1,v=!1,b=0,S=-1,D=()=>{let B=b;return b++,B},O=B=>{if(!m)try{o.enqueue(B);let Y=new TextDecoder().decode(B);this.logger.debug({reqId:r.req.id,data:Y,type:"send data"})}catch(Y){if(Y instanceof TypeError&&Y.message.includes("Controller is already closed"))m=!0;else throw this.logger.debug({reqId:r.req.id,error:Y instanceof Error?Y.message:String(Y),type:"send data error"}),Y}},q=()=>{if(!m)try{if(S>=0){let Y={type:"content_block_stop",index:S};O(s.encode(`event: content_block_stop
|
|
78
78
|
data: ${JSON.stringify(Y)}
|
|
79
79
|
|
|
80
80
|
`)),S=-1}c?(O(s.encode(`event: message_delta
|
|
@@ -160,7 +160,7 @@ data: ${JSON.stringify(G)}
|
|
|
160
160
|
`);y=v.pop()||"";for(let b of v)await A(b,g)}}catch(_){g.error(_)}finally{g.close()}}});return new Response(p,{status:t.status,statusText:t.statusText,headers:t.headers})}}var bi=class{name="gemini";endPoint="/v1beta/models/:modelAndAction";async transformRequestIn(e,r){return{body:gi(e),config:{url:new URL(`./${e.model}:${e.stream?"streamGenerateContent?alt=sse":"generateContent"}`,r.baseUrl),headers:{"x-goog-api-key":r.apiKey,Authorization:void 0}}}}transformRequestOut=yi;async transformResponseOut(e){return _i(e,this.name,this.logger)}};async function ov(){try{let{GoogleAuth:t}=await Promise.resolve().then(()=>Oe(Pd(),1));return(await(await new t({scopes:["https://www.googleapis.com/auth/cloud-platform"]}).getClient()).getAccessToken()).token||""}catch(t){throw console.error("Error getting access token:",t),new Error(`Failed to get access token for Vertex AI. Please ensure you have set up authentication using one of these methods:
|
|
161
161
|
1. Set GOOGLE_APPLICATION_CREDENTIALS to point to service account key file
|
|
162
162
|
2. Run "gcloud auth application-default login"
|
|
163
|
-
3. Use Google Cloud environment with default service account`)}}var Na=class{name="vertex-gemini";async transformRequestIn(e,r){let n=process.env.GOOGLE_CLOUD_PROJECT,o=process.env.GOOGLE_CLOUD_LOCATION||"us-central1";if(!n&&process.env.GOOGLE_APPLICATION_CREDENTIALS)try{let c=(await import("fs")).readFileSync(process.env.GOOGLE_APPLICATION_CREDENTIALS,"utf8"),l=JSON.parse(c);l&&l.project_id&&(n=l.project_id)}catch(a){console.error("Error extracting project_id from GOOGLE_APPLICATION_CREDENTIALS:",a)}if(!n)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 ov();return{body:gi(e),config:{url:new URL(`./v1beta1/projects/${n}/locations/${o}/publishers/google/models/${e.model}:${e.stream?"streamGenerateContent":"generateContent"}`,r.baseUrl.endsWith("/")?r.baseUrl:r.baseUrl+"/"||`https://${o}-aiplatform.googleapis.com`),headers:{Authorization:`Bearer ${s}`,"x-goog-api-key":void 0}}}}async transformRequestOut(e){return yi(e)}async transformResponseOut(e){return _i(e,this.name)}};var Ma=class{name="deepseek";async transformRequestIn(e){e.max_tokens&&e.max_tokens>8192&&(e.max_tokens=8192);let r=e.model?.includes("reasoner")||e.model?.includes("v4")||e.model?.includes("pro")||e.model?.includes("think"),n=e.thinking||e.reasoning?.enabled||e.messages.some(o=>o.thinking?.content)||r;return e.messages.forEach(o=>{if(o.role==="assistant"){let s=o.thinking?.content,a=o.thinking?.signature,c="";if(typeof o.content=="string"){let d=/<thinking>([\s\S]*?)<\/thinking>/g.exec(o.content);d&&(c=d[1].trim(),o.content=o.content.replace(d[0],"").trim())}s&&typeof s=="string"&&s.trim()?(o.reasoning_content=s,a&&(o.reasoning_content_signature=a)):c&&(o.reasoning_content=c),n&&!o.reasoning_content&&(o.reasoning_content=" "),o.thinking&&delete o.thinking}}),e}async transformResponseOut(e){if(e.headers.get("Content-Type")?.includes("application/json")){let r=await e.json();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=new TextDecoder,n=new TextEncoder,o="",s=!1,a="",c=new ReadableStream({async start(l){let d=e.body.getReader(),f=(g,A,w)=>{let y=g.split(`
|
|
163
|
+
3. Use Google Cloud environment with default service account`)}}var Na=class{name="vertex-gemini";async transformRequestIn(e,r){let n=process.env.GOOGLE_CLOUD_PROJECT,o=process.env.GOOGLE_CLOUD_LOCATION||"us-central1";if(!n&&process.env.GOOGLE_APPLICATION_CREDENTIALS)try{let c=(await import("fs")).readFileSync(process.env.GOOGLE_APPLICATION_CREDENTIALS,"utf8"),l=JSON.parse(c);l&&l.project_id&&(n=l.project_id)}catch(a){console.error("Error extracting project_id from GOOGLE_APPLICATION_CREDENTIALS:",a)}if(!n)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 ov();return{body:gi(e),config:{url:new URL(`./v1beta1/projects/${n}/locations/${o}/publishers/google/models/${e.model}:${e.stream?"streamGenerateContent":"generateContent"}`,r.baseUrl.endsWith("/")?r.baseUrl:r.baseUrl+"/"||`https://${o}-aiplatform.googleapis.com`),headers:{Authorization:`Bearer ${s}`,"x-goog-api-key":void 0}}}}async transformRequestOut(e){return yi(e)}async transformResponseOut(e){return _i(e,this.name)}};var Ma=class{name="deepseek";async transformRequestIn(e){e.max_tokens&&e.max_tokens>8192&&(e.max_tokens=8192);let r=e.model?.includes("reasoner")||e.model?.includes("v4")||e.model?.includes("pro")||e.model?.includes("think"),n=e.thinking||e.reasoning?.enabled||e.messages.some(o=>o.thinking?.content)||r;return n&&e.tool_choice&&delete e.tool_choice,e.messages.forEach(o=>{if(o.role==="assistant"){let s=o.thinking?.content,a=o.thinking?.signature,c="";if(typeof o.content=="string"){let d=/<thinking>([\s\S]*?)<\/thinking>/g.exec(o.content);d&&(c=d[1].trim(),o.content=o.content.replace(d[0],"").trim())}s&&typeof s=="string"&&s.trim()?(o.reasoning_content=s,a&&(o.reasoning_content_signature=a)):c&&(o.reasoning_content=c),n&&!o.reasoning_content&&(o.reasoning_content=" "),o.thinking&&delete o.thinking}}),e}async transformResponseOut(e){if(e.headers.get("Content-Type")?.includes("application/json")){let r=await e.json();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=new TextDecoder,n=new TextEncoder,o="",s=!1,a="",c=new ReadableStream({async start(l){let d=e.body.getReader(),f=(g,A,w)=>{let y=g.split(`
|
|
164
164
|
`);for(let _ of y)_.trim()&&A.enqueue(w.encode(_+`
|
|
165
165
|
`))},p=(g,A)=>{let{controller:w,encoder:y}=A;if(g.startsWith("data: ")&&g.trim()!=="data: [DONE]")try{let _=JSON.parse(g.slice(6));if(_.choices?.[0]?.delta?.reasoning_content){A.appendReasoningContent(_.choices[0].delta.reasoning_content);let m={..._,choices:[{..._.choices[0],delta:{..._.choices[0].delta,thinking:{content:_.choices[0].delta.reasoning_content}}}]};delete m.choices[0].delta.reasoning_content;let v=`data: ${JSON.stringify(m)}
|
|
166
166
|
|