xling 0.9.7 → 0.9.8

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.
@@ -1,4 +1,4 @@
1
- import{c as e,u as t}from"../../validators-CzOBqk3u.js";import"../../errors-BzZfdKtJ.js";import"../../editor-6Nht_jnv.js";import"../../config-Bf-EeKY5.js";import"../../fsStore-CwAffYMN.js";import"../../base-BUo37ebo.js";import"../../template-zeZsnoLb.js";import"../../xling-CMIOhJ6S.js";import"../../loadBalancer-BUZZKUIh.js";import"../../errorClassifier-B-lYIh-6.js";import"../../transformer-DTxdVklF.js";import{a as n,t as r}from"../../server-Dag3i5Zg.js";import{Command as i,Flags as a}from"@oclif/core";var o=class o extends i{static summary=`Start an OpenAI-compatible proxy server with load balancing and key rotation`;static description=`Boot a local proxy server that forwards requests to configured upstream AI providers.
1
+ import{c as e,u as t}from"../../validators-CzOBqk3u.js";import"../../errors-BzZfdKtJ.js";import"../../editor-6Nht_jnv.js";import"../../config-Bf-EeKY5.js";import"../../fsStore-CwAffYMN.js";import"../../base-BUo37ebo.js";import"../../template-zeZsnoLb.js";import"../../xling-CMIOhJ6S.js";import"../../loadBalancer-BUZZKUIh.js";import"../../errorClassifier-B-lYIh-6.js";import"../../transformer-DTxdVklF.js";import{a as n,t as r}from"../../server-CAH57wTY.js";import{Command as i,Flags as a}from"@oclif/core";var o=class o extends i{static summary=`Start an OpenAI-compatible proxy server with load balancing and key rotation`;static description=`Boot a local proxy server that forwards requests to configured upstream AI providers.
2
2
 
3
3
  Features:
4
4
  - OpenAI Chat Completions API (/v1/chat/completions)
@@ -1 +1 @@
1
- import{Command as e}from"@oclif/core";var t=`0.9.7`,n=class extends e{static summary=`Show the current xling version`;static description=`Displays the version from package.json.`;static examples=[{description:`Print the installed CLI version`,command:`<%= config.bin %> <%= command.id %>`},{description:`Shortcut using the built-in flag`,command:`<%= config.bin %> --version`}];async run(){this.log(t??`unknown`)}};export{n as default};
1
+ import{Command as e}from"@oclif/core";var t=`0.9.8`,n=class extends e{static summary=`Show the current xling version`;static description=`Displays the version from package.json.`;static examples=[{description:`Print the installed CLI version`,command:`<%= config.bin %> <%= command.id %>`},{description:`Shortcut using the built-in flag`,command:`<%= config.bin %> --version`}];async run(){this.log(t??`unknown`)}};export{n as default};
@@ -0,0 +1 @@
1
+ import{p as e}from"./config-Bf-EeKY5.js";import{m as t}from"./fsStore-CwAffYMN.js";import{t as n}from"./xling-CMIOhJ6S.js";import{t as r}from"./loadBalancer-BUZZKUIh.js";import{t as i}from"./errorClassifier-B-lYIh-6.js";import{c as a,i as o,l as s,n as c,o as l,r as u,s as d,t as f}from"./transformer-DTxdVklF.js";import{watch as p}from"node:fs";const m=4320;function h(){return`req_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,8)}`}function g(e){if(typeof e==`string`)return e;if(typeof e==`number`||typeof e==`boolean`)return String(e);if(e==null)return``;if(typeof e==`object`)try{return JSON.stringify(e)}catch{return`[object Object]`}return typeof e==`symbol`?e.toString():typeof e==`function`?e.name||`[function]`:``}async function _(e={}){let i=new n,a=i.resolvePath(`user`),o=i.readConfig(a);if(!o.providers?.length)throw Error(`No providers configured in ~/.claude/xling.json. Add a 'providers' array.`);let s=()=>o,c=o.proxy??{},l=e.host??c.host??`127.0.0.1`,u=e.port??c.port??m,d=e.accessKey??c.accessKey,f=new r(c.loadBalance??`failover`,c.keyRotation?.cooldownMs??6e4),h=Bun.serve({hostname:l,port:u,async fetch(t){let n=new URL(t.url).pathname;if(t.method===`OPTIONS`)return new Response(null,{status:204,headers:E()});if(n===`/health`||n===`/`){let e=s();return Response.json({status:`ok`,providers:e.providers.map(e=>e.name),loadBalance:e.proxy?.loadBalance??`failover`},{headers:E()})}if(n===`/stats`)return Response.json({stats:f.getStats()},{headers:E()});if(n===`/v1/models`||n===`/models`){let e=O(s().providers);return Response.json(e,{headers:E()})}if(d){let r=t.headers.get(`authorization`),i=t.headers.get(`x-api-key`)??t.headers.get(`X-Api-Key`),a=r?.replace(/^Bearer\s+/i,``)||i||void 0;if(a!==d){if(e.logger){console.log(`[auth] Access key validation failed for path: ${n}`),console.log(`[auth] Expected: ${d.slice(0,4)}...`);let e=a?a.slice(0,4)+`...`:`(none)`;console.log(`[auth] Received: ${e}`)}return Response.json({error:{message:`Invalid access key`,type:`auth_error`}},{status:401,headers:E()})}}return n.startsWith(`/v1/`)||n.startsWith(`/claude/`)||n.startsWith(`/openai/`)||n===`/responses`||n===`/messages`||n===`/chat/completions`?(e.logger&&console.log(`[proxy] Handling request: ${t.method} ${n}`),v(t,n,()=>{let e=s();return{providers:e.providers,modelMapping:e.proxy?.modelMapping,defaultModel:e.defaultModel,passthroughResponsesAPI:e.proxy?.passthroughResponsesAPI,keyRotation:e.proxy?.keyRotation}},f,e.logger??!0)):(e.logger&&console.log(`[proxy] 404 Not Found: ${t.method} ${n}`),Response.json({error:{message:`Not found`,type:`not_found`}},{status:404,headers:E()}))}}),g=t(a),_=null;try{_=p(g,t=>{if(t===`change`)try{let t=i.readConfig(a);t.providers?.length&&(o=t,e.logger&&console.log(`[proxy] Config reloaded`))}catch(t){e.logger&&console.error(`[proxy] Failed to reload config:`,t)}})}catch(t){e.logger&&console.warn(`[proxy] Failed to watch config file:`,t)}return{baseUrl:`http://${l}:${u}`,providers:o.providers.map(e=>e.name),models:o.providers.flatMap(e=>e.models.map(t=>`${e.name},${t}`)),server:h,shutdown:async()=>{_?.close(),await h.stop()}}}async function v(t,n,r,a,c){let u={requestId:h(),startTime:Date.now(),retryCount:0},d=n;n.startsWith(`/claude/`)?d=n.replace(`/claude`,``):n.startsWith(`/openai/`)&&(d=n.replace(`/openai`,``)),d.startsWith(`/v1/v1/`)&&(d=d.replace(`/v1/v1/`,`/v1/`));let p;if(t.headers.get(`content-type`)?.includes(`application/json`))try{p=await t.json()}catch{return Response.json({error:{message:`Invalid JSON body`,type:`invalid_request`}},{status:400,headers:E()})}let m=r(),_=o(p),v=l(p),x=p,O=!1,k=`openai`,A=b(p),j=S(A,m.modelMapping,m.defaultModel,m.providers);if(_&&p&&typeof p==`object`){let e=p;e.model=j||A,O=e.stream===!0,k=`anthropic`,x=f(e),(d===`/v1/messages`||d===`/messages`)&&(d=`/v1/chat/completions`),c&&console.log(`[${u.requestId}] Converting Anthropic -> OpenAI format (path: ${d})`)}else if(v&&p&&typeof p==`object`){let e=p;if(e.model=j||A,O=e.stream===!0,(m.passthroughResponsesAPI??[]).some(t=>t.endsWith(`*`)?String(e.model).startsWith(t.slice(0,-1)):e.model===t))k=`openai`,x=e,c&&console.log(`[${u.requestId}] Responses API passthrough (native support): model=${g(e.model)}`);else{if(k=`responses`,c){let t=g(e.model);if(console.log(`[${u.requestId}] Responses API request: stream=${O}, model=${t}`),e.tools){let t=e.tools;console.log(`[${u.requestId}] Tools count: ${t.length}`),t.slice(0,5).forEach((e,t)=>{let n=e,r=g(n.type),i=g(n.function?.name??n.name??`N/A`);console.log(`[${u.requestId}] Tool[${t}]: type=${r}, name=${i}, keys=${Object.keys(n).join(`,`)}`)})}else console.log(`[${u.requestId}] No tools in request`)}if(x=s(e),(d===`/v1/responses`||d===`/responses`)&&(d=`/v1/chat/completions`),c){console.log(`[${u.requestId}] Converting Responses API -> OpenAI format (path: ${d})`);let e=x?.tools;e?console.log(`[${u.requestId}] Converted tools count: ${e.length}`):console.log(`[${u.requestId}] No tools after conversion`)}}}else p&&typeof p==`object`&&j&&j!==A&&(p.model=j,x=p,O=p.stream===!0);let M=j,N=m.keyRotation?.enabled===!1?1:m.providers.length*2,P=null;for(;u.retryCount<N;){if(u.retryCount>0){let e=r(),t=S(A,e.modelMapping,e.defaultModel,e.providers);t!==j&&(j=t,M=t,x&&typeof x==`object`&&(x.model=t)),m=e}let n=T(m.providers,a,M);if(!n)return Response.json({error:{message:`No available providers`,type:`service_unavailable`}},{status:503,headers:E()});u.provider=n.name;let o=e(n),s=a.getProviderState(n.name),l=s?a.selectKey({...n,apiKeys:o},s):o[0];if(!l){u.retryCount++;continue}let f=o.indexOf(l);u.keyIndex=f,c&&(j&&j!==A&&console.log(`[${u.requestId}] Model mapped: ${A??`unknown`} -> ${j} (provider: ${n.name})`),console.log(`[${u.requestId}] -> ${n.name} (key ${f+1}/${o.length})`));try{let e=await y(t,n,l,d,x);if(e.ok){if(a.reportSuccess(n.name,f),c){let t=Date.now()-u.startTime;console.log(`[${u.requestId}] <- ${e.status} (${t}ms)`)}return k===`anthropic`?await C(e,A||`unknown`,O,c,u.requestId):k===`responses`?await w(e,A||`unknown`,O,c,u.requestId):D(e)}let r=await e.clone().json().catch(()=>null),o=i(e.status,r);if(a.reportError(n.name,f,o),c&&console.log(`[${u.requestId}] Error: ${o.type} - ${o.message}`),o.retryable&&m.keyRotation?.onError!==!1){u.retryCount++,P=e;continue}return D(e)}catch(e){let t=i(0,void 0,e);if(a.reportError(n.name,f,t),c&&console.log(`[${u.requestId}] Network error: ${t.message}`),t.retryable){u.retryCount++;continue}return Response.json({error:{message:t.message,type:t.type}},{status:502,headers:E()})}}return P?D(P):Response.json({error:{message:`All providers failed after retries`,type:`service_unavailable`}},{status:503,headers:E()})}async function y(e,t,n,r,i){let a=t.baseUrl.replace(/\/+$/,``),o=r;a.endsWith(`/v1`)&&r.startsWith(`/v1/`)&&(o=r.slice(3));let s=`${a}${o}`,c={"Content-Type":`application/json`,Authorization:`Bearer ${n}`};t.headers&&Object.assign(c,t.headers);for(let t of[`accept`,`accept-encoding`,`x-request-id`]){let n=e.headers.get(t);n&&(c[t]=n)}let l={method:e.method,headers:c};if(i&&e.method!==`GET`&&e.method!==`HEAD`&&(l.body=JSON.stringify(i)),t.timeout){let e=new AbortController,n=setTimeout(()=>e.abort(),t.timeout);l.signal=e.signal;try{let e=await fetch(s,l);return clearTimeout(n),e}catch(e){throw clearTimeout(n),e}}return fetch(s,l)}function b(e){if(!e||typeof e!=`object`)return;let t=e;if(typeof t.model==`string`)return t.model}function x(e,t){return e.models.some(e=>e===t||t.startsWith(e)||e.startsWith(t))}function S(e,t,n,r){if(!e)return n;if(!t||Object.keys(t).length===0)return e;if(t[e])return t[e];for(let[n,r]of Object.entries(t))if(n!==`*`&&n.endsWith(`*`)){let t=n.slice(0,-1);if(e.startsWith(t))return r}return r?.some(t=>x(t,e))?e:t[`*`]?t[`*`]:n??e}async function C(e,t,n,r,i){if(n){r&&console.log(`[${i}] Converting streaming response OpenAI -> Anthropic`);let n=u(t),a=e.body?.pipeThrough(n);return new Response(a,{status:200,headers:{...E(),"Content-Type":`text/event-stream`,"Cache-Control":`no-cache, no-transform`,Connection:`keep-alive`,"X-Accel-Buffering":`no`}})}try{let n=await e.text(),a;try{a=JSON.parse(n)}catch{r&&console.log(`[${i}] Response is not JSON, wrapping as text`),a={content:n}}r&&console.log(`[${i}] Response type: ${typeof a}, keys: ${Object.keys(a).join(`, `)}`);let o=d(a,t);return r&&console.log(`[${i}] Converted response OpenAI -> Anthropic`),Response.json(o,{status:200,headers:E()})}catch(e){return console.error(`[${i}] Response conversion failed:`,e),Response.json({type:`error`,error:{type:`api_error`,message:`Response conversion failed: ${e.message}`}},{status:500,headers:E()})}}async function w(e,t,n,r,i){if(n){r&&console.log(`[${i}] Converting streaming response OpenAI -> Responses API`);let n=c(t),a=e.body?.pipeThrough(n);return new Response(a,{status:200,headers:{...E(),"Content-Type":`text/event-stream`,"Cache-Control":`no-cache, no-transform`,Connection:`keep-alive`,"X-Accel-Buffering":`no`}})}try{let n=await e.text(),o;try{o=JSON.parse(n)}catch{r&&console.log(`[${i}] Response is not JSON, wrapping as text`),o={content:n}}r&&console.log(`[${i}] Response type: ${typeof o}, keys: ${Object.keys(o).join(`, `)}`);let s=a(o,t);return r&&console.log(`[${i}] Converted response OpenAI -> Responses API`),Response.json(s,{status:200,headers:E()})}catch(e){return console.error(`[${i}] Response conversion failed:`,e),Response.json({id:`resp_${Date.now()}`,object:`response`,created_at:Math.floor(Date.now()/1e3),model:t,output:[],status:`failed`,error:{code:`api_error`,message:`Response conversion failed: ${e.message}`}},{status:500,headers:E()})}}function T(t,n,r){let i=t.map(t=>({...t,apiKeys:e(t)}));if(r?.includes(`,`)){let[e]=r.split(`,`),t=i.find(t=>t.name===e);if(t)return t}if(r){let e=i.filter(e=>x(e,r));if(e.length>0)return n.selectProvider(e)}return n.selectProvider(i)}function E(){return{"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`GET, POST, PUT, DELETE, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type, Authorization, X-Request-ID, X-API-Key`,"Access-Control-Max-Age":`86400`}}function D(e){let t=new Headers(e.headers);for(let[e,n]of Object.entries(E()))t.set(e,n);return new Response(e.body,{status:e.status,statusText:e.statusText,headers:t})}function O(e){let t=Math.floor(Date.now()/1e3),n=[],r=new Set;for(let i of e)for(let e of i.models){let a=`${i.name},${e}`;r.has(a)||(r.add(a),n.push({id:a,object:`model`,created:t,owned_by:i.name})),r.has(e)||(r.add(e),n.push({id:e,object:`model`,created:t,owned_by:i.name}))}return{object:`list`,data:n}}export{_ as a,T as i,S as n,x as r,m as t};
@@ -1 +1 @@
1
- import"../../errors-BzZfdKtJ.js";import"../../editor-6Nht_jnv.js";import"../../config-Bf-EeKY5.js";import"../../fsStore-CwAffYMN.js";import"../../base-BUo37ebo.js";import"../../template-zeZsnoLb.js";import"../../xling-CMIOhJ6S.js";import{t as e}from"../../loadBalancer-BUZZKUIh.js";import{i as t,r as n,t as r}from"../../errorClassifier-B-lYIh-6.js";import"../../transformer-DTxdVklF.js";import{a as i,t as a}from"../../server-Dag3i5Zg.js";export{a as DEFAULT_PROXY_PORT,e as ProxyLoadBalancer,r as classifyError,n as isRetryable,t as shouldRotateKey,i as startProxyServer};
1
+ import"../../errors-BzZfdKtJ.js";import"../../editor-6Nht_jnv.js";import"../../config-Bf-EeKY5.js";import"../../fsStore-CwAffYMN.js";import"../../base-BUo37ebo.js";import"../../template-zeZsnoLb.js";import"../../xling-CMIOhJ6S.js";import{t as e}from"../../loadBalancer-BUZZKUIh.js";import{i as t,r as n,t as r}from"../../errorClassifier-B-lYIh-6.js";import"../../transformer-DTxdVklF.js";import{a as i,t as a}from"../../server-CAH57wTY.js";export{a as DEFAULT_PROXY_PORT,e as ProxyLoadBalancer,r as classifyError,n as isRetryable,t as shouldRotateKey,i as startProxyServer};
@@ -1 +1 @@
1
- import"../../errors-BzZfdKtJ.js";import"../../editor-6Nht_jnv.js";import"../../config-Bf-EeKY5.js";import"../../fsStore-CwAffYMN.js";import"../../base-BUo37ebo.js";import"../../template-zeZsnoLb.js";import"../../xling-CMIOhJ6S.js";import"../../loadBalancer-BUZZKUIh.js";import"../../errorClassifier-B-lYIh-6.js";import"../../transformer-DTxdVklF.js";import{a as e,i as t,n,r,t as i}from"../../server-Dag3i5Zg.js";export{i as DEFAULT_PROXY_PORT,n as mapModel,r as providerSupportsModel,t as selectProviderForModel,e as startProxyServer};
1
+ import"../../errors-BzZfdKtJ.js";import"../../editor-6Nht_jnv.js";import"../../config-Bf-EeKY5.js";import"../../fsStore-CwAffYMN.js";import"../../base-BUo37ebo.js";import"../../template-zeZsnoLb.js";import"../../xling-CMIOhJ6S.js";import"../../loadBalancer-BUZZKUIh.js";import"../../errorClassifier-B-lYIh-6.js";import"../../transformer-DTxdVklF.js";import{a as e,i as t,n,r,t as i}from"../../server-CAH57wTY.js";export{i as DEFAULT_PROXY_PORT,n as mapModel,r as providerSupportsModel,t as selectProviderForModel,e as startProxyServer};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xling",
3
- "version": "0.9.7",
3
+ "version": "0.9.8",
4
4
  "description": "Unified CLI for AI tools: settings management, API proxy with load balancing, multi-model discussions",
5
5
  "homepage": "https://github.com/kingsword09/xling/tree/main#readme",
6
6
  "bugs": {
@@ -1 +0,0 @@
1
- import{p as e}from"./config-Bf-EeKY5.js";import{m as t}from"./fsStore-CwAffYMN.js";import{t as n}from"./xling-CMIOhJ6S.js";import{t as r}from"./loadBalancer-BUZZKUIh.js";import{t as i}from"./errorClassifier-B-lYIh-6.js";import{c as a,i as o,l as s,n as c,o as l,r as u,s as d,t as f}from"./transformer-DTxdVklF.js";import{watch as p}from"node:fs";const m=4320;function h(){return`req_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,8)}`}function g(e){if(typeof e==`string`)return e;if(typeof e==`number`||typeof e==`boolean`)return String(e);if(e==null)return``;if(typeof e==`object`)try{return JSON.stringify(e)}catch{return`[object Object]`}return typeof e==`symbol`?e.toString():typeof e==`function`?e.name||`[function]`:``}async function _(e={}){let i=new n,a=i.resolvePath(`user`),o=i.readConfig(a);if(!o.providers?.length)throw Error(`No providers configured in ~/.claude/xling.json. Add a 'providers' array.`);let s=()=>o,c=o.proxy??{},l=e.host??c.host??`127.0.0.1`,u=e.port??c.port??m,d=e.accessKey??c.accessKey,f=new r(c.loadBalance??`failover`,c.keyRotation?.cooldownMs??6e4),h=Bun.serve({hostname:l,port:u,async fetch(t){let n=new URL(t.url).pathname;if(t.method===`OPTIONS`)return new Response(null,{status:204,headers:E()});if(n===`/health`||n===`/`){let e=s();return Response.json({status:`ok`,providers:e.providers.map(e=>e.name),loadBalance:e.proxy?.loadBalance??`failover`},{headers:E()})}if(n===`/stats`)return Response.json({stats:f.getStats()},{headers:E()});if(n===`/v1/models`||n===`/models`){let e=O(s().providers);return Response.json(e,{headers:E()})}if(d){let r=t.headers.get(`authorization`)?.replace(/^Bearer\s+/i,``);if(r!==d)return e.logger&&(console.log(`[auth] Access key validation failed for path: ${n}`),console.log(`[auth] Expected: ${d.slice(0,4)}...`),console.log(`[auth] Received: ${r?r.slice(0,4)+`...`:`(none)`}`)),Response.json({error:{message:`Invalid access key`,type:`auth_error`}},{status:401,headers:E()})}return n.startsWith(`/v1/`)||n.startsWith(`/claude/`)||n.startsWith(`/openai/`)||n===`/responses`||n===`/messages`||n===`/chat/completions`?(e.logger&&console.log(`[proxy] Handling request: ${t.method} ${n}`),v(t,n,()=>{let e=s();return{providers:e.providers,modelMapping:e.proxy?.modelMapping,defaultModel:e.defaultModel,passthroughResponsesAPI:e.proxy?.passthroughResponsesAPI,keyRotation:e.proxy?.keyRotation}},f,e.logger??!0)):(e.logger&&console.log(`[proxy] 404 Not Found: ${t.method} ${n}`),Response.json({error:{message:`Not found`,type:`not_found`}},{status:404,headers:E()}))}}),g=t(a),_=null;try{_=p(g,t=>{if(t===`change`)try{let t=i.readConfig(a);t.providers?.length&&(o=t,e.logger&&console.log(`[proxy] Config reloaded`))}catch(t){e.logger&&console.error(`[proxy] Failed to reload config:`,t)}})}catch(t){e.logger&&console.warn(`[proxy] Failed to watch config file:`,t)}return{baseUrl:`http://${l}:${u}`,providers:o.providers.map(e=>e.name),models:o.providers.flatMap(e=>e.models.map(t=>`${e.name},${t}`)),server:h,shutdown:async()=>{_?.close(),await h.stop()}}}async function v(t,n,r,a,c){let u={requestId:h(),startTime:Date.now(),retryCount:0},d=n;n.startsWith(`/claude/`)?d=n.replace(`/claude`,``):n.startsWith(`/openai/`)&&(d=n.replace(`/openai`,``)),d.startsWith(`/v1/v1/`)&&(d=d.replace(`/v1/v1/`,`/v1/`));let p;if(t.headers.get(`content-type`)?.includes(`application/json`))try{p=await t.json()}catch{return Response.json({error:{message:`Invalid JSON body`,type:`invalid_request`}},{status:400,headers:E()})}let m=r(),_=o(p),v=l(p),x=p,O=!1,k=`openai`,A=b(p),j=S(A,m.modelMapping,m.defaultModel,m.providers);if(_&&p&&typeof p==`object`){let e=p;e.model=j||A,O=e.stream===!0,k=`anthropic`,x=f(e),(d===`/v1/messages`||d===`/messages`)&&(d=`/v1/chat/completions`),c&&console.log(`[${u.requestId}] Converting Anthropic -> OpenAI format (path: ${d})`)}else if(v&&p&&typeof p==`object`){let e=p;if(e.model=j||A,O=e.stream===!0,(m.passthroughResponsesAPI??[]).some(t=>t.endsWith(`*`)?String(e.model).startsWith(t.slice(0,-1)):e.model===t))k=`openai`,x=e,c&&console.log(`[${u.requestId}] Responses API passthrough (native support): model=${g(e.model)}`);else{if(k=`responses`,c){let t=g(e.model);if(console.log(`[${u.requestId}] Responses API request: stream=${O}, model=${t}`),e.tools){let t=e.tools;console.log(`[${u.requestId}] Tools count: ${t.length}`),t.slice(0,5).forEach((e,t)=>{let n=e,r=g(n.type),i=g(n.function?.name??n.name??`N/A`);console.log(`[${u.requestId}] Tool[${t}]: type=${r}, name=${i}, keys=${Object.keys(n).join(`,`)}`)})}else console.log(`[${u.requestId}] No tools in request`)}if(x=s(e),(d===`/v1/responses`||d===`/responses`)&&(d=`/v1/chat/completions`),c){console.log(`[${u.requestId}] Converting Responses API -> OpenAI format (path: ${d})`);let e=x?.tools;e?console.log(`[${u.requestId}] Converted tools count: ${e.length}`):console.log(`[${u.requestId}] No tools after conversion`)}}}else p&&typeof p==`object`&&j&&j!==A&&(p.model=j,x=p,O=p.stream===!0);let M=j,N=m.keyRotation?.enabled===!1?1:m.providers.length*2,P=null;for(;u.retryCount<N;){if(u.retryCount>0){let e=r(),t=S(A,e.modelMapping,e.defaultModel,e.providers);t!==j&&(j=t,M=t,x&&typeof x==`object`&&(x.model=t)),m=e}let n=T(m.providers,a,M);if(!n)return Response.json({error:{message:`No available providers`,type:`service_unavailable`}},{status:503,headers:E()});u.provider=n.name;let o=e(n),s=a.getProviderState(n.name),l=s?a.selectKey({...n,apiKeys:o},s):o[0];if(!l){u.retryCount++;continue}let f=o.indexOf(l);u.keyIndex=f,c&&(j&&j!==A&&console.log(`[${u.requestId}] Model mapped: ${A??`unknown`} -> ${j} (provider: ${n.name})`),console.log(`[${u.requestId}] -> ${n.name} (key ${f+1}/${o.length})`));try{let e=await y(t,n,l,d,x);if(e.ok){if(a.reportSuccess(n.name,f),c){let t=Date.now()-u.startTime;console.log(`[${u.requestId}] <- ${e.status} (${t}ms)`)}return k===`anthropic`?await C(e,A||`unknown`,O,c,u.requestId):k===`responses`?await w(e,A||`unknown`,O,c,u.requestId):D(e)}let r=await e.clone().json().catch(()=>null),o=i(e.status,r);if(a.reportError(n.name,f,o),c&&console.log(`[${u.requestId}] Error: ${o.type} - ${o.message}`),o.retryable&&m.keyRotation?.onError!==!1){u.retryCount++,P=e;continue}return D(e)}catch(e){let t=i(0,void 0,e);if(a.reportError(n.name,f,t),c&&console.log(`[${u.requestId}] Network error: ${t.message}`),t.retryable){u.retryCount++;continue}return Response.json({error:{message:t.message,type:t.type}},{status:502,headers:E()})}}return P?D(P):Response.json({error:{message:`All providers failed after retries`,type:`service_unavailable`}},{status:503,headers:E()})}async function y(e,t,n,r,i){let a=t.baseUrl.replace(/\/+$/,``),o=r;a.endsWith(`/v1`)&&r.startsWith(`/v1/`)&&(o=r.slice(3));let s=`${a}${o}`,c={"Content-Type":`application/json`,Authorization:`Bearer ${n}`};t.headers&&Object.assign(c,t.headers);for(let t of[`accept`,`accept-encoding`,`x-request-id`]){let n=e.headers.get(t);n&&(c[t]=n)}let l={method:e.method,headers:c};if(i&&e.method!==`GET`&&e.method!==`HEAD`&&(l.body=JSON.stringify(i)),t.timeout){let e=new AbortController,n=setTimeout(()=>e.abort(),t.timeout);l.signal=e.signal;try{let e=await fetch(s,l);return clearTimeout(n),e}catch(e){throw clearTimeout(n),e}}return fetch(s,l)}function b(e){if(!e||typeof e!=`object`)return;let t=e;if(typeof t.model==`string`)return t.model}function x(e,t){return e.models.some(e=>e===t||t.startsWith(e)||e.startsWith(t))}function S(e,t,n,r){if(!e)return n;if(!t||Object.keys(t).length===0)return e;if(t[e])return t[e];for(let[n,r]of Object.entries(t))if(n!==`*`&&n.endsWith(`*`)){let t=n.slice(0,-1);if(e.startsWith(t))return r}return r?.some(t=>x(t,e))?e:t[`*`]?t[`*`]:n??e}async function C(e,t,n,r,i){if(n){r&&console.log(`[${i}] Converting streaming response OpenAI -> Anthropic`);let n=u(t),a=e.body?.pipeThrough(n);return new Response(a,{status:200,headers:{...E(),"Content-Type":`text/event-stream`,"Cache-Control":`no-cache, no-transform`,Connection:`keep-alive`,"X-Accel-Buffering":`no`}})}try{let n=await e.text(),a;try{a=JSON.parse(n)}catch{r&&console.log(`[${i}] Response is not JSON, wrapping as text`),a={content:n}}r&&console.log(`[${i}] Response type: ${typeof a}, keys: ${Object.keys(a).join(`, `)}`);let o=d(a,t);return r&&console.log(`[${i}] Converted response OpenAI -> Anthropic`),Response.json(o,{status:200,headers:E()})}catch(e){return console.error(`[${i}] Response conversion failed:`,e),Response.json({type:`error`,error:{type:`api_error`,message:`Response conversion failed: ${e.message}`}},{status:500,headers:E()})}}async function w(e,t,n,r,i){if(n){r&&console.log(`[${i}] Converting streaming response OpenAI -> Responses API`);let n=c(t),a=e.body?.pipeThrough(n);return new Response(a,{status:200,headers:{...E(),"Content-Type":`text/event-stream`,"Cache-Control":`no-cache, no-transform`,Connection:`keep-alive`,"X-Accel-Buffering":`no`}})}try{let n=await e.text(),o;try{o=JSON.parse(n)}catch{r&&console.log(`[${i}] Response is not JSON, wrapping as text`),o={content:n}}r&&console.log(`[${i}] Response type: ${typeof o}, keys: ${Object.keys(o).join(`, `)}`);let s=a(o,t);return r&&console.log(`[${i}] Converted response OpenAI -> Responses API`),Response.json(s,{status:200,headers:E()})}catch(e){return console.error(`[${i}] Response conversion failed:`,e),Response.json({id:`resp_${Date.now()}`,object:`response`,created_at:Math.floor(Date.now()/1e3),model:t,output:[],status:`failed`,error:{code:`api_error`,message:`Response conversion failed: ${e.message}`}},{status:500,headers:E()})}}function T(t,n,r){let i=t.map(t=>({...t,apiKeys:e(t)}));if(r?.includes(`,`)){let[e]=r.split(`,`),t=i.find(t=>t.name===e);if(t)return t}if(r){let e=i.filter(e=>x(e,r));if(e.length>0)return n.selectProvider(e)}return n.selectProvider(i)}function E(){return{"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`GET, POST, PUT, DELETE, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type, Authorization, X-Request-ID`,"Access-Control-Max-Age":`86400`}}function D(e){let t=new Headers(e.headers);for(let[e,n]of Object.entries(E()))t.set(e,n);return new Response(e.body,{status:e.status,statusText:e.statusText,headers:t})}function O(e){let t=Math.floor(Date.now()/1e3),n=[],r=new Set;for(let i of e)for(let e of i.models){let a=`${i.name},${e}`;r.has(a)||(r.add(a),n.push({id:a,object:`model`,created:t,owned_by:i.name})),r.has(e)||(r.add(e),n.push({id:e,object:`model`,created:t,owned_by:i.name}))}return{object:`list`,data:n}}export{_ as a,T as i,S as n,x as r,m as t};