@wengine-ai/llms 2.0.36 → 2.0.37
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/dist/cjs/server.cjs +2 -2
- package/dist/cjs/server.cjs.map +3 -3
- package/dist/esm/server.mjs +2 -2
- package/dist/esm/server.mjs.map +3 -3
- package/package.json +1 -1
package/dist/cjs/server.cjs
CHANGED
|
@@ -69,7 +69,7 @@ https://cloud.google.com/compute/docs/metadata/predefined-metadata-keys`};var Ql
|
|
|
69
69
|
${this.toMarkdown(s,r+1)}`:`${n}- ${s}`).join(`
|
|
70
70
|
`):typeof e=="object"&&e!==null?Object.entries(e).map(([s,i])=>typeof i=="object"&&i!==null?`${n}${s}:
|
|
71
71
|
${this.toMarkdown(i,r+1)}`:`${n}${s}: ${i}`).join(`
|
|
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 po,Od=Be(()=>{"use strict";po=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:s=!0,prefix:i,metadata:u}=r||{},c={data:e};return s&&(c.timestamp=new Date().toISOString()),i&&(c.prefix=i),u&&Object.keys(u).length>0&&(c.metadata=u),c}async sendRequest(e,r,n,s,i){let u=new AbortController,c=setTimeout(()=>u.abort(),i);try{let l=await fetch(e,{method:r,headers:n,body:JSON.stringify(s),signal:u.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,s,i,u){let c=null;for(let l=1;l<=u.maxAttempts;l++)try{return await this.sendRequest(e,r,n,s,i)}catch(h){if(c=h,l===u.maxAttempts)break;let f=u.backoffMs*Math.pow(2,l-1);console.warn(`[WebhookOutputHandler] Request failed (attempt ${l}/${u.maxAttempts}), retrying in ${f}ms...`,h.message),await this.delay(f)}throw c}async output(e,r={}){let n=r.timeout||this.defaultTimeout;try{let s=this.buildHeaders(),i=this.buildBody(e,r),u=await this.sendWithRetry(this.config.url,this.config.method,s,i,n,this.config.retry);return!0}catch(s){let i=s instanceof Error?s.message:String(s);if(this.config.silent)return console.error(`[WebhookOutputHandler] Failed to send data: ${i}`),!1;throw new Error(`Webhook output failed: ${i}`)}}}});var fs,Fd,t0,mo,xd=Be(()=>{"use strict";fs=require("fs"),Fd=require("path"),t0=require("os"),mo=class{type="temp-file";config;baseDir;constructor(e={}){this.config={subdirectory:"claude-code-router",extension:"json",includeTimestamp:!1,prefix:"session",...e};let r=(0,t0.tmpdir)();this.baseDir=(0,Fd.join)(r,this.config.subdirectory),this.ensureDir()}ensureDir(){try{(0,fs.existsSync)(this.baseDir)||(0,fs.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}`:"",s;if(this.config.includeTimestamp){let i=Date.now();s=`${r}-${e}-${i}${n}`}else s=`${r}-${e}${n}`;return(0,Fd.join)(this.baseDir,s)}async output(e,r={}){try{let n=r.metadata?.sessionId;if(!n)return!1;let s={...e,timestamp:Date.now(),sessionId:n},i=this.getFilePath(n);return(0,fs.writeFileSync)(i,JSON.stringify(s,null,2),"utf-8"),!0}catch{return!1}}getBaseDir(){return this.baseDir}}});var Pd,hs,r0=Be(()=>{"use strict";Rd();Od();xd();Pd=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),s=r.type+"_"+Date.now();this.registerHandler(s,n)}catch(n){console.error(`[OutputManager] Failed to register ${r.type} handler:`,n)}}createHandler(e){switch(e.type){case"console":return new ho(e.config);case"webhook":return new po(e.config);case"temp-file":return new mo(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},s={success:[],failed:[]},i=Array.from(this.handlers.entries()).map(async([u,c])=>{try{await c.output(e,n)?s.success.push(u):s.failed.push(u)}catch(l){console.error(`[OutputManager] Handler ${u} failed:`,l),s.failed.push(u)}});return await Promise.all(i),s}async outputTo(e,r,n){let s={...this.defaultOptions,...n},i={success:[],failed:[]},u=e.map(async c=>{let l=this.handlers.get(c);if(!l){console.warn(`[OutputManager] Handler ${c} not found`),i.failed.push(c);return}try{await l.output(r,s)?i.success.push(c):i.failed.push(c)}catch(h){console.error(`[OutputManager] Handler ${c} failed:`,h),i.failed.push(c)}});return await Promise.all(u),i}async outputToType(e,r,n){let s=Array.from(this.handlers.entries()).filter(([i,u])=>u.type===e).map(([i])=>i);return this.outputTo(s,r,n)}},hs=new Pd});var aD={};ku(aD,{ConfigService:()=>sn,ProviderHealthStore:()=>ks,ProviderService:()=>an,SSEParserTransform:()=>wn,SSESerializerTransform:()=>fo,TokenizerService:()=>Cn,TransformerService:()=>bn,calculateTokenCount:()=>Ed,default:()=>iD,getHealthStore:()=>on,pluginManager:()=>kd,rewriteStream:()=>vd,router:()=>Ya,searchProjectBySession:()=>Ad,sessionUsageCache:()=>Wa,tokenSpeedPlugin:()=>Nd});module.exports=J_(aD);var o0=Ue(require("fastify"),1),i0=Ue(require("@fastify/cors"),1);var Ss=require("fs"),Nu=require("path"),Xf=require("dotenv"),Qf=Ue(Iu(),1),sn=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,Nu.join)(process.cwd(),this.options.jsonPath);if((0,Ss.existsSync)(e))try{let r=(0,Ss.readFileSync)(e,"utf-8"),n=Qf.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,Nu.join)(process.cwd(),this.options.envPath);if((0,Ss.existsSync)(e))try{let r=(0,Xf.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 nt(t,e=500,r="internal_error",n="api_error"){let s=new Error(t);return s.statusCode=e,s.code=r,s.type=n,s}async function Zf(t,e,r){e.log.error(t);let n=t.statusCode||500,s={error:{message:t.message+t.stack||"Internal Server Error",type:t.type||"api_error",code:t.code||"internal_error"}};return r.code(n).send(s)}var eh=require("undici");function th(t,e,r,n,s){let i=new Headers({"Content-Type":"application/json"});r.headers&&Object.entries(r.headers).forEach(([h,f])=>{f&&i.set(h,f)});let u,c=AbortSignal.timeout(r.TIMEOUT??60*1e3*60);if(r.signal){let h=new AbortController,f=()=>h.abort();r.signal.addEventListener("abort",f),c.addEventListener("abort",f),u=h.signal}else u=c;let l={method:"POST",headers:i,body:JSON.stringify(e),signal:u};return r.httpsProxy&&(l.dispatcher=new eh.ProxyAgent(new URL(r.httpsProxy).toString())),s?.debug({reqId:n.req.id,request:l,headers:Object.fromEntries(i.entries()),requestUrl:typeof t=="string"?t:t.toString(),useProxy:r.httpsProxy},"final request"),fetch(typeof t=="string"?t:t.toString(),l)}var rh="2.0.36";var nb={enabled:!0,failureThreshold:3,probeIntervalMinutes:5,halfOpenSuccessThreshold:2,rateLimitThreshold:1},ks=class{states=new Map;config;probeTimer;constructor(e){this.config={...nb,...e}}getKey(e,r){return`${e},${r}`}recordSuccess(e,r){if(!this.config.enabled)return;let n=this.getKey(e,r),s=this.states.get(n);s&&(s.successCount++,s.status==="half-open"?s.successCount>=this.config.halfOpenSuccessThreshold&&this.states.delete(n):s.status==="open"&&(s.status="half-open",s.successCount=1,s.failureCount=0))}isRateLimitError(e){if(!e)return!1;let r=e.toLowerCase();return r.includes("429")||r.includes("rate_limit")||r.includes("ratelimit")||r.includes("rate limit")||r.includes("overloaded")||r.includes("quota")}recordFailure(e,r,n){if(!this.config.enabled)return;let s=this.getKey(e,r),i=this.states.get(s);i||(i={provider:e,model:r,status:"closed",failureCount:0,successCount:0,lastFailureTime:0,lastProbeTime:0},this.states.set(s,i)),i.failureCount++,i.lastFailureTime=Date.now(),i.lastError=n;let c=this.isRateLimitError(n)?this.config.rateLimitThreshold:this.config.failureThreshold;i.status==="half-open"?(i.status="open",i.successCount=0,i.lastProbeTime=0):i.status==="closed"&&i.failureCount>=c&&(i.status="open",i.lastProbeTime=0)}getState(e,r){return this.states.get(this.getKey(e,r))}isAvailable(e,r){if(!this.config.enabled)return!0;let n=this.getState(e,r);return n?n.status!=="open":!0}getPriority(e,r){if(!this.config.enabled)return 0;let n=this.getState(e,r);if(!n)return 0;switch(n.status){case"closed":return 0;case"half-open":return 1;case"open":return 2}}getHealthyModels(){return[]}getFailPoolModels(){let e=[];for(let[r,n]of this.states)n.status==="open"&&e.push(r);return e}getHalfOpenModels(){let e=[];for(let[r,n]of this.states)n.status==="half-open"&&e.push(r);return e}needsProbe(e){return Date.now()-e.lastProbeTime>=this.config.probeIntervalMinutes*60*1e3}markProbeAttempt(e,r){let n=this.getKey(e,r),s=this.states.get(n);s&&s.status==="open"&&(s.lastProbeTime=Date.now())}clear(){this.states.clear()}getAllStates(){return Array.from(this.states.values())}stopProbeTimer(){this.probeTimer&&(clearInterval(this.probeTimer),this.probeTimer=void 0)}},Bu=null;function on(t){return Bu||(Bu=new ks(t)),Bu}async function sb(t,e,r,n){let s=t.body,i=t.provider,u=r.providerService.getProvider(i);if(!u)throw nt(`Provider '${i}' not found`,404,"provider_not_found");try{let{requestBody:c,config:l,bypass:h}=await nh(s,u,n,t.headers,{req:t}),f=await sh(c,l,u,r,h,n,{req:t}),p=await oh(c,f,u,n,h,{req:t});return ih(p,e,s)}catch(c){let l=await ob(t,e,r,n,c);if(l)return l;throw c}}async function ob(t,e,r,n,s){let i=t.scenarioType||"default",u=t.familyFallback,c=r.configService.get("fallback"),l=on(),h=[];if(u?.[i]?h=u[i]:c?.[i]&&(h=c[i]),!Array.isArray(h)||h.length===0)return null;let f=t.provider||"",p=t.body.model||"";l.recordFailure(f,p,s?.message),t.log.warn(`Request failed for ${t.scenarioType}, trying ${h.length} fallback models`);let S=h.sort((D,E)=>{let[y,g]=D.split(","),[m,T]=E.split(",");return l.getPriority(y,g)-l.getPriority(m,T)});for(let D of S)try{let[E,...y]=D.split(","),g=y.join(",");if(!l.isAvailable(E,g)){t.log.warn(`Fallback model ${D} unavailable (fail pool), skipping`);continue}t.log.info(`Trying fallback model: ${D}`);let m={...t.body};m.model=g;let T={...t,provider:E,body:m},b=r.providerService.getProvider(E);if(!b){t.log.warn(`Fallback provider '${E}' not found, skipping`);continue}let{requestBody:w,config:O,bypass:x}=await nh(m,b,n,t.headers,{req:T}),$=await sh(w,O,b,r,x,n,{req:T}),V=await oh(w,$,b,n,x,{req:T});return t.log.info(`Fallback model ${D} succeeded`),l.recordSuccess(E,g),ih(V,e,m)}catch(E){let[y,...g]=D.split(","),m=g.join(",");l.recordFailure(y,m,E.message),t.log.warn(`Fallback model ${D} failed: ${E.message}`);continue}return t.log.error(`All fallback models failed for ${i}`),null}async function nh(t,e,r,n,s){let i=JSON.parse(JSON.stringify(t)),u={},c=!1;if(c=ib(e,r,t),c&&(n instanceof Headers?n.delete("content-length"):delete n["content-length"],u.headers=n),!c&&typeof r.transformRequestOut=="function"){let l=await r.transformRequestOut(i);l.body?(i=l.body,u=l.config||{}):i=l}if(!c&&e.transformer?.use?.length)for(let l of e.transformer.use){if(!l||typeof l.transformRequestIn!="function")continue;let h=await l.transformRequestIn(i,e,s);h.body?(i=h.body,u={...u,...h.config}):i=h}if(!c&&e.transformer?.[t.model]?.use?.length)for(let l of e.transformer[t.model].use)!l||typeof l.transformRequestIn!="function"||(i=await l.transformRequestIn(i,e,s));return{requestBody:i,config:u,bypass:c}}function ib(t,e,r){return 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 sh(t,e,r,n,s,i,u){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(s&&typeof i.auth=="function"){let f=await i.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];let h=await th(c,t,{httpsProxy:n.configService.getHttpsProxy(),...e,headers:JSON.parse(JSON.stringify(l))},u,n.log);if(!h.ok){let f=await h.text();throw n.log.error(`[provider_response_error] Error from provider(${r.name},${t.model}: ${h.status}): ${f}`),nt(`Error from provider(${r.name},${t.model}: ${h.status}): ${f}`,h.status,"provider_response_error")}return h}async function oh(t,e,r,n,s,i){let u=e;if(!s&&r.transformer?.use?.length)for(let c of Array.from(r.transformer.use).reverse())!c||typeof c.transformResponseOut!="function"||(u=await c.transformResponseOut(u,i));if(!s&&r.transformer?.[t.model]?.use?.length)for(let c of Array.from(r.transformer[t.model].use).reverse())!c||typeof c.transformResponseOut!="function"||(u=await c.transformResponseOut(u,i));return!s&&n.transformResponseIn&&(u=await n.transformResponseIn(u,i)),u}function ih(t,e,r){return t.ok||e.code(t.status),r.stream===!0?(e.header("Content-Type","text/event-stream"),e.header("Cache-Control","no-cache"),e.header("Connection","keep-alive"),e.send(t.body)):t.json()}var ju=async t=>{t.get("/",async()=>({message:"LLMs API",version:rh})),t.get("/health",async()=>({status:"ok",timestamp:new Date().toISOString()})),t.get("/providers/health",async()=>({states:on().getAllStates().map(s=>({provider:s.provider,model:s.model,status:s.status,failureCount:s.failureCount,successCount:s.successCount,lastFailureTime:s.lastFailureTime,lastError:s.lastError})),timestamp:new Date().toISOString()}));let e=t.transformerService.getTransformersWithEndpoint();for(let{transformer:r}of e)r.endPoint&&t.post(r.endPoint,async(n,s)=>sb(n,s,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:s,baseUrl:i,apiKey:u,models:c}=r.body;if(!s?.trim())throw nt("Provider name is required",400,"invalid_request");if(!i||!ab(i))throw nt("Valid base URL is required",400,"invalid_request");if(!u?.trim())throw nt("API key is required",400,"invalid_request");if(!c||!Array.isArray(c)||c.length===0)throw nt("At least one model is required",400,"invalid_request");if(t.providerService.getProvider(r.body.name))throw nt(`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 nt("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 s=t.providerService.updateProvider(r.params.id,r.body);if(!s)throw nt("Provider not found",404,"provider_not_found");return s}),t.delete("/providers/:id",{schema:{params:{type:"object",properties:{id:{type:"string"}},required:["id"]}}},async r=>{if(!t.providerService.deleteProvider(r.params.id))throw nt("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 nt("Provider not found",404,"provider_not_found");return{message:`Provider ${r.body.enabled?"enabled":"disabled"} successfully`}})};function ab(t){try{return new URL(t),!0}catch{return!1}}var an=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(s=>{s==="use"?Array.isArray(r.transformer.use)&&(n.use=r.transformer.use.map(i=>{if(Array.isArray(i)&&typeof i[0]=="string"){let u=this.transformerService.getTransformer(i[0]);if(u)return new u(i[1])}if(typeof i=="string"){let u=this.transformerService.getTransformer(i);return typeof u=="function"?new u:u}}).filter(i=>typeof i<"u")):Array.isArray(r.transformer[s]?.use)&&(n[s]={use:r.transformer[s].use.map(i=>{if(Array.isArray(i)&&typeof i[0]=="string"){let u=this.transformerService.getTransformer(i[0]);if(u)return new u(i[1])}if(typeof i=="string"){let u=this.transformerService.getTransformer(i);return typeof u=="function"?new u:u}}).filter(i=>typeof i<"u")})}),this.registerProvider({name:r.name,baseUrl:r.api_base_url,apiKey:r.api_key,models:r.models||[],transformer:r.transformer?n:void 0}),this.logger.info(`${r.name} provider registered`)}catch(n){this.logger.error(`${r.name} provider registered error: ${n}`)}})}registerProvider(e){let r={...e};return this.providers.set(r.name,r),e.models.forEach(n=>{let s=`${r.name},${n}`,i={provider:r.name,model:n,fullModel:s};this.modelRoutes.set(s,i),this.modelRoutes.has(n)||this.modelRoutes.set(n,i)}),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 s={...n,...r,updatedAt:new Date};return this.providers.set(e,s),r.models&&(n.models.forEach(i=>{let u=`${n.name},${i}`;this.modelRoutes.delete(u),this.modelRoutes.delete(i)}),r.models.forEach(i=>{let u=`${n.name},${i}`,c={provider:n.name,model:i,fullModel:u};this.modelRoutes.set(u,c),this.modelRoutes.has(i)||this.modelRoutes.set(i,c)})),s}deleteProvider(e){let r=this.providers.get(e);return r?(r.models.forEach(n=>{let s=`${r.name},${n}`;this.modelRoutes.delete(s),this.modelRoutes.delete(n)}),this.providers.delete(e),!0):!1}toggleProvider(e,r){return!!this.providers.get(e)}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.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[s,i={}]=n;r[s]=i}else r[n]={};return r},{}):e:{}}async getAvailableModels(){let e=[];return this.providers.forEach(r=>{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 Je=[];for(let t=0;t<256;++t)Je.push((t+256).toString(16).slice(1));function ah(t,e=0){return(Je[t[e+0]]+Je[t[e+1]]+Je[t[e+2]]+Je[t[e+3]]+"-"+Je[t[e+4]]+Je[t[e+5]]+"-"+Je[t[e+6]]+Je[t[e+7]]+"-"+Je[t[e+8]]+Je[t[e+9]]+"-"+Je[t[e+10]]+Je[t[e+11]]+Je[t[e+12]]+Je[t[e+13]]+Je[t[e+14]]+Je[t[e+15]]).toLowerCase()}var uh=require("crypto"),Xo=new Uint8Array(256),Yo=Xo.length;function Lu(){return Yo>Xo.length-16&&((0,uh.randomFillSync)(Xo),Yo=0),Xo.slice(Yo,Yo+=16)}var ch=require("crypto"),Mu={randomUUID:ch.randomUUID};function ub(t,e,r){if(Mu.randomUUID&&!e&&!t)return Mu.randomUUID();t=t||{};let n=t.random??t.rng?.()??Lu();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 s=0;s<16;++s)e[r+s]=n[s];return e}return ah(n)}var Vt=ub;var lh=t=>t<=0?"none":t<=1024?"low":t<=8192?"medium":"high";var dh=(t,e)=>(t.includes("base64")&&(t=t.split("base64").pop(),t.startsWith(",")&&(t=t.slice(1))),`data:${e};base64,${t}`);var Qo=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 i=e.system.filter(u=>u.type==="text"&&u.text).map(u=>({type:"text",text:u.text,cache_control:u.cache_control}));r.push({role:"system",content:i})}}JSON.parse(JSON.stringify(e.messages||[]))?.forEach(i=>{if(i.role==="user"||i.role==="assistant"){if(typeof i.content=="string"){r.push({role:i.role,content:i.content});return}if(Array.isArray(i.content)){if(i.role==="user"){let u=i.content.filter(l=>l.type==="tool_result"&&l.tool_use_id);u.length&&u.forEach(l=>{let h={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(h)});let c=i.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"?dh(l.source.data,l.source.media_type):l.source.url},media_type:l.source.media_type}:l)})}else if(i.role==="assistant"){let u={role:"assistant",content:""},c=i.content.filter(f=>f.type==="text"&&f.text);c.length&&(u.content=c.map(f=>f.text).join(`
|
|
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 po,Od=Be(()=>{"use strict";po=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:s=!0,prefix:i,metadata:u}=r||{},c={data:e};return s&&(c.timestamp=new Date().toISOString()),i&&(c.prefix=i),u&&Object.keys(u).length>0&&(c.metadata=u),c}async sendRequest(e,r,n,s,i){let u=new AbortController,c=setTimeout(()=>u.abort(),i);try{let l=await fetch(e,{method:r,headers:n,body:JSON.stringify(s),signal:u.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,s,i,u){let c=null;for(let l=1;l<=u.maxAttempts;l++)try{return await this.sendRequest(e,r,n,s,i)}catch(h){if(c=h,l===u.maxAttempts)break;let f=u.backoffMs*Math.pow(2,l-1);console.warn(`[WebhookOutputHandler] Request failed (attempt ${l}/${u.maxAttempts}), retrying in ${f}ms...`,h.message),await this.delay(f)}throw c}async output(e,r={}){let n=r.timeout||this.defaultTimeout;try{let s=this.buildHeaders(),i=this.buildBody(e,r),u=await this.sendWithRetry(this.config.url,this.config.method,s,i,n,this.config.retry);return!0}catch(s){let i=s instanceof Error?s.message:String(s);if(this.config.silent)return console.error(`[WebhookOutputHandler] Failed to send data: ${i}`),!1;throw new Error(`Webhook output failed: ${i}`)}}}});var fs,Fd,t0,mo,xd=Be(()=>{"use strict";fs=require("fs"),Fd=require("path"),t0=require("os"),mo=class{type="temp-file";config;baseDir;constructor(e={}){this.config={subdirectory:"claude-code-router",extension:"json",includeTimestamp:!1,prefix:"session",...e};let r=(0,t0.tmpdir)();this.baseDir=(0,Fd.join)(r,this.config.subdirectory),this.ensureDir()}ensureDir(){try{(0,fs.existsSync)(this.baseDir)||(0,fs.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}`:"",s;if(this.config.includeTimestamp){let i=Date.now();s=`${r}-${e}-${i}${n}`}else s=`${r}-${e}${n}`;return(0,Fd.join)(this.baseDir,s)}async output(e,r={}){try{let n=r.metadata?.sessionId;if(!n)return!1;let s={...e,timestamp:Date.now(),sessionId:n},i=this.getFilePath(n);return(0,fs.writeFileSync)(i,JSON.stringify(s,null,2),"utf-8"),!0}catch{return!1}}getBaseDir(){return this.baseDir}}});var Pd,hs,r0=Be(()=>{"use strict";Rd();Od();xd();Pd=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),s=r.type+"_"+Date.now();this.registerHandler(s,n)}catch(n){console.error(`[OutputManager] Failed to register ${r.type} handler:`,n)}}createHandler(e){switch(e.type){case"console":return new ho(e.config);case"webhook":return new po(e.config);case"temp-file":return new mo(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},s={success:[],failed:[]},i=Array.from(this.handlers.entries()).map(async([u,c])=>{try{await c.output(e,n)?s.success.push(u):s.failed.push(u)}catch(l){console.error(`[OutputManager] Handler ${u} failed:`,l),s.failed.push(u)}});return await Promise.all(i),s}async outputTo(e,r,n){let s={...this.defaultOptions,...n},i={success:[],failed:[]},u=e.map(async c=>{let l=this.handlers.get(c);if(!l){console.warn(`[OutputManager] Handler ${c} not found`),i.failed.push(c);return}try{await l.output(r,s)?i.success.push(c):i.failed.push(c)}catch(h){console.error(`[OutputManager] Handler ${c} failed:`,h),i.failed.push(c)}});return await Promise.all(u),i}async outputToType(e,r,n){let s=Array.from(this.handlers.entries()).filter(([i,u])=>u.type===e).map(([i])=>i);return this.outputTo(s,r,n)}},hs=new Pd});var aD={};ku(aD,{ConfigService:()=>sn,ProviderHealthStore:()=>ks,ProviderService:()=>an,SSEParserTransform:()=>wn,SSESerializerTransform:()=>fo,TokenizerService:()=>Cn,TransformerService:()=>bn,calculateTokenCount:()=>Ed,default:()=>iD,getHealthStore:()=>on,pluginManager:()=>kd,rewriteStream:()=>vd,router:()=>Ya,searchProjectBySession:()=>Ad,sessionUsageCache:()=>Wa,tokenSpeedPlugin:()=>Nd});module.exports=J_(aD);var o0=Ue(require("fastify"),1),i0=Ue(require("@fastify/cors"),1);var Ss=require("fs"),Nu=require("path"),Xf=require("dotenv"),Qf=Ue(Iu(),1),sn=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,Nu.join)(process.cwd(),this.options.jsonPath);if((0,Ss.existsSync)(e))try{let r=(0,Ss.readFileSync)(e,"utf-8"),n=Qf.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,Nu.join)(process.cwd(),this.options.envPath);if((0,Ss.existsSync)(e))try{let r=(0,Xf.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 nt(t,e=500,r="internal_error",n="api_error"){let s=new Error(t);return s.statusCode=e,s.code=r,s.type=n,s}async function Zf(t,e,r){e.log.error(t);let n=t.statusCode||500,s={error:{message:t.message+t.stack||"Internal Server Error",type:t.type||"api_error",code:t.code||"internal_error"}};return r.code(n).send(s)}var eh=require("undici");function th(t,e,r,n,s){let i=new Headers({"Content-Type":"application/json"});r.headers&&Object.entries(r.headers).forEach(([h,f])=>{f&&i.set(h,f)});let u,c=AbortSignal.timeout(r.TIMEOUT??60*1e3*60);if(r.signal){let h=new AbortController,f=()=>h.abort();r.signal.addEventListener("abort",f),c.addEventListener("abort",f),u=h.signal}else u=c;let l={method:"POST",headers:i,body:JSON.stringify(e),signal:u};return r.httpsProxy&&(l.dispatcher=new eh.ProxyAgent(new URL(r.httpsProxy).toString())),s?.debug({reqId:n.req.id,request:l,headers:Object.fromEntries(i.entries()),requestUrl:typeof t=="string"?t:t.toString(),useProxy:r.httpsProxy},"final request"),fetch(typeof t=="string"?t:t.toString(),l)}var rh="2.0.37";var nb={enabled:!0,failureThreshold:3,probeIntervalMinutes:5,halfOpenSuccessThreshold:2,rateLimitThreshold:1},ks=class{states=new Map;config;probeTimer;constructor(e){this.config={...nb,...e}}getKey(e,r){return`${e},${r}`}recordSuccess(e,r){if(!this.config.enabled)return;let n=this.getKey(e,r),s=this.states.get(n);s&&(s.successCount++,s.status==="half-open"?s.successCount>=this.config.halfOpenSuccessThreshold&&this.states.delete(n):s.status==="open"&&(s.status="half-open",s.successCount=1,s.failureCount=0))}isRateLimitError(e){if(!e)return!1;let r=e.toLowerCase();return r.includes("429")||r.includes("rate_limit")||r.includes("ratelimit")||r.includes("rate limit")||r.includes("overloaded")||r.includes("quota")}recordFailure(e,r,n){if(!this.config.enabled)return;let s=this.getKey(e,r),i=this.states.get(s);i||(i={provider:e,model:r,status:"closed",failureCount:0,successCount:0,lastFailureTime:0,lastProbeTime:0},this.states.set(s,i)),i.failureCount++,i.lastFailureTime=Date.now(),i.lastError=n;let c=this.isRateLimitError(n)?this.config.rateLimitThreshold:this.config.failureThreshold;i.status==="half-open"?(i.status="open",i.successCount=0,i.lastProbeTime=0):i.status==="closed"&&i.failureCount>=c&&(i.status="open",i.lastProbeTime=0)}getState(e,r){return this.states.get(this.getKey(e,r))}isAvailable(e,r){if(!this.config.enabled)return!0;let n=this.getState(e,r);return n?n.status!=="open":!0}getPriority(e,r){if(!this.config.enabled)return 0;let n=this.getState(e,r);if(!n)return 0;switch(n.status){case"closed":return 0;case"half-open":return 1;case"open":return 2}}getHealthyModels(){return[]}getFailPoolModels(){let e=[];for(let[r,n]of this.states)n.status==="open"&&e.push(r);return e}getHalfOpenModels(){let e=[];for(let[r,n]of this.states)n.status==="half-open"&&e.push(r);return e}needsProbe(e){return Date.now()-e.lastProbeTime>=this.config.probeIntervalMinutes*60*1e3}markProbeAttempt(e,r){let n=this.getKey(e,r),s=this.states.get(n);s&&s.status==="open"&&(s.lastProbeTime=Date.now())}clear(){this.states.clear()}getAllStates(){return Array.from(this.states.values())}stopProbeTimer(){this.probeTimer&&(clearInterval(this.probeTimer),this.probeTimer=void 0)}},Bu=null;function on(t){return Bu||(Bu=new ks(t)),Bu}async function sb(t,e,r,n){let s=t.body,i=t.provider,u=r.providerService.getProvider(i);if(!u)throw nt(`Provider '${i}' not found`,404,"provider_not_found");try{let{requestBody:c,config:l,bypass:h}=await nh(s,u,n,t.headers,{req:t}),f=await sh(c,l,u,r,h,n,{req:t}),p=await oh(c,f,u,n,h,{req:t});return ih(p,e,s)}catch(c){let l=await ob(t,e,r,n,c);if(l)return l;throw c}}async function ob(t,e,r,n,s){let i=t.scenarioType||"default",u=t.familyFallback,c=r.configService.get("fallback"),l=on(),h=[];if(u?.[i]?h=u[i]:c?.[i]&&(h=c[i]),!Array.isArray(h)||h.length===0)return null;let f=t.provider||"",p=t.body.model||"";l.recordFailure(f,p,s?.message),t.log.warn(`Request failed for ${t.scenarioType}, trying ${h.length} fallback models`);let S=h.sort((D,E)=>{let[y,g]=D.split(","),[m,T]=E.split(",");return l.getPriority(y,g)-l.getPriority(m,T)});for(let D of S)try{let[E,...y]=D.split(","),g=y.join(",");if(!l.isAvailable(E,g)){t.log.warn(`Fallback model ${D} unavailable (fail pool), skipping`);continue}t.log.info(`Trying fallback model: ${D}`);let m={...t.body};m.model=g;let T={...t,provider:E,body:m},b=r.providerService.getProvider(E);if(!b){t.log.warn(`Fallback provider '${E}' not found, skipping`);continue}let{requestBody:w,config:O,bypass:x}=await nh(m,b,n,t.headers,{req:T}),$=await sh(w,O,b,r,x,n,{req:T}),V=await oh(w,$,b,n,x,{req:T});return t.log.info(`Fallback model ${D} succeeded`),l.recordSuccess(E,g),ih(V,e,m)}catch(E){let[y,...g]=D.split(","),m=g.join(",");l.recordFailure(y,m,E.message),t.log.warn(`Fallback model ${D} failed: ${E.message}`);continue}return t.log.error(`All fallback models failed for ${i}`),null}async function nh(t,e,r,n,s){let i=JSON.parse(JSON.stringify(t)),u={},c=!1;if(c=ib(e,r,t),c&&(n instanceof Headers?n.delete("content-length"):delete n["content-length"],u.headers=n),!c&&typeof r.transformRequestOut=="function"){let l=await r.transformRequestOut(i);l.body?(i=l.body,u=l.config||{}):i=l}if(!c&&e.transformer?.use?.length)for(let l of e.transformer.use){if(!l||typeof l.transformRequestIn!="function")continue;let h=await l.transformRequestIn(i,e,s);h.body?(i=h.body,u={...u,...h.config}):i=h}if(!c&&e.transformer?.[t.model]?.use?.length)for(let l of e.transformer[t.model].use)!l||typeof l.transformRequestIn!="function"||(i=await l.transformRequestIn(i,e,s));return{requestBody:i,config:u,bypass:c}}function ib(t,e,r){return 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 sh(t,e,r,n,s,i,u){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(s&&typeof i.auth=="function"){let f=await i.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];let h=await th(c,t,{httpsProxy:n.configService.getHttpsProxy(),...e,headers:JSON.parse(JSON.stringify(l))},u,n.log);if(!h.ok){let f=await h.text();throw n.log.error(`[provider_response_error] Error from provider(${r.name},${t.model}: ${h.status}): ${f}`),nt(`Error from provider(${r.name},${t.model}: ${h.status}): ${f}`,h.status,"provider_response_error")}return h}async function oh(t,e,r,n,s,i){let u=e;if(!s&&r.transformer?.use?.length)for(let c of Array.from(r.transformer.use).reverse())!c||typeof c.transformResponseOut!="function"||(u=await c.transformResponseOut(u,i));if(!s&&r.transformer?.[t.model]?.use?.length)for(let c of Array.from(r.transformer[t.model].use).reverse())!c||typeof c.transformResponseOut!="function"||(u=await c.transformResponseOut(u,i));return!s&&n.transformResponseIn&&(u=await n.transformResponseIn(u,i)),u}function ih(t,e,r){return t.ok||e.code(t.status),r.stream===!0?(e.header("Content-Type","text/event-stream"),e.header("Cache-Control","no-cache"),e.header("Connection","keep-alive"),e.send(t.body)):t.json()}var ju=async t=>{t.get("/",async()=>({message:"LLMs API",version:rh})),t.get("/health",async()=>({status:"ok",timestamp:new Date().toISOString()})),t.get("/providers/health",async()=>({states:on().getAllStates().map(s=>({provider:s.provider,model:s.model,status:s.status,failureCount:s.failureCount,successCount:s.successCount,lastFailureTime:s.lastFailureTime,lastError:s.lastError})),timestamp:new Date().toISOString()}));let e=t.transformerService.getTransformersWithEndpoint();for(let{transformer:r}of e)r.endPoint&&t.post(r.endPoint,async(n,s)=>sb(n,s,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:s,baseUrl:i,apiKey:u,models:c}=r.body;if(!s?.trim())throw nt("Provider name is required",400,"invalid_request");if(!i||!ab(i))throw nt("Valid base URL is required",400,"invalid_request");if(!u?.trim())throw nt("API key is required",400,"invalid_request");if(!c||!Array.isArray(c)||c.length===0)throw nt("At least one model is required",400,"invalid_request");if(t.providerService.getProvider(r.body.name))throw nt(`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 nt("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 s=t.providerService.updateProvider(r.params.id,r.body);if(!s)throw nt("Provider not found",404,"provider_not_found");return s}),t.delete("/providers/:id",{schema:{params:{type:"object",properties:{id:{type:"string"}},required:["id"]}}},async r=>{if(!t.providerService.deleteProvider(r.params.id))throw nt("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 nt("Provider not found",404,"provider_not_found");return{message:`Provider ${r.body.enabled?"enabled":"disabled"} successfully`}})};function ab(t){try{return new URL(t),!0}catch{return!1}}var an=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(s=>{s==="use"?Array.isArray(r.transformer.use)&&(n.use=r.transformer.use.map(i=>{if(Array.isArray(i)&&typeof i[0]=="string"){let u=this.transformerService.getTransformer(i[0]);if(u)return new u(i[1])}if(typeof i=="string"){let u=this.transformerService.getTransformer(i);return typeof u=="function"?new u:u}}).filter(i=>typeof i<"u")):Array.isArray(r.transformer[s]?.use)&&(n[s]={use:r.transformer[s].use.map(i=>{if(Array.isArray(i)&&typeof i[0]=="string"){let u=this.transformerService.getTransformer(i[0]);if(u)return new u(i[1])}if(typeof i=="string"){let u=this.transformerService.getTransformer(i);return typeof u=="function"?new u:u}}).filter(i=>typeof i<"u")})}),this.registerProvider({name:r.name,baseUrl:r.api_base_url,apiKey:r.api_key,models:r.models||[],transformer:r.transformer?n:void 0}),this.logger.info(`${r.name} provider registered`)}catch(n){this.logger.error(`${r.name} provider registered error: ${n}`)}})}registerProvider(e){let r={...e};return this.providers.set(r.name,r),e.models.forEach(n=>{let s=`${r.name},${n}`,i={provider:r.name,model:n,fullModel:s};this.modelRoutes.set(s,i),this.modelRoutes.has(n)||this.modelRoutes.set(n,i)}),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 s={...n,...r,updatedAt:new Date};return this.providers.set(e,s),r.models&&(n.models.forEach(i=>{let u=`${n.name},${i}`;this.modelRoutes.delete(u),this.modelRoutes.delete(i)}),r.models.forEach(i=>{let u=`${n.name},${i}`,c={provider:n.name,model:i,fullModel:u};this.modelRoutes.set(u,c),this.modelRoutes.has(i)||this.modelRoutes.set(i,c)})),s}deleteProvider(e){let r=this.providers.get(e);return r?(r.models.forEach(n=>{let s=`${r.name},${n}`;this.modelRoutes.delete(s),this.modelRoutes.delete(n)}),this.providers.delete(e),!0):!1}toggleProvider(e,r){return!!this.providers.get(e)}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.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[s,i={}]=n;r[s]=i}else r[n]={};return r},{}):e:{}}async getAvailableModels(){let e=[];return this.providers.forEach(r=>{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 Je=[];for(let t=0;t<256;++t)Je.push((t+256).toString(16).slice(1));function ah(t,e=0){return(Je[t[e+0]]+Je[t[e+1]]+Je[t[e+2]]+Je[t[e+3]]+"-"+Je[t[e+4]]+Je[t[e+5]]+"-"+Je[t[e+6]]+Je[t[e+7]]+"-"+Je[t[e+8]]+Je[t[e+9]]+"-"+Je[t[e+10]]+Je[t[e+11]]+Je[t[e+12]]+Je[t[e+13]]+Je[t[e+14]]+Je[t[e+15]]).toLowerCase()}var uh=require("crypto"),Xo=new Uint8Array(256),Yo=Xo.length;function Lu(){return Yo>Xo.length-16&&((0,uh.randomFillSync)(Xo),Yo=0),Xo.slice(Yo,Yo+=16)}var ch=require("crypto"),Mu={randomUUID:ch.randomUUID};function ub(t,e,r){if(Mu.randomUUID&&!e&&!t)return Mu.randomUUID();t=t||{};let n=t.random??t.rng?.()??Lu();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 s=0;s<16;++s)e[r+s]=n[s];return e}return ah(n)}var Vt=ub;var lh=t=>t<=0?"none":t<=1024?"low":t<=8192?"medium":"high";var dh=(t,e)=>(t.includes("base64")&&(t=t.split("base64").pop(),t.startsWith(",")&&(t=t.slice(1))),`data:${e};base64,${t}`);var Qo=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 i=e.system.filter(u=>u.type==="text"&&u.text).map(u=>({type:"text",text:u.text,cache_control:u.cache_control}));r.push({role:"system",content:i})}}JSON.parse(JSON.stringify(e.messages||[]))?.forEach(i=>{if(i.role==="user"||i.role==="assistant"){if(typeof i.content=="string"){r.push({role:i.role,content:i.content});return}if(Array.isArray(i.content)){if(i.role==="user"){let u=i.content.filter(l=>l.type==="tool_result"&&l.tool_use_id);u.length&&u.forEach(l=>{let h={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(h)});let c=i.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"?dh(l.source.data,l.source.media_type):l.source.url},media_type:l.source.media_type}:l)})}else if(i.role==="assistant"){let u={role:"assistant",content:""},c=i.content.filter(f=>f.type==="text"&&f.text);c.length&&(u.content=c.map(f=>f.text).join(`
|
|
73
73
|
`));let l=i.content.filter(f=>f.type==="tool_use"&&f.id);l.length&&(u.tool_calls=l.map(f=>({id:f.id,type:"function",function:{name:f.name,arguments:JSON.stringify(f.input||{})}})));let h=i.content.find(f=>f.type==="thinking"&&f.signature);h&&(u.thinking={content:h.thinking,signature:h.signature}),r.push(u)}return}}});let s={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&&(s.reasoning={effort:lh(e.thinking.budget_tokens),enabled:e.thinking.type==="enabled"}),e.tool_choice&&(e.tool_choice.type==="tool"?s.tool_choice={type:"function",function:{name:e.tool_choice.name}}:s.tool_choice=e.tool_choice.type),s}async transformResponseIn(e,r){if(e.headers.get("Content-Type")?.includes("text/event-stream")){if(!e.body)throw new Error("Stream response body is null");let s=await this.convertOpenAIStreamToAnthropic(e.body,r);return new Response(s,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}else{let s=await e.json(),i=this.convertOpenAIResponseToAnthropic(s,r);return new Response(JSON.stringify(i),{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 s=>{let i=new TextEncoder,u=`msg_${Date.now()}`,c=null,l="unknown",h=!1,f=!1,p=!1,S=new Map,D=new Map,E=0,y=0,g=0,m=!1,T=!1,b=0,w=-1,O=()=>{let U=b;return b++,U},x=U=>{if(!m)try{s.enqueue(U);let X=new TextDecoder().decode(U);this.logger.debug({reqId:r.req.id,data:X,type:"send data"})}catch(X){if(X instanceof TypeError&&X.message.includes("Controller is already closed"))m=!0;else throw this.logger.debug({reqId:r.req.id,error:X instanceof Error?X.message:String(X),type:"send data error"}),X}},$=()=>{if(!m)try{if(w>=0){let X={type:"content_block_stop",index:w};x(i.encode(`event: content_block_stop
|
|
74
74
|
data: ${JSON.stringify(X)}
|
|
75
75
|
|
|
@@ -344,7 +344,7 @@ Stack: ${e.stack}`)}}async registerDefaultTransformersInternal(){try{Object.valu
|
|
|
344
344
|
`),e.data&&(e.data.type==="done"?n+=`data: [DONE]
|
|
345
345
|
`:n+=`data: ${JSON.stringify(e.data)}
|
|
346
346
|
`),n+=`
|
|
347
|
-
`,r.enqueue(n)}})}};var vd=(t,e)=>{let r=t.getReader();return new ReadableStream({async start(n){try{for(;;){let{done:s,value:i}=await r.read();if(s){n.close();break}let u=await e(i,n);u!==void 0&&n.enqueue(u)}}catch(s){n.error(s)}finally{r.releaseLock()}}})};Rd();Od();xd();r0();var go=new Map,Id=new Map,Nd={name:"token-speed",version:"1.0.0",description:"Statistics for streaming response token generation speed",register:(0,s0.default)(async(t,e)=>{let r={reporter:["console","temp-file"],...e},n=Array.isArray(r.reporter)?r.reporter:[r.reporter];if(r.outputHandlers&&r.outputHandlers.length>0)hs.registerHandlers(r.outputHandlers);else{let i=[];for(let u of n)u==="console"?i.push({type:"console",enabled:!0,config:{colors:!0,level:"log"}}):u==="temp-file"?i.push({type:"temp-file",enabled:!0,config:{subdirectory:"claude-code-router",extension:"json",includeTimestamp:!0,prefix:"session"}}):u==="webhook"&&console.warn("[TokenSpeedPlugin] Webhook reporter requires explicit configuration in outputHandlers");i.length>0&&hs.registerHandlers(i)}r.outputOptions&&hs.setDefaultOptions(r.outputOptions);let s=async i=>{let u=t.tokenizerService;if(!u)return t.log?.warn("TokenizerService not available"),null;if(!i.provider||!i.model)return null;let c=i.provider,l=i.model,h=`${c}:${l}`;if(Id.has(h))return Id.get(h);let f=u.getTokenizerConfigForModel(c,l);if(!f)return t.log?.debug(`No tokenizer config for ${c}:${l}, using fallback`),null;try{let p=await u.getTokenizer(f);return Id.set(h,p),t.log?.info(`Created tokenizer for ${c}:${l} - ${p.name}`),p}catch(p){return t.log?.warn(`Failed to create tokenizer for ${c}:${l}: ${p.message}`),null}};t.addHook("onRequest",async i=>{new URL(`http://127.0.0.1${i.url}`).pathname.endsWith("/v1/messages")&&(i.requestStartTime=performance.now())}),t.addHook("onSend",async(i,u,c)=>{let l=i.requestStartTime;if(!l)return;let h=i.id||Date.now().toString(),f;try{let E=i.body?.metadata?.user_id;if(E&&typeof E=="string")try{let y=JSON.parse(E);y.session_id&&(f=y.session_id)}catch{let y=E.match(/_session_([a-f0-9-]+)/i);f=y?y[1]:void 0}}catch{}if(!f)return;let p=await s(i);if(c instanceof ReadableStream){go.set(h,{requestId:h,sessionId:f,startTime:l,lastTokenTime:l,tokenCount:0,tokensPerSecond:0,tokenTimestamps:[],stream:!0});let[E,y]=c.tee();return(async()=>{let m=null,T=async b=>{let w=go.get(h);if(!w)return;let O=performance.now();if(b){let x=(w.lastTokenTime-w.startTime)/1e3
|
|
347
|
+
`,r.enqueue(n)}})}};var vd=(t,e)=>{let r=t.getReader();return new ReadableStream({async start(n){try{for(;;){let{done:s,value:i}=await r.read();if(s){n.close();break}let u=await e(i,n);u!==void 0&&n.enqueue(u)}}catch(s){n.error(s)}finally{r.releaseLock()}}})};Rd();Od();xd();r0();var go=new Map,Id=new Map,Nd={name:"token-speed",version:"1.0.0",description:"Statistics for streaming response token generation speed",register:(0,s0.default)(async(t,e)=>{let r={reporter:["console","temp-file"],...e},n=Array.isArray(r.reporter)?r.reporter:[r.reporter];if(r.outputHandlers&&r.outputHandlers.length>0)hs.registerHandlers(r.outputHandlers);else{let i=[];for(let u of n)u==="console"?i.push({type:"console",enabled:!0,config:{colors:!0,level:"log"}}):u==="temp-file"?i.push({type:"temp-file",enabled:!0,config:{subdirectory:"claude-code-router",extension:"json",includeTimestamp:!0,prefix:"session"}}):u==="webhook"&&console.warn("[TokenSpeedPlugin] Webhook reporter requires explicit configuration in outputHandlers");i.length>0&&hs.registerHandlers(i)}r.outputOptions&&hs.setDefaultOptions(r.outputOptions);let s=async i=>{let u=t.tokenizerService;if(!u)return t.log?.warn("TokenizerService not available"),null;if(!i.provider||!i.model)return null;let c=i.provider,l=i.model,h=`${c}:${l}`;if(Id.has(h))return Id.get(h);let f=u.getTokenizerConfigForModel(c,l);if(!f)return t.log?.debug(`No tokenizer config for ${c}:${l}, using fallback`),null;try{let p=await u.getTokenizer(f);return Id.set(h,p),t.log?.info(`Created tokenizer for ${c}:${l} - ${p.name}`),p}catch(p){return t.log?.warn(`Failed to create tokenizer for ${c}:${l}: ${p.message}`),null}};t.addHook("onRequest",async i=>{new URL(`http://127.0.0.1${i.url}`).pathname.endsWith("/v1/messages")&&(i.requestStartTime=performance.now())}),t.addHook("onSend",async(i,u,c)=>{let l=i.requestStartTime;if(!l)return;let h=i.id||Date.now().toString(),f;try{let E=i.body?.metadata?.user_id;if(E&&typeof E=="string")try{let y=JSON.parse(E);y.session_id&&(f=y.session_id)}catch{let y=E.match(/_session_([a-f0-9-]+)/i);f=y?y[1]:void 0}}catch{}if(!f)return;let p=await s(i);if(c instanceof ReadableStream){go.set(h,{requestId:h,sessionId:f,startTime:l,lastTokenTime:l,tokenCount:0,tokensPerSecond:0,tokenTimestamps:[],stream:!0});let[E,y]=c.tee();return(async()=>{let m=null,T=async b=>{let w=go.get(h);if(!w)return;let O=performance.now();if(b){let x=w.firstTokenTime?w.firstTokenTime-w.startTime:0,$=(w.lastTokenTime-w.startTime-x)/1e3;$>0&&(w.tokensPerSecond=Math.round(w.tokenCount/$))}else{let x=O-1e3;w.tokenTimestamps=w.tokenTimestamps.filter($=>$>x),w.tokensPerSecond=w.tokenTimestamps.length}await n0(w,n,r.outputOptions,b).catch(x=>{t.log?.warn(`Failed to output streaming stats: ${x.message}`)})};try{let w=y.pipeThrough(new TextDecoderStream).pipeThrough(new wn).getReader();for(m=setInterval(async()=>{go.get(h)&&await T(!1)},1e3);;){let{done:O,value:x}=await w.read();if(O)break;let $=x,V=go.get(h);if(!V)continue;let U=performance.now();if(!V.firstTokenTime&&($.event==="content_block_start"||$.event==="content_block_delta"||$.event==="text_block"||$.event==="content_block")&&(V.firstTokenTime=U,V.timeToFirstToken=Math.round(U-V.startTime)),$.event==="content_block_delta"&&$.data?.delta){let X=$.data.delta.type,re="";if(X==="text_delta"?re=$.data.delta.text||"":X==="input_json_delta"?re=$.data.delta.partial_json||"":X==="thinking_delta"&&(re=$.data.delta.thinking||""),re){let ie=p&&p.encodeText?p.encodeText(re).length:yo(re);V.tokenCount+=ie,V.lastTokenTime=U;for(let le=0;le<ie;le++)V.tokenTimestamps.push(U)}}$.event==="message_stop"&&(m&&(clearInterval(m),m=null),await T(!0),go.delete(h))}}catch(b){m&&clearInterval(m),b.name!=="AbortError"&&b.code!=="ERR_STREAM_PREMATURE_CLOSE"&&t.log?.warn(`Error processing token stats: ${b.message}`)}})().catch(m=>{console.log(m),t.log?.warn(`Background stats processing failed: ${m.message}`)}),E}let S=performance.now(),D=0;if(c&&typeof c=="string")try{let E=JSON.parse(c);if(E.usage?.output_tokens)D=E.usage.output_tokens;else{let y=E.content||E.message?.content||"";if(p)Array.isArray(y)?D=y.reduce((g,m)=>{if(m.type==="text"){let T=m.text||"";return g+(p.encodeText?p.encodeText(T).length:yo(T))}return g},0):typeof y=="string"&&(D=p.encodeText?p.encodeText(y).length:yo(y));else{let g=Array.isArray(y)?y.map(m=>m.text).join(""):y;D=yo(g)}}}catch{}if(D>0){let E=Math.round(S-l),y=S-l-E>0?(S-l-E)/1e3:(S-l)/1e3,g={requestId:h,sessionId:f,startTime:l,lastTokenTime:S,tokenCount:D,tokensPerSecond:y>0?Math.round(D/y):0,timeToFirstToken:E,stream:!1,tokenTimestamps:[]};await n0(g,n,r.outputOptions,!0)}return c})})};function yo(t){let e=(t.match(/[\u4e00-\u9fa5]/g)||[]).length,r=t.length-e;return Math.ceil(e/1.5+r/4)}async function n0(t,e,r,n=!1){let s=n?"[Token Speed Final]":"[Token Speed]",i={requestId:t.requestId.substring(0,8),sessionId:t.sessionId,stream:t.stream,tokenCount:t.tokenCount,tokensPerSecond:t.tokensPerSecond,timeToFirstToken:t.timeToFirstToken?`${t.timeToFirstToken}ms`:"N/A",duration:`${((t.lastTokenTime-t.startTime)/1e3).toFixed(2)}s`,timestamp:Date.now()},u={prefix:s,metadata:{sessionId:t.sessionId},...r};for(let c of e)try{await hs.outputToType(c,i,u)}catch(l){console.error(`[TokenSpeedPlugin] Failed to output to ${c}:`,l)}}function oD(t={}){let e=(0,o0.default)({bodyLimit:52428800,...t});return e.setErrorHandler(Zf),e.register(i0.default),e}var Bd=class{app;configService;providerService;transformerService;tokenizerService;constructor(e={}){let{initialConfig:r,...n}=e;this.app=oD({...n,logger:n.logger??!0}),this.configService=new sn(e),this.transformerService=new bn(this.configService,this.app.log),this.tokenizerService=new Cn(this.configService,this.app.log),this.transformerService.initialize().finally(()=>{this.providerService=new an(this.configService,this.transformerService,this.app.log)}),this.tokenizerService.initialize().catch(s=>{this.app.log.error(`Failed to initialize TokenizerService: ${s}`)})}async register(e,r){await this.app.register(e,r)}addHook(e,r){this.app.addHook(e,r)}async registerNamespace(e,r){if(!e)throw new Error("name is required");if(e==="/"){await this.app.register(async c=>{c.decorate("configService",this.configService),c.decorate("transformerService",this.transformerService),c.decorate("providerService",this.providerService),c.decorate("tokenizerService",this.tokenizerService),c.addHook("preHandler",async(l,h)=>{new URL(`http://127.0.0.1${l.url}`).pathname.endsWith("/v1/messages")&&await Ya(l,h,{configService:this.configService,tokenizerService:this.tokenizerService})}),await ju(c)});return}if(!r)throw new Error("options is required");let n=new sn({initialConfig:{providers:r.Providers,Router:r.Router}}),s=new bn(n,this.app.log);await s.initialize();let i=new an(n,s,this.app.log),u=new Cn(n,this.app.log);await u.initialize(),await this.app.register(async c=>{c.decorate("configService",n),c.decorate("transformerService",s),c.decorate("providerService",i),c.decorate("tokenizerService",u),c.addHook("preHandler",async(l,h)=>{new URL(`http://127.0.0.1${l.url}`).pathname.endsWith("/v1/messages")&&await Ya(l,h,{configService:n,tokenizerService:u})}),await ju(c)},{prefix:e})}async start(){try{this.app._server=this,this.app.addHook("preHandler",(n,s,i)=>{if(new URL(`http://127.0.0.1${n.url}`).pathname.endsWith("/v1/messages")&&n.body){let c=n.body;n.log.info({data:c,type:"request body"}),c.stream||(c.stream=!1)}i()}),await this.registerNamespace("/"),this.app.addHook("preHandler",async(n,s)=>{if(new URL(`http://127.0.0.1${n.url}`).pathname.endsWith("/v1/messages")&&n.body)try{let u=n.body;if(!u||!u.model)return s.code(400).send({error:"Missing model in request body"});let[c,...l]=u.model.split(",");u.model=l.join(","),n.provider=c,n.model=l;return}catch(u){return n.log.error({error:u},"Error in modelProviderMiddleware:"),s.code(500).send({error:"Internal server error"})}});let e=await this.app.listen({port:parseInt(this.configService.get("PORT")||"3000",10),host:this.configService.get("HOST")||"127.0.0.1"});this.app.log.info(`\u{1F680} LLMs API server listening on ${e}`);let r=async n=>{this.app.log.info(`Received ${n}, shutting down gracefully...`),await this.app.close(),process.exit(0)};process.on("SIGINT",()=>r("SIGINT")),process.on("SIGTERM",()=>r("SIGTERM"))}catch(e){this.app.log.error(`Error starting server: ${e}`),process.exit(1)}}},iD=Bd;0&&(module.exports={ConfigService,ProviderHealthStore,ProviderService,SSEParserTransform,SSESerializerTransform,TokenizerService,TransformerService,calculateTokenCount,getHealthStore,pluginManager,rewriteStream,router,searchProjectBySession,sessionUsageCache,tokenSpeedPlugin});
|
|
348
348
|
/*! Bundled license information:
|
|
349
349
|
|
|
350
350
|
web-streams-polyfill/dist/ponyfill.es2018.js:
|