@urun-sh/openai 0.2.53 → 0.2.55
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/ResponsesClient-DrccxHTc.d.cts +108 -0
- package/dist/{ResponsesClient-CQ3l8Wft.d.ts → ResponsesClient-DrccxHTc.d.ts} +18 -2
- package/dist/chunk-47ZLHRBM.js +27 -0
- package/dist/{chunk-PS4BLX7J.js → chunk-5CEMLB6H.js} +1 -1
- package/dist/chunk-HQVV5UN5.js +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/pi-extension/index.cjs +3 -2
- package/dist/pi-extension/index.d.cts +74 -28
- package/dist/pi-extension/index.d.ts +30 -6
- package/dist/pi-extension/index.js +3 -2
- package/dist/pi-extension/standalone.cjs +48 -47
- package/dist/proxy/cli.cjs +33 -22
- package/dist/proxy/cli.js +17 -12
- package/dist/proxy/index.cjs +18 -12
- package/dist/proxy/index.d.cts +1 -0
- package/dist/proxy/index.d.ts +1 -0
- package/dist/proxy/index.js +1 -1
- package/package.json +1 -1
- package/dist/ResponsesClient-CQ3l8Wft.d.cts +0 -62
- package/dist/chunk-FSS2A7IU.js +0 -1
- package/dist/chunk-KJ25VEMG.js +0 -21
package/dist/proxy/cli.cjs
CHANGED
|
@@ -1,33 +1,44 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
"use strict";var Xe=Object.create;var M=Object.defineProperty;var Ve=Object.getOwnPropertyDescriptor;var Qe=Object.getOwnPropertyNames;var Ze=Object.getPrototypeOf,et=Object.prototype.hasOwnProperty;var tt=(e,n)=>{for(var t in n)M(e,t,{get:n[t],enumerable:!0})},ce=(e,n,t,r)=>{if(n&&typeof n=="object"||typeof n=="function")for(let o of Qe(n))!et.call(e,o)&&o!==t&&M(e,o,{get:()=>n[o],enumerable:!(r=Ve(n,o))||r.enumerable});return e};var D=(e,n,t)=>(t=e!=null?Xe(Ze(e)):{},ce(n||!e||!e.__esModule?M(t,"default",{value:e,enumerable:!0}):t,e)),nt=e=>ce(M({},"__esModule",{value:!0}),e);var Ot={};tt(Ot,{buildClients:()=>Fe,buildRouter:()=>Ye});module.exports=nt(Ot);var rt=()=>typeof document>"u"?new URL(`file:${__filename}`).href:document.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"?document.currentScript.src:new URL("main.js",document.baseURI).href,v=rt();var pe=require("child_process"),I=require("fs"),Ge=D(require("path"),1),m=D(require("process"),1),T=require("@urun-sh/core");function le(e,n,t,r){let o=e.response??{},s={request_id:t,consumer_id:r,stream:!0,kind:"chat",messages:n};return typeof o.instructions=="string"&&(s.instructions=o.instructions),Array.isArray(o.modalities)&&(s.modalities=o.modalities),typeof o.temperature=="number"&&(s.temperature=o.temperature),typeof o.max_output_tokens=="number"&&(s.max_output_tokens=o.max_output_tokens),o.tools!==void 0&&(s.tools=o.tools),s}function de(e,n,t){let r={request_id:n,consumer_id:t,stream:!!e.stream,kind:"responses",input:e.input};return e.model&&(r.model=e.model),e.tools!==void 0&&(r.tools=e.tools),typeof e.temperature=="number"&&(r.temperature=e.temperature),typeof e.max_output_tokens=="number"&&(r.max_output_tokens=e.max_output_tokens),r}function me(e){if(e instanceof Error)return{type:"error",error:{type:"urun_error",code:e.name||null,message:e.message}};if(e&&typeof e=="object"&&e.t==="error"){let n=e,t=n.body??{};return{type:"error",error:{type:"urun_error",code:n.code??null,message:t.message??"unknown error"}}}return{type:"error",error:{type:"urun_error",code:null,message:String(e)}}}var ot="llm-resp";async function*z(e,n){let t=`${ot}:${n}`,r=`resp_${n}`;yield{type:"response.created",response:{id:r,status:"in_progress"}};for await(let o of e.stream(t).messages()){let s=o;if(s.t==="delta")yield{type:"response.output_text.delta",item_id:r,delta:s.delta};else if(s.t==="response"){yield{type:"response.completed",response:{id:r,status:"completed",...s.body}};return}else if(s.t==="error"){yield me(s);return}}}var st="llm",B=class{constructor(n){this.session=n}session;get consumerId(){return this.session.consumerId}write(n){this.session.doc(st).set({requests:{[n.request_id]:{payload:n,consumer_id:n.consumer_id,stream:n.stream}}})}sendResponses(n,t){let r=de(n,t,this.consumerId);return this.write(r),z(this.session,t)}sendResponseCreate(n,t,r){let o=le(n,t,r,this.consumerId);return this.write(o),z(this.session,r)}};var fe=0;function it(){return fe+=1,`req_${Date.now().toString(36)}_${fe.toString(36)}`}var N=class{transport;constructor(n){this.transport=new B(n)}responses={create:async n=>{let t=it(),r=this.transport.sendResponses(n,t);return Object.assign((async function*(){yield*r})(),{requestId:t})}}};async function ye(e){let t=await(e.fetchImpl??fetch)(`${e.catalogUrl}/model_catalog?select=model_id,variant`,{headers:{apikey:e.anonKey,Authorization:`Bearer ${e.anonKey}`}});if(!t.ok)throw new Error(`model_catalog fetch failed: ${t.status}`);return await t.json()}var ke=require("http");var ge="https://api.urun.sh/v1";function H(e){return e.toLowerCase().replace(/[^\p{L}\p{N}-]/gu,"-").replace(/^-+|-+$/g,"")}var k=class extends Error{};async function he(e){let n=e.fetchImpl??fetch,t=`${e.apiUrl.replace(/\/+$/,"")}/apps`,r=await n(t,{headers:{Authorization:`Bearer ${e.apiKey}`,Accept:"application/json"}});if(!r.ok)throw new Error(`org apps listing failed: GET ${t} \u2192 ${r.status}`);let o=await r.json();if(!Array.isArray(o.apps))throw new Error(`org apps listing returned no "apps" array (GET ${t})`);if(o.truncated===!0)throw new Error(`org apps listing was truncated (GET ${t} returned ${o.apps.length} of more) \u2014 model discovery would silently omit deployed apps`);return o.apps}var at=6e4,J=class{constructor(n){this.opts=n}opts;pool=new Map;appsCache=null;seed(n,t){this.pool.set(n,Promise.resolve(t))}async deployedApps(){if(!this.opts.listApps)return[];let n=this.opts.appsTtlMs??at;if(this.appsCache&&Date.now()-this.appsCache.at<n)return this.appsCache.apps;let t=await this.opts.listApps();return this.appsCache={at:Date.now(),apps:t},t}servable(n){return n.filter(t=>t.function_name===this.opts.fnName&&t.deployment_status==="active").map(t=>t.app_slug)}async availableIds(){let n=new Set([this.opts.defaultApp]);if(this.opts.listApps)for(let t of this.servable(await this.deployedApps()))n.add(t);for(let t of this.pool.keys())n.add(t);return[this.opts.defaultApp,...[...n].filter(t=>t!==this.opts.defaultApp).sort()]}async resolveApp(n){let t=(n??"").trim();if(!t||t==="urun")return this.opts.defaultApp;let r=H(t);if(r===this.opts.defaultApp)return this.opts.defaultApp;if(this.pool.has(r))return r;if(this.opts.listApps){let o=await this.deployedApps(),s=this.servable(o);if(s.includes(r))return r;let a=s.filter(u=>u.startsWith(`${r}-`));if(a.length===1)return a[0];if(a.length>1)throw new k(`model "${t}" is ambiguous across deployed apps ${a.join(", ")} \u2014 name the exact app slug (or catalog id:variant)`);let i=o.find(u=>u.app_slug===r||u.app_slug.startsWith(`${r}-`));if(i)throw new k(`model "${t}" maps to app "${i.app_slug}", which is not an active "${this.opts.fnName}" app \u2014 deploy it with \`urun serve ${t}\`; available models: ${(await this.availableIds()).join(", ")}`)}if(this.opts.listCatalog){let s=(await this.opts.listCatalog()).find(a=>t===a.model_id||t===`${a.model_id}:${a.variant}`||r===H(a.model_id)||r===H(`${a.model_id}-${a.variant}`));if(s)throw new k(`model "${t}" is in the uRun catalog but not deployed \u2014 deploy it with \`urun serve ${s.model_id}\`; available models: ${(await this.availableIds()).join(", ")}`)}return this.opts.defaultApp}async sessionFor(n){let t=await this.resolveApp(n),r=this.pool.get(t);return r||(r=Promise.resolve(this.opts.openSession(t)),this.pool.set(t,r),r.catch(()=>this.pool.delete(t))),{app:t,entry:await r}}async modelList(){return{object:"list",data:(await this.availableIds()).map(t=>({id:t,object:"model",created:0,owned_by:"urun"}))}}async closeAll(){let n=[...this.pool.values()];this.pool.clear();let t=[];if(await Promise.all(n.map(async r=>{try{await this.opts.closeSession(await r)}catch(o){t.push(String(o instanceof Error?o.message:o))}})),t.length>0)throw new Error(`failed to close ${t.length} pooled session(s): ${t.join("; ")}`)}};var X=class e{startedAt=Date.now();requests={};models={};ttftMs=[];tokRates=[];tokensOut=0;charsOut=0;localInBytes=0;naiveInBytes=0;request(n,t,r){this.requests[n]=(this.requests[n]??0)+1,this.localInBytes+=t,this.naiveInBytes+=r}modelEntry(n){let t=this.models[n];if(t)return t;let r=Object.keys(this.models).length>=pt?"(other)":n;return this.models[r]??={requests:0,tokens_out:0}}model(n){this.modelEntry(n).requests+=1}track(n,t){let r=this,o=performance.now(),s=null,a=0;return(async function*(){for await(let u of n)u.type==="response.output_text.delta"&&typeof u.delta=="string"&&(s===null&&(s=performance.now(),r.ttftMs.push(s-o),r.ttftMs.length>512&&r.ttftMs.shift()),a+=1,r.tokensOut+=1,r.charsOut+=u.delta.length,t!==void 0&&(r.modelEntry(t).tokens_out+=1)),yield u;let i=(performance.now()-(s??o))/1e3;a>0&&i>0&&(r.tokRates.push(a/i),r.tokRates.length>512&&r.tokRates.shift())})()}static p50(n){if(!n.length)return null;let t=[...n].sort((r,o)=>r-o);return t[Math.floor(t.length/2)]}snapshot(){let n=Object.values(this.requests).reduce((t,r)=>t+r,0);return{uptime_s:Math.round((Date.now()-this.startedAt)/1e3),requests:this.requests,models:this.models,tokens_out:this.tokensOut,chars_out:this.charsOut,ttft_ms:{p50:e.p50(this.ttftMs),last:this.ttftMs.at(-1)??null},tok_per_s:{p50:e.p50(this.tokRates),last:this.tokRates.at(-1)??null},traffic:{local_request_bytes:this.localInBytes,naive_baseline:{request_bytes:this.naiveInBytes,connections:n},persistent_connections:1,history_bytes_saved:Math.max(0,this.naiveInBytes-this.localInBytes),history_bytes_saved_pct:this.naiveInBytes>0?Math.round((1-this.localInBytes/this.naiveInBytes)*1e3)/10:null}}}};function Q(e){e.writeHead(200,{"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive"})}function R(e,n,t){e.writeHead(n,{"content-type":"application/json"}),e.end(JSON.stringify(t))}function _(e,n,t,r="invalid_request_error"){R(e,n,{error:{message:t,type:r}})}function Z(e,n,t){if(n==="anthropic"){R(e,404,{type:"error",error:{type:"not_found_error",message:t.message}});return}R(e,404,{error:{message:t.message,type:"invalid_request_error",code:"model_not_found"}})}var pt=256,ut=128;function ee(e){return typeof e.model!="string"||!e.model.trim()?"(default)":e.model.trim().slice(0,ut)}var _e=64*1024*1024,q=class extends Error{};async function ct(e){let n=[],t=0;for await(let o of e){if(t+=o.length,t>_e)throw new q(`request body exceeds ${_e} bytes`);n.push(o)}let r=Buffer.concat(n).toString("utf8");return r?JSON.parse(r):{}}function K(e,n,t,r){return{id:e,object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:n,choices:[{index:0,delta:t,finish_reason:r}]}}var lt=256;function dt(e){if(typeof e=="string")return[{role:"user",content:e}];if(Array.isArray(e))return e;throw new Error("responses input must be a string or an array of messages/items")}var V=class{conversations=new Map;thread(n,t){let r=dt(t);if(n==null)return r;let o=this.conversations.get(String(n));if(!o)throw new Error(`unknown previous_response_id ${String(n)} (proxy restarts drop stored responses)`);return[...o,...r]}remember(n,t,r){this.conversations.set(n,[...t,{role:"assistant",content:r}]);for(let o of this.conversations.keys()){if(this.conversations.size<=lt)break;this.conversations.delete(o)}}};function te(e){let n=e?.output;return Array.isArray(n)?n.filter(t=>t.type==="function_call"):[]}function L(e){return e.find(n=>n.type==="response.completed")?.response??null}function mt(e){if(Array.isArray(e))return e.map(n=>{let t=n.function;return!t||typeof t!="object"?n:{type:"function",name:t.name,description:t.description,parameters:t.parameters,strict:t.strict}})}var G=class extends Error{};function ft(e,n){return Array.isArray(n)?n.map(t=>{let r=t;if(r.type==="text")return{type:e==="assistant"?"output_text":"input_text",text:r.text};if(r.type==="image_url"){let o=r.image_url??{};return{type:"input_image",image_url:o.url,detail:o.detail}}throw new G(`unsupported chat content part type "${String(r.type)}" \u2014 the proxy translates text and image_url parts`)}):n}function yt(e){let n=[];for(let t of e){if(t.role==="tool"){n.push({type:"function_call_output",call_id:t.tool_call_id,output:typeof t.content=="string"?t.content:JSON.stringify(t.content??"")});continue}if(t.role==="assistant"&&Array.isArray(t.tool_calls)){typeof t.content=="string"&&t.content&&n.push({role:"assistant",content:t.content});for(let r of t.tool_calls){let o=r.function??{};n.push({type:"function_call",call_id:r.id,name:o.name,arguments:o.arguments})}continue}n.push({...t,content:ft(t.role,t.content)})}return n}function we(e){return te(e).map((n,t)=>({index:t,id:n.call_id??n.id??`call_${t}`,type:"function",function:{name:n.name??"",arguments:n.arguments??"{}"}}))}function xe(e,n){let t=n?.output_text;return typeof t=="string"?t:e.filter(r=>r.type==="response.output_text.delta"&&typeof r.delta=="string").map(r=>r.delta).join("")}async function gt(e,n,t,r,o){let s=e.stream===!0,a;try{a=t.thread(e.previous_response_id,e.input)}catch(p){_(r,400,String(p instanceof Error?p.message:p));return}e.previous_response_id!=null&&(o.naiveInBytes+=Buffer.byteLength(JSON.stringify(a))-Buffer.byteLength(JSON.stringify(e.input)));let i=`resp_${Math.random().toString(36).slice(2,14)}`,u=e.store!==!1,d=ee(e);o.model(d);let l;try{l=await n.createResponse({model:e.model,input:a,stream:s,tools:e.tools,temperature:e.temperature,max_output_tokens:e.max_output_tokens})}catch(p){if(p instanceof k){Z(r,"openai",p);return}throw p}let f=[];if(s){Q(r);let p=g=>{r.write(`event: ${String(g.type??"message")}
|
|
2
|
+
"use strict";var Et=Object.create;var ue=Object.defineProperty;var Rt=Object.getOwnPropertyDescriptor;var bt=Object.getOwnPropertyNames;var At=Object.getPrototypeOf,It=Object.prototype.hasOwnProperty;var Pt=(e,n)=>{for(var t in n)ue(e,t,{get:n[t],enumerable:!0})},Le=(e,n,t,r)=>{if(n&&typeof n=="object"||typeof n=="function")for(let o of bt(n))!It.call(e,o)&&o!==t&&ue(e,o,{get:()=>n[o],enumerable:!(r=Rt(n,o))||r.enumerable});return e};var le=(e,n,t)=>(t=e!=null?Et(At(e)):{},Le(n||!e||!e.__esModule?ue(t,"default",{value:e,enumerable:!0}):t,e)),Ot=e=>Le(ue({},"__esModule",{value:!0}),e);var mn={};Pt(mn,{buildClients:()=>vt,buildRouter:()=>kt});module.exports=Ot(mn);var $t=()=>typeof document>"u"?new URL(`file:${__filename}`).href:document.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"?document.currentScript.src:new URL("main.js",document.baseURI).href,N=$t();var Te=require("child_process"),J=require("fs"),xt=le(require("path"),1),y=le(require("process"),1),ie=require("@urun-sh/core");function Me(e,n,t,r){let o=e.response??{},i={request_id:t,consumer_id:r,stream:!0,kind:"chat",messages:n};return typeof o.instructions=="string"&&(i.instructions=o.instructions),Array.isArray(o.modalities)&&(i.modalities=o.modalities),typeof o.temperature=="number"&&(i.temperature=o.temperature),typeof o.max_output_tokens=="number"&&(i.max_output_tokens=o.max_output_tokens),o.tools!==void 0&&(i.tools=o.tools),i}function je(e,n,t){let r={request_id:n,consumer_id:t,stream:!!e.stream,kind:"responses",input:e.input};return e.model&&(r.model=e.model),e.tools!==void 0&&(r.tools=e.tools),e.tool_choice!==void 0&&(r.tool_choice=e.tool_choice),typeof e.temperature=="number"&&(r.temperature=e.temperature),typeof e.max_output_tokens=="number"&&(r.max_output_tokens=e.max_output_tokens),r}function De(e){if(e instanceof Error)return{type:"error",error:{type:"urun_error",code:e.name||null,message:e.message}};if(e&&typeof e=="object"&&e.t==="error"){let n=e,t=n.body??{};return{type:"error",error:{type:"urun_error",code:n.code??null,message:t.message??"unknown error"}}}return{type:"error",error:{type:"urun_error",code:null,message:String(e)}}}var Ut="llm-resp";async function*we(e,n){let t=`${Ut}:${n}`,r=`resp_${n}`;yield{type:"response.created",response:{id:r,status:"in_progress"}};let o=new Map;for await(let i of e.stream(t).messages()){let s=i;if(s.t==="delta"){if(typeof s.delta=="string"&&(yield{type:"response.output_text.delta",item_id:r,delta:s.delta}),typeof s.reasoning=="string"&&(yield{type:"response.reasoning_text.delta",item_id:r,delta:s.reasoning}),Array.isArray(s.tool_calls))for(let a of s.tool_calls){let u=typeof a.index=="number"?a.index:0,c=o.get(u)??{};a.id&&(c.id=a.id),a.function?.name&&(c.name=a.function.name),o.set(u,c),yield{type:"response.function_call_arguments.delta",item_id:`fc_${n}_${u}`,tool_index:u,call_id:c.id,name:c.name,delta:a.function?.arguments??""}}}else if(s.t==="response"){yield{type:"response.completed",response:{id:r,status:"completed",...s.body}};return}else if(s.t==="error"){yield De(s);return}}}var Nt="llm",pe=class{constructor(n){this.session=n;this.sessionTag=n.sessionId??globalThis.crypto.randomUUID()}session;sessionTag;get consumerId(){return this.session.consumerId}write(n){n.session_tag=this.sessionTag,this.session.doc(Nt).set({requests:{[n.request_id]:{payload:n,consumer_id:n.consumer_id,stream:n.stream}}})}sendResponses(n,t){let r=je(n,t,this.consumerId);return this.write(r),we(this.session,t)}sendResponseCreate(n,t,r){let o=Me(n,t,r,this.consumerId);return this.write(o),we(this.session,r)}};var Ge=0;function Tt(){return Ge+=1,`req_${Date.now().toString(36)}_${Ge.toString(36)}`}var ee=class{transport;constructor(n){this.transport=new pe(n)}responses={create:async n=>{let t=Tt(),r=this.transport.sendResponses(n,t);return Object.assign((async function*(){yield*r})(),{requestId:t})}}};async function Be(e){let t=await(e.fetchImpl??fetch)(`${e.catalogUrl}/model_catalog?select=model_id,variant`,{headers:{apikey:e.anonKey,Authorization:`Bearer ${e.anonKey}`}});if(!t.ok)throw new Error(`model_catalog fetch failed: ${t.status}`);return await t.json()}var ze=require("http");var Je="https://api.urun.sh/v1";function xe(e){return e.toLowerCase().replace(/[^\p{L}\p{N}-]/gu,"-").replace(/^-+|-+$/g,"")}var D=class extends Error{};async function qe(e){let n=e.fetchImpl??fetch,t=`${e.apiUrl.replace(/\/+$/,"")}/apps`,r=await n(t,{headers:{Authorization:`Bearer ${e.apiKey}`,Accept:"application/json"}});if(!r.ok)throw new Error(`org apps listing failed: GET ${t} \u2192 ${r.status}`);let o=await r.json();if(!Array.isArray(o.apps))throw new Error(`org apps listing returned no "apps" array (GET ${t})`);if(o.truncated===!0)throw new Error(`org apps listing was truncated (GET ${t} returned ${o.apps.length} of more) \u2014 model discovery would silently omit deployed apps`);return o.apps}var Ct=6e4,ce=class{constructor(n){this.opts=n}opts;pool=new Map;appsCache=null;seed(n,t){this.pool.set(n,Promise.resolve(t))}async deployedApps(){if(!this.opts.listApps)return[];let n=this.opts.appsTtlMs??Ct;if(this.appsCache&&Date.now()-this.appsCache.at<n)return this.appsCache.apps;let t=await this.opts.listApps();return this.appsCache={at:Date.now(),apps:t},t}servable(n){return n.filter(t=>t.function_name===this.opts.fnName&&t.deployment_status==="active").map(t=>t.app_slug)}async availableIds(){let n=new Set([this.opts.defaultApp]);if(this.opts.listApps)for(let t of this.servable(await this.deployedApps()))n.add(t);for(let t of this.pool.keys())n.add(t);return[this.opts.defaultApp,...[...n].filter(t=>t!==this.opts.defaultApp).sort()]}async resolveApp(n){let t=(n??"").trim();if(!t||t==="urun")return this.opts.defaultApp;let r=xe(t);if(r===this.opts.defaultApp)return this.opts.defaultApp;if(this.pool.has(r))return r;if(this.opts.listApps){let o=await this.deployedApps(),i=this.servable(o);if(i.includes(r))return r;let s=i.filter(u=>u.startsWith(`${r}-`));if(s.length===1)return s[0];if(s.length>1)throw new D(`model "${t}" is ambiguous across deployed apps ${s.join(", ")} \u2014 name the exact app slug (or catalog id:variant)`);let a=o.find(u=>u.app_slug===r||u.app_slug.startsWith(`${r}-`));if(a)throw new D(`model "${t}" maps to app "${a.app_slug}", which is not an active "${this.opts.fnName}" app \u2014 deploy it with \`urun serve ${t}\`; available models: ${(await this.availableIds()).join(", ")}`)}if(this.opts.listCatalog){let i=(await this.opts.listCatalog()).find(s=>t===s.model_id||t===`${s.model_id}:${s.variant}`||r===xe(s.model_id)||r===xe(`${s.model_id}-${s.variant}`));if(i)throw new D(`model "${t}" is in the uRun catalog but not deployed \u2014 deploy it with \`urun serve ${i.model_id}\`; available models: ${(await this.availableIds()).join(", ")}`)}return this.opts.defaultApp}async sessionFor(n){let t=await this.resolveApp(n),r=this.pool.get(t);return r||(r=Promise.resolve(this.opts.openSession(t)),this.pool.set(t,r),r.catch(()=>this.pool.delete(t))),{app:t,entry:await r}}async evict(n,t){let r=this.pool.get(n);!r||await r.then(i=>i,()=>null)!==t||this.pool.get(n)!==r||(this.pool.delete(n),await this.opts.closeSession(t).catch(()=>{}))}async modelList(){return{object:"list",data:(await this.availableIds()).map(t=>({id:t,object:"model",created:0,owned_by:"urun"}))}}async closeAll(){let n=[...this.pool.values()];this.pool.clear();let t=[];if(await Promise.all(n.map(async r=>{try{await this.opts.closeSession(await r)}catch(o){t.push(String(o instanceof Error?o.message:o))}})),t.length>0)throw new Error(`failed to close ${t.length} pooled session(s): ${t.join("; ")}`)}};var Se=class e{startedAt=Date.now();requests={};models={};ttftMs=[];tokRates=[];tokensOut=0;charsOut=0;localInBytes=0;naiveInBytes=0;request(n,t,r){this.requests[n]=(this.requests[n]??0)+1,this.localInBytes+=t,this.naiveInBytes+=r}modelEntry(n){let t=this.models[n];if(t)return t;let r=Object.keys(this.models).length>=Lt?"(other)":n;return this.models[r]??={requests:0,tokens_out:0}}model(n){this.modelEntry(n).requests+=1}track(n,t){let r=this,o=performance.now(),i=null,s=0;return(async function*(){for await(let u of n)u.type==="response.output_text.delta"&&typeof u.delta=="string"&&(i===null&&(i=performance.now(),r.ttftMs.push(i-o),r.ttftMs.length>512&&r.ttftMs.shift()),s+=1,r.tokensOut+=1,r.charsOut+=u.delta.length,t!==void 0&&(r.modelEntry(t).tokens_out+=1)),yield u;let a=(performance.now()-(i??o))/1e3;s>0&&a>0&&(r.tokRates.push(s/a),r.tokRates.length>512&&r.tokRates.shift())})()}static p50(n){if(!n.length)return null;let t=[...n].sort((r,o)=>r-o);return t[Math.floor(t.length/2)]}snapshot(){let n=Object.values(this.requests).reduce((t,r)=>t+r,0);return{uptime_s:Math.round((Date.now()-this.startedAt)/1e3),requests:this.requests,models:this.models,tokens_out:this.tokensOut,chars_out:this.charsOut,ttft_ms:{p50:e.p50(this.ttftMs),last:this.ttftMs.at(-1)??null},tok_per_s:{p50:e.p50(this.tokRates),last:this.tokRates.at(-1)??null},traffic:{local_request_bytes:this.localInBytes,naive_baseline:{request_bytes:this.naiveInBytes,connections:n},persistent_connections:1,history_bytes_saved:Math.max(0,this.naiveInBytes-this.localInBytes),history_bytes_saved_pct:this.naiveInBytes>0?Math.round((1-this.localInBytes/this.naiveInBytes)*1e3)/10:null}}}};function Re(e){e.writeHead(200,{"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive"})}function B(e,n,t){e.writeHead(n,{"content-type":"application/json"}),e.end(JSON.stringify(t))}function R(e,n,t,r="invalid_request_error"){B(e,n,{error:{message:t,type:r}})}function be(e,n,t){if(n==="anthropic"){B(e,404,{type:"error",error:{type:"not_found_error",message:t.message}});return}B(e,404,{error:{message:t.message,type:"invalid_request_error",code:"model_not_found"}})}var Lt=256,Mt=128;function Ae(e){return typeof e.model!="string"||!e.model.trim()?"(default)":e.model.trim().slice(0,Mt)}var Fe=64*1024*1024,de=class extends Error{};async function jt(e){let n=[],t=0;for await(let o of e){if(t+=o.length,t>Fe)throw new de(`request body exceeds ${Fe} bytes`);n.push(o)}let r=Buffer.concat(n).toString("utf8");return r?JSON.parse(r):{}}function K(e,n,t,r){return{id:e,object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:n,choices:[{index:0,delta:t,finish_reason:r}]}}var Dt=256;function Gt(e){if(typeof e=="string")return[{role:"user",content:e}];if(Array.isArray(e))return e;throw new Error("responses input must be a string or an array of messages/items")}var Ee=class{conversations=new Map;thread(n,t){let r=Gt(t);if(n==null)return r;let o=this.conversations.get(String(n));if(!o)throw new Error(`unknown previous_response_id ${String(n)} (proxy restarts drop stored responses)`);return[...o,...r]}remember(n,t,r){this.conversations.set(n,[...t,{role:"assistant",content:r}]);for(let o of this.conversations.keys()){if(this.conversations.size<=Dt)break;this.conversations.delete(o)}}};function te(e){let n=e?.output;return Array.isArray(n)?n.filter(t=>t.type==="function_call"):[]}function ne(e){return e.find(n=>n.type==="response.completed")?.response??null}function Ye(e){let n=e?.output;if(!Array.isArray(n))return"";let t="";for(let r of n)if(!(r.type!=="reasoning"||!Array.isArray(r.content)))for(let o of r.content)o.type==="reasoning_text"&&(t+=String(o.text??""));return t}function re(e){return e.type!=="response.function_call_arguments.delta"||typeof e.tool_index!="number"?null:{tool_index:e.tool_index,call_id:typeof e.call_id=="string"?e.call_id:void 0,name:typeof e.name=="string"?e.name:void 0,delta:typeof e.delta=="string"?e.delta:""}}var F=class{calls=new Map;add(n){let t=this.calls.get(n.tool_index),r=!t;return t||(t={args:""},this.calls.set(n.tool_index,t)),n.call_id&&(t.id=n.call_id),n.name&&(t.name=n.name),t.args+=n.delta,{call:t,isNew:r}}get size(){return this.calls.size}items(){return[...this.calls.entries()].map(([n,t])=>({type:"function_call",call_id:t.id??`call_${n}`,name:t.name??"",arguments:t.args}))}},Bt=["<tool_call>","<function="];function Jt(e){return Bt.find(n=>e.includes(n))}function z(e,n){return`serving row emitted a prose tool call (literal ${JSON.stringify(n)} in the assistant text) for a request that carried tools, and no structured tool_calls arrived \u2014 the tool-call parser is not configured on the model row "${e}" (see catalog parser_defaults)`}function Y(e,n,t){if(!(!e||n>0))return Jt(t)}function qt(e){if(Array.isArray(e))return e.map(n=>{let t=n.function;return!t||typeof t!="object"?n:{type:"function",name:t.name,description:t.description,parameters:t.parameters,strict:t.strict}})}var me=class extends Error{};function Ft(e,n){return Array.isArray(n)?n.map(t=>{let r=t;if(r.type==="text")return{type:e==="assistant"?"output_text":"input_text",text:r.text};if(r.type==="image_url"){let o=r.image_url??{};return{type:"input_image",image_url:o.url,detail:o.detail}}throw new me(`unsupported chat content part type "${String(r.type)}" \u2014 the proxy translates text and image_url parts`)}):n}function Kt(e){let n=[];for(let t of e){if(t.role==="tool"){n.push({type:"function_call_output",call_id:t.tool_call_id,output:typeof t.content=="string"?t.content:JSON.stringify(t.content??"")});continue}if(t.role==="assistant"&&Array.isArray(t.tool_calls)){typeof t.content=="string"&&t.content&&n.push({role:"assistant",content:t.content});for(let r of t.tool_calls){let o=r.function??{};n.push({type:"function_call",call_id:r.id,name:o.name,arguments:o.arguments})}continue}n.push({...t,content:Ft(t.role,t.content)})}return n}function ke(e){return te(e).map((n,t)=>({index:t,id:n.call_id??n.id??`call_${t}`,type:"function",function:{name:n.name??"",arguments:n.arguments??"{}"}}))}function Ke(e,n){let t=n?.output_text;return typeof t=="string"?t:e.filter(r=>r.type==="response.output_text.delta"&&typeof r.delta=="string").map(r=>r.delta).join("")}async function zt(e,n,t,r,o){let i=e.stream===!0,s;try{s=t.thread(e.previous_response_id,e.input)}catch(p){R(r,400,String(p instanceof Error?p.message:p));return}e.previous_response_id!=null&&(o.naiveInBytes+=Buffer.byteLength(JSON.stringify(s))-Buffer.byteLength(JSON.stringify(e.input)));let a=`resp_${Math.random().toString(36).slice(2,14)}`,u=e.store!==!1,c=Ae(e);o.model(c);let d=Array.isArray(e.tools)&&e.tools.length>0,w;try{w=await n.createResponse({model:e.model,input:s,stream:i,tools:e.tools,tool_choice:e.tool_choice,temperature:e.temperature,max_output_tokens:e.max_output_tokens})}catch(p){if(p instanceof D){be(r,"openai",p);return}throw p}let h=[];if(i){Re(r);let p=g=>{r.write(`event: ${String(g.type??"message")}
|
|
3
3
|
data: ${JSON.stringify(g)}
|
|
4
4
|
|
|
5
|
-
`)},
|
|
5
|
+
`)},A=g=>g.response&&typeof g.response=="object"?{...g,response:{...g.response,id:a}}:g,m=`item_${a.slice(5)}`,I=`rs_${a.slice(5)}`,U=!1,T=!1,l=0,k=()=>{U||(U=!0,p({type:"response.created",response:{id:a,object:"response",status:"in_progress"}}))},M=!1,P=0,C="",j=()=>{M&&(M=!1,p({type:"response.reasoning_text.done",item_id:I,output_index:P,content_index:0,text:C}),p({type:"response.output_item.done",output_index:P,item:{id:I,type:"reasoning",summary:[],content:[{type:"reasoning_text",text:C}],status:"completed"}}))},_=!1,b=0,O="",q=g=>{_&&(_=!1,p({type:"response.output_text.done",item_id:m,output_index:b,content_index:0,text:O}),p({type:"response.content_part.done",item_id:m,output_index:b,content_index:0,part:{type:"output_text",text:O}}),p({type:"response.output_item.done",output_index:b,item:{id:m,type:"message",role:"assistant",status:g,content:[{type:"output_text",text:O}]}}))},G=new F,v=null,H=-1,W=g=>{if(!v)return;let S=v;v=null,p({type:"response.function_call_arguments.done",item_id:S.fcId,output_index:S.outputIndex,arguments:S.args}),p({type:"response.output_item.done",output_index:S.outputIndex,item:{id:S.fcId,type:"function_call",call_id:S.callId??S.fcId,name:S.name??"",arguments:S.args,status:g}})},X=!1;for await(let g of o.track(w,c)){h.push(g);let S=String(g.type??"");if(S==="response.created"||S==="response.in_progress"){U=!0,p(A(g));continue}if(S==="response.output_item.added"){T=!0,p(A(g));continue}if(S==="response.reasoning_text.delta"&&!T){k(),M||(M=!0,P=l++,p({type:"response.output_item.added",output_index:P,item:{id:I,type:"reasoning",summary:[],content:[],status:"in_progress"}})),C+=String(g.delta??""),p({type:"response.reasoning_text.delta",item_id:I,output_index:P,content_index:0,delta:g.delta});continue}if(S==="response.output_text.delta"&&!T){k(),j(),_||(_=!0,b=l++,p({type:"response.output_item.added",output_index:b,item:{id:m,type:"message",role:"assistant",status:"in_progress",content:[]}}),p({type:"response.content_part.added",item_id:m,output_index:b,content_index:0,part:{type:"output_text",text:""}})),O+=String(g.delta??""),p({type:S,item_id:m,output_index:b,content_index:0,delta:g.delta});continue}let f=T?null:re(g);if(f){if(k(),j(),q("completed"),G.add(f),f.tool_index!==H){W("completed"),H=f.tool_index;let E=l++;v={fcId:`fc_${a.slice(5)}_${f.tool_index}`,outputIndex:E,callId:f.call_id,name:f.name,args:""},p({type:"response.output_item.added",output_index:E,item:{id:v.fcId,type:"function_call",call_id:v.callId??v.fcId,name:v.name??"",arguments:"",status:"in_progress"}})}v&&(f.call_id&&(v.callId=f.call_id),f.name&&(v.name=f.name),v.args+=f.delta,p({type:"response.function_call_arguments.delta",item_id:v.fcId,output_index:v.outputIndex,delta:f.delta}));continue}if(S==="response.completed"&&!T){let E=te(g.response),V=Y(d,G.size+E.length,O);if(V){X=!0,p({type:"error",error:{type:"urun_error",code:"tool_call_parser_missing",message:z(c,V)}});break}j(),q("completed"),W("completed"),G.size===0&&E.forEach(Q=>{let Z=l++,ae=Q.id??Q.call_id??`fc_${Z}`,_e=Q.arguments??"",Ce={id:ae,type:"function_call",call_id:Q.call_id??ae,name:Q.name??""};p({type:"response.output_item.added",output_index:Z,item:{...Ce,arguments:"",status:"in_progress"}}),p({type:"response.function_call_arguments.delta",item_id:ae,output_index:Z,delta:_e}),p({type:"response.function_call_arguments.done",item_id:ae,output_index:Z,arguments:_e}),p({type:"response.output_item.done",output_index:Z,item:{...Ce,arguments:_e,status:"completed"}})}),p(A(g));continue}p(A(g))}j(),q("incomplete"),W("incomplete"),u&&!X&&t.remember(a,s,Ke(h,ne(h))),r.write(`data: [DONE]
|
|
6
6
|
|
|
7
|
-
`),r.end();return}let
|
|
7
|
+
`),r.end();return}let x=null;for await(let p of o.track(w,c)){if(h.push(p),p.type==="error"){R(r,502,JSON.stringify(p),"upstream_error");return}p.type==="response.completed"&&(x=p.response)}if(x==null){R(r,502,"upstream produced no response.completed event","upstream_error");return}let $=Ke(h,x),L=Y(d,te(x).length,$);if(L){R(r,502,z(c,L),"upstream_error");return}u&&t.remember(a,s,$),B(r,200,{...x,id:a})}async function Yt(e,n,t,r){let o=e.messages;if(!Array.isArray(o)){R(t,400,"chat/completions requires a messages array");return}let i=String(e.model??"urun"),s=`chatcmpl-${Math.random().toString(36).slice(2,14)}`,a;try{a=Kt(o)}catch(l){if(l instanceof me){R(t,400,l.message);return}throw l}let u=Ae(e);r.model(u);let c=Array.isArray(e.tools)&&e.tools.length>0,d;try{d=await n.createResponse({model:e.model,input:a,stream:!0,tools:qt(e.tools),tool_choice:e.tool_choice,temperature:e.temperature,max_output_tokens:e.max_completion_tokens??e.max_tokens})}catch(l){if(l instanceof D){be(t,"openai",l);return}throw l}if(e.stream===!0){Re(t);let l=[],k=new F,M="";t.write(`data: ${JSON.stringify(K(s,i,{role:"assistant"},null))}
|
|
8
8
|
|
|
9
|
-
`);for await(let
|
|
9
|
+
`);for await(let _ of r.track(d,u)){l.push(_);let b=re(_);if(_.type==="response.output_text.delta"&&typeof _.delta=="string")M+=_.delta,t.write(`data: ${JSON.stringify(K(s,i,{content:_.delta},null))}
|
|
10
10
|
|
|
11
|
-
`);else if(
|
|
11
|
+
`);else if(_.type==="response.reasoning_text.delta"&&typeof _.delta=="string")t.write(`data: ${JSON.stringify(K(s,i,{reasoning_content:_.delta},null))}
|
|
12
12
|
|
|
13
|
-
`)
|
|
13
|
+
`);else if(b){let{call:O,isNew:q}=k.add(b),G=q?{index:b.tool_index,id:O.id??`call_${b.tool_index}`,type:"function",function:{name:O.name??"",arguments:b.delta}}:{index:b.tool_index,function:{arguments:b.delta}};t.write(`data: ${JSON.stringify(K(s,i,{tool_calls:[G]},null))}
|
|
14
14
|
|
|
15
|
-
`)
|
|
15
|
+
`)}else if(_.type==="error"){t.write(`data: ${JSON.stringify({error:_})}
|
|
16
|
+
|
|
17
|
+
`),t.end();return}}let P=ke(ne(l)),C=Y(c,k.size+P.length,M);if(C){t.write(`data: ${JSON.stringify({error:{type:"urun_error",code:"tool_call_parser_missing",message:z(u,C)}})}
|
|
18
|
+
|
|
19
|
+
`),t.end();return}k.size===0&&P.length>0&&t.write(`data: ${JSON.stringify(K(s,i,{tool_calls:P},null))}
|
|
20
|
+
|
|
21
|
+
`);let j=k.size>0||P.length>0;t.write(`data: ${JSON.stringify(K(s,i,{},j?"tool_calls":"stop"))}
|
|
16
22
|
|
|
17
23
|
`),t.write(`data: [DONE]
|
|
18
24
|
|
|
19
|
-
`),t.end();return}let
|
|
20
|
-
data: ${JSON.stringify({type:
|
|
21
|
-
|
|
22
|
-
`)};if(e.stream===!0){let c=r.track(d,u);Q(t),l("message_start",{message:{id:a,type:"message",role:"assistant",content:[],model:s,stop_reason:null,usage:{input_tokens:0,output_tokens:0}}}),l("content_block_start",{index:0,content_block:{type:"text",text:""}});let y=0,S=[];for await(let h of c)if(S.push(h),h.type==="response.output_text.delta"&&typeof h.delta=="string")y+=1,l("content_block_delta",{index:0,delta:{type:"text_delta",text:h.delta}});else if(h.type==="error"){l("error",{error:{type:"api_error",message:JSON.stringify(h)}}),t.end();return}let b;try{b=ve(L(S))}catch(h){l("error",{error:{type:"api_error",message:String(h instanceof Error?h.message:h)}}),t.end();return}l("content_block_stop",{index:0}),b.forEach((h,E)=>{let P=1+E;l("content_block_start",{index:P,content_block:{...h,input:{}}}),l("content_block_delta",{index:P,delta:{type:"input_json_delta",partial_json:JSON.stringify(h.input??{})}}),l("content_block_stop",{index:P})}),l("message_delta",{delta:{stop_reason:b.length>0?"tool_use":"end_turn"},usage:{output_tokens:y}}),l("message_stop",{}),t.end();return}let f="",w=[];for await(let c of r.track(d,u))if(w.push(c),c.type==="response.output_text.delta"&&typeof c.delta=="string"&&(f+=c.delta),c.type==="error"){_(t,502,JSON.stringify(c),"upstream_error");return}let x;try{x=ve(L(w))}catch(c){_(t,502,String(c instanceof Error?c.message:c),"upstream_error");return}let p=[];(f||x.length===0)&&p.push({type:"text",text:f}),p.push(...x),R(t,200,{id:a,type:"message",role:"assistant",content:p,model:s,stop_reason:x.length>0?"tool_use":"end_turn",usage:{input_tokens:0,output_tokens:0}})}function Re(e){let{clients:n,apiKey:t,identity:r}=e,o=new V,s=new X;return(0,ke.createServer)((a,i)=>{(async()=>{let u=new URL(a.url??"/","http://localhost");if(a.method==="GET"&&u.pathname==="/healthz"){R(i,200,{ok:!0});return}if(a.method==="GET"&&u.pathname==="/stats"){R(i,200,r?{identity:r,...s.snapshot()}:s.snapshot());return}if(t&&(a.headers.authorization??"")!==`Bearer ${t}`){_(i,401,"invalid local proxy api key","authentication_error");return}if(a.method==="GET"&&u.pathname==="/v1/models"){R(i,200,await n.listModels());return}if(a.method!=="POST"){_(i,404,`no route for ${a.method} ${u.pathname}`);return}let d;try{d=await ct(a)}catch(f){if(f instanceof q){_(i,413,f.message,"request_too_large");return}_(i,400,"request body is not valid JSON");return}let l=Buffer.byteLength(JSON.stringify(d));if(u.pathname==="/v1/responses"){s.request("responses",l,l),await gt(d,n,o,i,s);return}if(u.pathname==="/v1/chat/completions"){s.request("chat_completions",l,l),await ht(d,n,i,s);return}if(u.pathname==="/v1/messages"){s.request("messages",l,l),await kt(d,n,i,s);return}_(i,404,`no route for POST ${u.pathname}`)})().catch(u=>{i.headersSent?i.end():_(i,500,String(u),"proxy_error")})})}var Ae=D(require("os"),1),Se=D(require("path"),1),Ee=require("url"),Pe=require("util");var be="0.2.53";var Ue=4141,bt=be,F={claude:{bin:"claude",env:"anthropic"},codex:{bin:"codex",env:"openai"},pi:{bin:"pi",env:"openai"},aider:{bin:"aider",env:"openai"},opencode:{bin:"opencode",env:"openai"},crush:{bin:"crush",env:"openai"}};function oe(e,n="openai"){if(n==="anthropic")return{ANTHROPIC_BASE_URL:`http://127.0.0.1:${e}`,ANTHROPIC_API_KEY:"urun-local"};let t=`http://127.0.0.1:${e}/v1`;return{OPENAI_BASE_URL:t,OPENAI_API_BASE:t,OPENAI_API_KEY:"urun-local"}}function Ie(e,n,t){let r={...e,...oe(n,t)};return delete r.URUN_API_KEY,delete r.URUN_JWT,r}function Oe(e,n,t){let r=["-c","model_providers.urun.name=urun","-c",`model_providers.urun.base_url="http://127.0.0.1:${e}/v1"`,"-c",'model_providers.urun.wire_api="responses"',"-c",'model_provider="urun"'],o=t.indexOf("--"),s=o===-1?t:t.slice(0,o),a=s.some(l=>l==="-m"||l==="--model"||l.startsWith("--model=")),i=t[0]==="exec",u=s.includes("--skip-git-repo-check"),d=i&&!u?["exec","--skip-git-repo-check",...t.slice(1)]:t;return[...r,...a?[]:["-m",n],...d]}function $e(e,n){return n.some(r=>r==="--model"||r==="--provider"||r.startsWith("--model=")||r.startsWith("--provider="))?n:["--provider","urun","--model",e,...n]}function Ne(e,n,t){let r=(e.URUN_PI_EXTENSION_ENTRY??"").trim();if(r){if(!t(r))throw new Error(`URUN_PI_EXTENSION_ENTRY points at ${r}, which does not exist \u2014 the launcher that injected it (the vendored urun CLI shim) must materialize the pi extension bundle before spawning pi`);return r}let o=(0,Ee.fileURLToPath)(new URL("../pi-extension/standalone.cjs",n));if(!t(o))throw new Error(`pi extension entry not found at ${o} \u2014 the pi lane loads the self-contained @urun-sh/openai dist/pi-extension/standalone.cjs from the installed package (run \`urun compat pi\` via the npm-installed CLI, e.g. \`npx @urun-sh/openai\`), or pass an entry to pi yourself: \`pi -e <path-to-@urun-sh/openai>/dist/pi-extension/standalone.cjs\``);return o}function Le(e){let n=Number(e);if(!Number.isInteger(n)||n<0)throw new Error(`--port needs a non-negative integer (0 = OS-assigned ephemeral), got ${e}`);return n}function Ce(e){if(e[0]!=="--port")return null;let n=Le(e[1]);return e.splice(0,2),n}function se(e){let n=e.indexOf("--port");if(n===-1)return Ue;let t=Le(e[n+1]);return e.splice(n,2),t}function Te(e){if(e===0)throw new Error("`env` cannot use --port 0: it starts no proxy, so the OS never assigns the ephemeral port \u2014 pass the actual port of the running proxy");return e}function ne(e,n){let t=(e[n]??"").trim();if(!t)throw new Error(`${n} is not set. The proxy needs URUN_BASE_URL, URUN_ORG_ID, URUN_APP and either URUN_API_KEY (the org key; the proxy vends short-lived function-scoped client tokens from it via the SDK) or URUN_JWT (an explicit pre-vended token override) \u2014 plus optional URUN_FUNCTION, default "serve" \u2014 to open the backhaul session.`);return t}function C(e){let n=At(ne(e,"URUN_BASE_URL")),t=ne(e,"URUN_ORG_ID"),r=ne(e,"URUN_APP"),o=(e.URUN_FUNCTION??"serve").trim()||"serve",s=(e.URUN_API_URL??"").trim(),a=s?Y(s,"URUN_API_URL"):ge,i=(e.URUN_JWT??"").trim();if(i)return{baseUrl:n,orgId:t,appId:r,fnName:o,apiUrl:a,auth:{lane:"jwt",jwt:i}};let u=(e.URUN_API_KEY??"").trim();if(u){let d=(e.URUN_GATEWAY_URL??"").trim(),l=d?Y(d):void 0;return{baseUrl:n,orgId:t,appId:r,fnName:o,apiUrl:a,auth:{lane:"api-key",apiKey:u,gatewayUrl:l}}}throw new Error("neither URUN_API_KEY nor URUN_JWT is set. Set URUN_API_KEY (the org API key \u2014 the proxy vends short-lived, function-scoped client tokens from it via the SDK, so the key never reaches the agent process) or URUN_JWT (an explicit pre-vended token; when set it always wins). URUN_BASE_URL, URUN_ORG_ID and URUN_APP are also required.")}function At(e,n="URUN_BASE_URL"){if(/\/v1\/*$/.test(new URL(e).pathname))throw new Error(`${n} must be the session-gateway base (e.g. https://api.urun.sh), got ${e} \u2014 a trailing /v1 is the org control-plane API form (that belongs in URUN_API_URL); session allocation 404s against it. Drop the /v1.`);return e}function Y(e,n="URUN_GATEWAY_URL"){let t=new URL(e),r=t.hostname==="localhost"||t.hostname==="127.0.0.1"||t.hostname==="[::1]";if(t.protocol!=="https:"&&!r)throw new Error(`${n} must be https (got ${e}) \u2014 the org API key rides the request's Authorization header`);return e}function ie(e){return{app:e.appId,org:e.orgId,fn:e.fnName,base_url:e.baseUrl,proxy_version:bt}}function St(e,n){return e.app===n.app&&e.org===n.org&&e.fn===n.fn&&e.base_url===n.base_url&&e.proxy_version===n.proxy_version}var Et=250;async function ae(e,n=Et){try{let t=await fetch(`http://127.0.0.1:${e}/stats`,{signal:AbortSignal.timeout(n)});if(!t.ok)return null;let r=(await t.json()).identity;if(r==null||typeof r!="object")return null;let{app:o,org:s,fn:a,base_url:i,proxy_version:u}=r;return typeof o!="string"||typeof s!="string"||typeof a!="string"||typeof i!="string"||typeof u!="string"?null:{app:o,org:s,fn:a,base_url:i,proxy_version:u}}catch{return null}}async function je(e,n,t=Ue){if(e!=null)return{mode:"spawn",port:e};let r=await ae(t);return r!==null&&St(r,n)?{mode:"reuse",port:t,identity:r}:{mode:"spawn",port:0}}function Me(e,n=Ae.default.homedir()){return Se.default.join(n,".urun","logs",`compat-proxy-${e}.log`)}var re=["log","info","warn","error","debug","trace"];function De(e,n=process,t=console){let r=n.stdout.write,o=n.stderr.write,s=(i,...u)=>e.write(i,...u);n.stdout.write=s,n.stderr.write=s;let a=Object.fromEntries(re.map(i=>[i,t[i]]));for(let i of re)t[i]=(...u)=>{e.write(`${(0,Pe.format)(...u)}
|
|
23
|
-
`)};return()=>{n.stdout.write=r,n.stderr.write=o;for(let
|
|
24
|
-
`);
|
|
25
|
-
`)
|
|
26
|
-
`)}
|
|
27
|
-
`),
|
|
28
|
-
`);let
|
|
29
|
-
`)}),
|
|
30
|
-
`),
|
|
31
|
-
`),
|
|
32
|
-
`)
|
|
33
|
-
`),
|
|
25
|
+
`),t.end();return}let w="",h="",x=[],$=new F;for await(let l of r.track(d,u)){x.push(l),l.type==="response.output_text.delta"&&typeof l.delta=="string"&&(w+=l.delta),l.type==="response.reasoning_text.delta"&&typeof l.delta=="string"&&(h+=l.delta);let k=re(l);if(k&&$.add(k),l.type==="error"){R(t,502,JSON.stringify(l),"upstream_error");return}}let L=ne(x),p=ke(L),A=p.length>0?p:ke({output:$.items()}),m=Y(c,A.length,w);if(m){R(t,502,z(u,m),"upstream_error");return}let I=A.map(({index:l,...k})=>k),U={role:"assistant",content:w||null},T=h||Ye(L);T&&(U.reasoning_content=T),I.length>0&&(U.tool_calls=I),B(t,200,{id:s,object:"chat.completion",created:Math.floor(Date.now()/1e3),model:i,choices:[{index:0,message:U,finish_reason:I.length>0?"tool_calls":"stop"}],usage:{prompt_tokens:0,completion_tokens:0,total_tokens:0}})}function Ht(e){return typeof e=="string"?e:Array.isArray(e)?e.filter(n=>n.type==="text").map(n=>String(n.text??"")).join(""):""}var oe=class extends Error{};function fe(e){return new oe(`unsupported anthropic content block type "${e}" \u2014 the proxy translates text, tool_use and tool_result blocks`)}function Wt(e){if(Array.isArray(e))return e.map(n=>{let t=n;return{type:"function",name:t.name,description:t.description,parameters:t.input_schema}})}function Xt(e){if(e==null)return;let n=e.type;if(n==="auto")return"auto";if(n==="none")return"none";if(n==="any")return"required";if(n==="tool")return{type:"function",name:e.name};throw new oe(`unsupported anthropic tool_choice type ${JSON.stringify(String(n))} \u2014 the proxy maps auto, none, any and tool`)}function Vt(e){if(typeof e=="string")return e;if(e==null)return"";if(!Array.isArray(e))throw fe(typeof e);let n="";for(let t of e){let r=String(t.type??"");if(r!=="text")throw fe(`tool_result > ${r}`);n+=String(t.text??"")}return n}function Qt(e){let{role:n,content:t}=e;if(typeof t=="string")return[{role:n,content:t}];if(t==null)return[];if(!Array.isArray(t))throw fe(typeof t);let r=[],o="",i=()=>{o&&(r.push({role:n,content:o}),o="")};for(let s of t){let a=String(s.type??"");if(a==="text")o+=String(s.text??"");else if(a==="tool_use")i(),r.push({type:"function_call",call_id:s.id,name:s.name,arguments:JSON.stringify(s.input??{})});else if(a==="tool_result")i(),r.push({type:"function_call_output",call_id:s.tool_use_id,output:Vt(s.content)});else{if(a==="thinking"||a==="redacted_thinking")continue;throw fe(a)}}return i(),r}function ve(e){return te(e).map((n,t)=>{let r;try{r=JSON.parse(n.arguments||"{}")}catch{throw new Error(`upstream function_call "${n.name??""}" arguments are not valid JSON`)}return{type:"tool_use",id:n.call_id??n.id??`toolu_${t}`,name:n.name??"",input:r}})}async function Zt(e,n,t,r){let o=e.messages;if(!Array.isArray(o)){R(t,400,"messages requires a messages array");return}let i=String(e.model??"urun"),s=`msg_${Math.random().toString(36).slice(2,14)}`,a=[],u;try{e.system&&a.push({role:"system",content:Ht(e.system)});for(let l of o)a.push(...Qt(l));u=Xt(e.tool_choice)}catch(l){if(l instanceof oe){R(t,400,l.message);return}throw l}let c=Ae(e);r.model(c);let d=Array.isArray(e.tools)&&e.tools.length>0,w;try{w=await n.createResponse({model:e.model,input:a,stream:!0,tools:Wt(e.tools),tool_choice:u,temperature:e.temperature,max_output_tokens:e.max_tokens})}catch(l){if(l instanceof D){be(t,"anthropic",l);return}throw l}let h=(l,k)=>{t.write(`event: ${l}
|
|
26
|
+
data: ${JSON.stringify({type:l,...k})}
|
|
27
|
+
|
|
28
|
+
`)};if(e.stream===!0){let l=r.track(w,c);Re(t),h("message_start",{message:{id:s,type:"message",role:"assistant",content:[],model:i,stop_reason:null,usage:{input_tokens:0,output_tokens:0}}});let k=0,M="",P=0,C="none",j=()=>C,_=-1,b=-1,O=new F,q=[],G=()=>{C!=="none"&&(C="none",h("content_block_stop",{index:_}))},v=(f,E)=>{G(),C=f,_=P++,h("content_block_start",{index:_,content_block:E})};for await(let f of l){q.push(f);let E=re(f);if(f.type==="response.reasoning_text.delta"&&typeof f.delta=="string")j()!=="thinking"&&v("thinking",{type:"thinking",thinking:""}),h("content_block_delta",{index:_,delta:{type:"thinking_delta",thinking:f.delta}});else if(f.type==="response.output_text.delta"&&typeof f.delta=="string")j()!=="text"&&v("text",{type:"text",text:""}),k+=1,M+=f.delta,h("content_block_delta",{index:_,delta:{type:"text_delta",text:f.delta}});else if(E){let{call:V}=O.add(E);(j()!=="tool"||E.tool_index!==b)&&(b=E.tool_index,v("tool",{type:"tool_use",id:V.id??`call_${E.tool_index}`,name:V.name??"",input:{}})),E.delta&&h("content_block_delta",{index:_,delta:{type:"input_json_delta",partial_json:E.delta}})}else if(f.type==="error"){h("error",{error:{type:"api_error",message:JSON.stringify(f)}}),t.end();return}}let H=ne(q),W=te(H),X=Y(d,O.size+W.length,M);if(X){h("error",{error:{type:"api_error",message:z(c,X)}}),t.end();return}G();let g=[];if(O.size===0)try{g=ve(H)}catch(f){h("error",{error:{type:"api_error",message:String(f instanceof Error?f.message:f)}}),t.end();return}P===0&&g.length===0&&(v("text",{type:"text",text:""}),G()),g.forEach(f=>{let E=P++;h("content_block_start",{index:E,content_block:{...f,input:{}}}),h("content_block_delta",{index:E,delta:{type:"input_json_delta",partial_json:JSON.stringify(f.input??{})}}),h("content_block_stop",{index:E})});let S=O.size>0||g.length>0;h("message_delta",{delta:{stop_reason:S?"tool_use":"end_turn"},usage:{output_tokens:k}}),h("message_stop",{}),t.end();return}let x="",$="",L=[],p=new F;for await(let l of r.track(w,c)){L.push(l),l.type==="response.output_text.delta"&&typeof l.delta=="string"&&(x+=l.delta),l.type==="response.reasoning_text.delta"&&typeof l.delta=="string"&&($+=l.delta);let k=re(l);if(k&&p.add(k),l.type==="error"){R(t,502,JSON.stringify(l),"upstream_error");return}}let A=ne(L),m;try{m=ve(A),m.length===0&&p.size>0&&(m=ve({output:p.items()}))}catch(l){R(t,502,String(l instanceof Error?l.message:l),"upstream_error");return}let I=Y(d,m.length,x);if(I){R(t,502,z(c,I),"upstream_error");return}let U=[],T=$||Ye(A);T&&U.push({type:"thinking",thinking:T}),(x||m.length===0)&&U.push({type:"text",text:x}),U.push(...m),B(t,200,{id:s,type:"message",role:"assistant",content:U,model:i,stop_reason:m.length>0?"tool_use":"end_turn",usage:{input_tokens:0,output_tokens:0}})}function He(e){let{clients:n,apiKey:t,identity:r}=e,o=new Ee,i=new Se;return(0,ze.createServer)((s,a)=>{(async()=>{let u=new URL(s.url??"/","http://localhost");if(s.method==="GET"&&u.pathname==="/healthz"){B(a,200,{ok:!0});return}if(s.method==="GET"&&u.pathname==="/stats"){B(a,200,r?{identity:r,...i.snapshot()}:i.snapshot());return}if(t&&(s.headers.authorization??"")!==`Bearer ${t}`){R(a,401,"invalid local proxy api key","authentication_error");return}if(s.method==="GET"&&u.pathname==="/v1/models"){B(a,200,await n.listModels());return}if(s.method!=="POST"){R(a,404,`no route for ${s.method} ${u.pathname}`);return}let c;try{c=await jt(s)}catch(w){if(w instanceof de){R(a,413,w.message,"request_too_large");return}R(a,400,"request body is not valid JSON");return}let d=Buffer.byteLength(JSON.stringify(c));if(u.pathname==="/v1/responses"){i.request("responses",d,d),await zt(c,n,o,a,i);return}if(u.pathname==="/v1/chat/completions"){i.request("chat_completions",d,d),await Yt(c,n,a,i);return}if(u.pathname==="/v1/messages"){i.request("messages",d,d),await Zt(c,n,a,i);return}R(a,404,`no route for POST ${u.pathname}`)})().catch(u=>{a.headersSent?a.end():R(a,500,String(u),"proxy_error")})})}var Xe=le(require("os"),1),Ve=le(require("path"),1),Qe=require("url"),Ze=require("util");var We="0.2.55";var et=4141,tn=We,ye={claude:{bin:"claude",env:"anthropic"},codex:{bin:"codex",env:"openai"},pi:{bin:"pi",env:"openai"},aider:{bin:"aider",env:"openai"},opencode:{bin:"opencode",env:"openai"},crush:{bin:"crush",env:"openai"}};function Oe(e,n="openai"){if(n==="anthropic")return{ANTHROPIC_BASE_URL:`http://127.0.0.1:${e}`,ANTHROPIC_API_KEY:"urun-local"};let t=`http://127.0.0.1:${e}/v1`;return{OPENAI_BASE_URL:t,OPENAI_API_BASE:t,OPENAI_API_KEY:"urun-local"}}function tt(e,n,t){let r={...e,...Oe(n,t)};return delete r.URUN_API_KEY,delete r.URUN_JWT,r}function nt(e,n,t){let r=["-c","model_providers.urun.name=urun","-c",`model_providers.urun.base_url="http://127.0.0.1:${e}/v1"`,"-c",'model_providers.urun.wire_api="responses"',"-c",'model_provider="urun"'],o=t.indexOf("--"),i=o===-1?t:t.slice(0,o),s=i.some(d=>d==="-m"||d==="--model"||d.startsWith("--model=")),a=t[0]==="exec",u=i.includes("--skip-git-repo-check"),c=a&&!u?["exec","--skip-git-repo-check",...t.slice(1)]:t;return[...r,...s?[]:["-m",n],...c]}function rt(e,n){return n.some(r=>r==="--model"||r==="--provider"||r.startsWith("--model=")||r.startsWith("--provider="))?n:["--provider","urun","--model",e,...n]}function ot(e,n,t){let r=(e.URUN_PI_EXTENSION_ENTRY??"").trim();if(r){if(!t(r))throw new Error(`URUN_PI_EXTENSION_ENTRY points at ${r}, which does not exist \u2014 the launcher that injected it (the vendored urun CLI shim) must materialize the pi extension bundle before spawning pi`);return r}let o=(0,Qe.fileURLToPath)(new URL("../pi-extension/standalone.cjs",n));if(!t(o))throw new Error(`pi extension entry not found at ${o} \u2014 the pi lane loads the self-contained @urun-sh/openai dist/pi-extension/standalone.cjs from the installed package (run \`urun compat pi\` via the npm-installed CLI, e.g. \`npx @urun-sh/openai\`), or pass an entry to pi yourself: \`pi -e <path-to-@urun-sh/openai>/dist/pi-extension/standalone.cjs\``);return o}function st(e){let n=Number(e);if(!Number.isInteger(n)||n<0)throw new Error(`--port needs a non-negative integer (0 = OS-assigned ephemeral), got ${e}`);return n}function it(e){if(e[0]!=="--port")return null;let n=st(e[1]);return e.splice(0,2),n}function $e(e){let n=e.indexOf("--port");if(n===-1)return et;let t=st(e[n+1]);return e.splice(n,2),t}function at(e){if(e===0)throw new Error("`env` cannot use --port 0: it starts no proxy, so the OS never assigns the ephemeral port \u2014 pass the actual port of the running proxy");return e}function Ie(e,n){let t=(e[n]??"").trim();if(!t)throw new Error(`${n} is not set. The proxy needs URUN_BASE_URL, URUN_ORG_ID, URUN_APP and either URUN_API_KEY (the org key; the proxy vends short-lived function-scoped client tokens from it via the SDK) or URUN_JWT (an explicit pre-vended token override) \u2014 plus optional URUN_FUNCTION, default "serve" \u2014 to open the backhaul session.`);return t}function se(e){let n=nn(Ie(e,"URUN_BASE_URL")),t=Ie(e,"URUN_ORG_ID"),r=Ie(e,"URUN_APP"),o=(e.URUN_FUNCTION??"serve").trim()||"serve",i=(e.URUN_API_URL??"").trim(),s=i?ge(i,"URUN_API_URL"):Je,a=(e.URUN_JWT??"").trim();if(a)return{baseUrl:n,orgId:t,appId:r,fnName:o,apiUrl:s,auth:{lane:"jwt",jwt:a}};let u=(e.URUN_API_KEY??"").trim();if(u){let c=(e.URUN_GATEWAY_URL??"").trim(),d=c?ge(c):void 0;return{baseUrl:n,orgId:t,appId:r,fnName:o,apiUrl:s,auth:{lane:"api-key",apiKey:u,gatewayUrl:d}}}throw new Error("neither URUN_API_KEY nor URUN_JWT is set. Set URUN_API_KEY (the org API key \u2014 the proxy vends short-lived, function-scoped client tokens from it via the SDK, so the key never reaches the agent process) or URUN_JWT (an explicit pre-vended token; when set it always wins). URUN_BASE_URL, URUN_ORG_ID and URUN_APP are also required.")}function nn(e,n="URUN_BASE_URL"){if(/\/v1\/*$/.test(new URL(e).pathname))throw new Error(`${n} must be the session-gateway base (e.g. https://api.urun.sh), got ${e} \u2014 a trailing /v1 is the org control-plane API form (that belongs in URUN_API_URL); session allocation 404s against it. Drop the /v1.`);return e}function ge(e,n="URUN_GATEWAY_URL"){let t=new URL(e),r=t.hostname==="localhost"||t.hostname==="127.0.0.1"||t.hostname==="[::1]";if(t.protocol!=="https:"&&!r)throw new Error(`${n} must be https (got ${e}) \u2014 the org API key rides the request's Authorization header`);return e}function Ue(e){return{app:e.appId,org:e.orgId,fn:e.fnName,base_url:e.baseUrl,proxy_version:tn}}function rn(e,n){return e.app===n.app&&e.org===n.org&&e.fn===n.fn&&e.base_url===n.base_url&&e.proxy_version===n.proxy_version}var on=250;async function Ne(e,n=on){try{let t=await fetch(`http://127.0.0.1:${e}/stats`,{signal:AbortSignal.timeout(n)});if(!t.ok)return null;let r=(await t.json()).identity;if(r==null||typeof r!="object")return null;let{app:o,org:i,fn:s,base_url:a,proxy_version:u}=r;return typeof o!="string"||typeof i!="string"||typeof s!="string"||typeof a!="string"||typeof u!="string"?null:{app:o,org:i,fn:s,base_url:a,proxy_version:u}}catch{return null}}var ut=2e3;async function sn(e,n=ut){try{let t=await fetch(`http://127.0.0.1:${e}/v1/models`,{signal:AbortSignal.timeout(n)});return t.ok?null:`GET /v1/models answered HTTP ${t.status}`}catch(t){return`GET /v1/models failed (${String(t instanceof Error?t.message:t)})`}}async function lt(e,n,t=et,r=ut){if(e!=null)return{mode:"spawn",port:e};let o=await Ne(t);if(o!==null&&rn(o,n)){let i=await sn(t,r);return i===null?{mode:"reuse",port:t,identity:o}:{mode:"spawn",port:0,reason:`a urun-openai proxy on port ${t} matches this invocation's identity but failed the serving-surface liveness check (${i}) \u2014 starting a fresh proxy on an ephemeral port instead of pointing the harness at it`}}return{mode:"spawn",port:0}}function pt(e,n=Xe.default.homedir()){return Ve.default.join(n,".urun","logs",`compat-proxy-${e}.log`)}var Pe=["log","info","warn","error","debug","trace"];function ct(e,n=process,t=console){let r=n.stdout.write,o=n.stderr.write,i=(a,...u)=>e.write(a,...u);n.stdout.write=i,n.stderr.write=i;let s=Object.fromEntries(Pe.map(a=>[a,t[a]]));for(let a of Pe)t[a]=(...u)=>{e.write(`${(0,Ze.format)(...u)}
|
|
29
|
+
`)};return()=>{n.stdout.write=r,n.stderr.write=o;for(let a of Pe)t[a]=s[a]}}var an=new Set(["EPIPE","EIO","EBADF","ENXIO"]);function dt(e){let n=e?.code;return typeof n=="string"&&an.has(n)}function he(e,n){try{return e.write(n),!0}catch(t){if(dt(t))return!1;throw t}}function mt(e){let n={stdout:!1,stderr:!1},t=[];for(let r of["stdout","stderr"]){let o=e.streams[r],i=s=>{dt(s)&&(n[r]=!0);let a=s?.code;try{e.note(`${new Date().toISOString()} urun compat: process.${r} died (${String(a??(s instanceof Error?s.message:s))}) \u2014 the terminal is gone; launcher output continues in this log only
|
|
30
|
+
`)}catch{}};o.on("error",i),t.push([o,i])}return{isDead:r=>n[r],uninstall:()=>{for(let[r,o]of t)r.off("error",o)}}}function ft(e){let n=t=>{let r=t instanceof Error?`${t.stack??`${t.name}: ${t.message}`}`:String(t);try{e.appendSync(e.logPath,`${new Date().toISOString()} launcher crashed (in-process proxy): ${r}
|
|
31
|
+
`)}catch{}e.restore();try{e.writeStderr(`urun compat: the in-process proxy crashed (${t instanceof Error?t.message:String(t)}) \u2014 terminating the harness (its backend is gone); details: ${e.logPath}
|
|
32
|
+
`)}catch(o){try{e.appendSync(e.logPath,`${new Date().toISOString()} urun compat: the crash line could not reach stderr (${String(o?.code??o)}) \u2014 the terminal is gone
|
|
33
|
+
`)}catch{}}e.killChild(),e.exit(1)};return e.proc.on("uncaughtException",n),e.proc.on("unhandledRejection",n),()=>{e.proc.off("uncaughtException",n),e.proc.off("unhandledRejection",n)}}function gt(e,n){let t="pass --port 0 for an OS-assigned ephemeral port";return n?`port ${e} is held by another urun-openai proxy serving app ${n.app} (org ${n.org}, fn ${n.fn}, version ${n.proxy_version}) \u2014 reuse it by pointing your agent at http://127.0.0.1:${e}, or ${t}`:`port ${e} is already in use and does not answer the urun-openai /stats identity probe \u2014 ${t}`}function un(e){let n=e?.type;return n==="response.created"||n==="response.in_progress"}function ln(e){let n=e?.type;return n==="response.completed"||n==="error"}function yt(e){return async function(t){return(async function*(){for(let o=1;o<=2;o++){let{app:i,entry:s}=await e.sessionFor(t.model),a=!1,u=!1;try{let c=await e.createStream(s,t);for await(let d of c){if(ln(d)&&(a=!0),un(d)){if(o>1)continue}else u=!0;yield d}}catch(c){if(o<2&&!u){await e.evict(i,s);continue}throw c}if(a)return;if(o<2&&!u){await e.evict(i,s);continue}return}})()}}function ht(e,n,t){let r=e[t];if(typeof r!="function")throw new Error(`app "${n}" has no function "${t}" (set URUN_FUNCTION)`);let o=r();if(typeof o.end!="function")throw new Error(`app "${n}" function "${t}" returned a session without end()`);return o}function _t(e,n){let{baseUrl:t,orgId:r,fnName:o,auth:i}=e;if(i.lane==="jwt"){let d=(0,ie.App)(n,{baseUrl:t,orgId:r,jwt:i.jwt}),w=ht(d,n,o);return{session:w,responses:new ee(w)}}let{apiKey:s,gatewayUrl:a}=i,u=(0,ie.App)(n,{baseUrl:t,orgId:r,getAccessToken:async()=>(await(0,ie.createClientToken)(s,{baseUrl:a,expiresIn:300,allowedFunctions:[`${n}/${o}`]})).token}),c=ht(u,n,o);return{session:c,responses:new ee(c)}}function kt(e){let n=(y.default.env.URUN_CATALOG_URL??"").trim(),t=n?ge(n,"URUN_CATALOG_URL"):"",r=(y.default.env.URUN_CATALOG_ANON_KEY??"").trim();(!t||!r)&&y.default.stderr.write(`urun compat: catalog oracle off (URUN_CATALOG_URL/URUN_CATALOG_ANON_KEY unset) \u2014 an undeployed uRun CATALOG model name falls through to the default app instead of a loud 404; deployed apps still resolve exactly, and /stats.models records every mapping
|
|
34
|
+
`);let o=e.auth,i=new ce({defaultApp:e.appId,fnName:e.fnName,openSession:s=>_t(e,s),closeSession:async s=>{await s.session.end()},listApps:o.lane==="api-key"?()=>qe({apiUrl:e.apiUrl,apiKey:o.apiKey}):null,listCatalog:t&&r?()=>Be({catalogUrl:t,anonKey:r}):null});return i.seed(e.appId,_t(e,e.appId)),i}function vt(e){return{createResponse:yt({sessionFor:n=>e.sessionFor(n),evict:(n,t)=>e.evict(n,t),createStream:(n,t)=>n.responses.responses.create(t)}),listModels:()=>e.modelList()}}async function pn(e,n,t){let r=(0,Te.spawn)(e,n,{stdio:"inherit",env:t});return new Promise(o=>{r.once("exit",i=>o(i??1)),r.once("error",i=>{y.default.stderr.write(`failed to launch ${e}: ${String(i)}
|
|
35
|
+
`),o(127)})})}function cn(){return ot(y.default.env,N,J.existsSync)}function St(e){for(let[n,t]of Object.entries(Oe(e)))y.default.stdout.write(`export ${n}=${t}
|
|
36
|
+
`)}async function wt(e,n){let t=se(y.default.env),r=n?Ue(t):void 0,o=kt(t),i=He({clients:vt(o),identity:r});try{await new Promise((a,u)=>{i.once("error",u),i.listen(e,"127.0.0.1",a)})}catch(a){throw await o.closeAll().catch(()=>{}),a.code==="EADDRINUSE"?new Error(gt(e,await Ne(e))):a}let s=i.address().port;return n&&(y.default.stdout.write(`urun openai proxy listening on http://127.0.0.1:${s}/v1
|
|
37
|
+
`),St(s)),{port:s,close:async()=>{let a=new Promise(u=>i.close(()=>u()));i.closeAllConnections(),await a,await o.closeAll()}}}async function dn(){let e=y.default.argv.slice(2),n=it(e),t=e.shift()??"proxy";if(t==="env")return St(at(n??$e(e))),0;if(t==="proxy"){let o=n??$e(e),i=await wt(o,!0);return await new Promise(s=>{y.default.once("SIGINT",s),y.default.once("SIGTERM",s)}),await i.close(),0}let r=t==="run"?e.shift():t;{if(!r)throw new Error(`launch needs an agent (${Object.keys(ye).join("|")}) or \`-- <cmd>\``);if(r==="pi"){let m=se(y.default.env);return pn("pi",["-e",cn(),...rt(m.appId,e)],y.default.env)}let o,i,s="openai";if(r==="--"){if(o=e.shift()??"",i=e,!o)throw new Error("`-- <cmd>` needs a command to launch")}else{let m=ye[r];if(!m)throw new Error(`unknown command/agent ${r}; commands: proxy | env; agents: ${Object.keys(ye).join(" | ")} \u2014 or \`-- <cmd>\``);o=m.bin,i=[...m.args??[],...e],s=m.env}let a=await lt(n,Ue(se(y.default.env))),u=null,c=a.port;a.mode==="reuse"?y.default.stdout.write(`reusing the running urun openai proxy on http://127.0.0.1:${c} (app ${a.identity.app}, fn ${a.identity.fn}, v${a.identity.proxy_version})
|
|
38
|
+
`):a.reason&&y.default.stderr.write(`urun compat: ${a.reason}
|
|
39
|
+
`);let d=null,w=null,h=null,x=null;a.mode!=="reuse"&&(u=await wt(a.port,!1),c=u.port,x=pt(c),(0,J.mkdirSync)(xt.default.dirname(x),{recursive:!0}),h=(0,J.createWriteStream)(x,{flags:"a"}),w=mt({streams:y.default,note:m=>(0,J.appendFileSync)(x,m)}).uninstall,h.on("error",m=>{d?.(),d=null,he(y.default.stderr,`urun compat: proxy log ${x} failed: ${String(m)} \u2014 proxy output continues on the terminal
|
|
40
|
+
`)}),y.default.stdout.write(`urun openai proxy on http://127.0.0.1:${c}/v1 \u2014 proxy logs: ${x}
|
|
41
|
+
`),d=ct(h)),r==="codex"&&(i=nt(c,se(y.default.env).appId,i));let $=(0,Te.spawn)(o,i,{stdio:"inherit",env:tt(y.default.env,c,s)}),L=x!==null?ft({logPath:x,appendSync:J.appendFileSync,restore:()=>{d?.(),d=null},writeStderr:m=>y.default.stderr.write(m),killChild:()=>$.kill("SIGTERM"),exit:m=>y.default.exit(m),proc:y.default}):null,p=await new Promise(m=>{$.once("exit",I=>m(I??1)),$.once("error",I=>{d?.(),d=null,he(y.default.stderr,`failed to launch ${o}: ${String(I)}
|
|
42
|
+
`),m(127)})});L?.();let A=null;try{u&&await u.close()}catch(m){A=m}finally{d?.(),d=null,w?.(),w=null,h?.end()}return A!==null&&he(y.default.stderr,`urun compat: proxy teardown failed after the harness exited (harness exit code ${p} preserved): ${String(A instanceof Error?A.message:A)}
|
|
43
|
+
`),p}}dn().then(e=>y.default.exit(e),e=>{y.default.stderr.write(`${String(e instanceof Error?e.message:e)}
|
|
44
|
+
`),y.default.exit(1)});0&&(module.exports={buildClients,buildRouter});
|
package/dist/proxy/cli.js
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{a as
|
|
3
|
-
`)};return()=>{
|
|
4
|
-
`);
|
|
5
|
-
`)
|
|
6
|
-
`)}
|
|
7
|
-
`),
|
|
8
|
-
`);let
|
|
9
|
-
`)}),
|
|
10
|
-
`),
|
|
11
|
-
`),
|
|
12
|
-
`)
|
|
13
|
-
`),
|
|
2
|
+
import{a as N}from"../chunk-OLE2YJO3.js";import{a as L}from"../chunk-47ZLHRBM.js";import{c as U}from"../chunk-HQVV5UN5.js";import{a as O,c as $,d as T}from"../chunk-5CEMLB6H.js";import{spawn as ae}from"child_process";import{appendFileSync as te,createWriteStream as Ue,existsSync as be,mkdirSync as Pe}from"fs";import Re from"path";import u from"process";import{App as re,createClientToken as _e}from"@urun-sh/core";import de from"os";import le from"path";import{fileURLToPath as me}from"url";import{format as fe}from"util";var C="0.2.55";var D=4141,he=C,x={claude:{bin:"claude",env:"anthropic"},codex:{bin:"codex",env:"openai"},pi:{bin:"pi",env:"openai"},aider:{bin:"aider",env:"openai"},opencode:{bin:"opencode",env:"openai"},crush:{bin:"crush",env:"openai"}};function R(e,n="openai"){if(n==="anthropic")return{ANTHROPIC_BASE_URL:`http://127.0.0.1:${e}`,ANTHROPIC_API_KEY:"urun-local"};let t=`http://127.0.0.1:${e}/v1`;return{OPENAI_BASE_URL:t,OPENAI_API_BASE:t,OPENAI_API_KEY:"urun-local"}}function M(e,n,t){let r={...e,...R(n,t)};return delete r.URUN_API_KEY,delete r.URUN_JWT,r}function F(e,n,t){let r=["-c","model_providers.urun.name=urun","-c",`model_providers.urun.base_url="http://127.0.0.1:${e}/v1"`,"-c",'model_providers.urun.wire_api="responses"',"-c",'model_provider="urun"'],o=t.indexOf("--"),s=o===-1?t:t.slice(0,o),a=s.some(p=>p==="-m"||p==="--model"||p.startsWith("--model=")),i=t[0]==="exec",c=s.includes("--skip-git-repo-check"),l=i&&!c?["exec","--skip-git-repo-check",...t.slice(1)]:t;return[...r,...a?[]:["-m",n],...l]}function K(e,n){return n.some(r=>r==="--model"||r==="--provider"||r.startsWith("--model=")||r.startsWith("--provider="))?n:["--provider","urun","--model",e,...n]}function Y(e,n,t){let r=(e.URUN_PI_EXTENSION_ENTRY??"").trim();if(r){if(!t(r))throw new Error(`URUN_PI_EXTENSION_ENTRY points at ${r}, which does not exist \u2014 the launcher that injected it (the vendored urun CLI shim) must materialize the pi extension bundle before spawning pi`);return r}let o=me(new URL("../pi-extension/standalone.cjs",n));if(!t(o))throw new Error(`pi extension entry not found at ${o} \u2014 the pi lane loads the self-contained @urun-sh/openai dist/pi-extension/standalone.cjs from the installed package (run \`urun compat pi\` via the npm-installed CLI, e.g. \`npx @urun-sh/openai\`), or pass an entry to pi yourself: \`pi -e <path-to-@urun-sh/openai>/dist/pi-extension/standalone.cjs\``);return o}function W(e){let n=Number(e);if(!Number.isInteger(n)||n<0)throw new Error(`--port needs a non-negative integer (0 = OS-assigned ephemeral), got ${e}`);return n}function J(e){if(e[0]!=="--port")return null;let n=W(e[1]);return e.splice(0,2),n}function _(e){let n=e.indexOf("--port");if(n===-1)return D;let t=W(e[n+1]);return e.splice(n,2),t}function H(e){if(e===0)throw new Error("`env` cannot use --port 0: it starts no proxy, so the OS never assigns the ephemeral port \u2014 pass the actual port of the running proxy");return e}function b(e,n){let t=(e[n]??"").trim();if(!t)throw new Error(`${n} is not set. The proxy needs URUN_BASE_URL, URUN_ORG_ID, URUN_APP and either URUN_API_KEY (the org key; the proxy vends short-lived function-scoped client tokens from it via the SDK) or URUN_JWT (an explicit pre-vended token override) \u2014 plus optional URUN_FUNCTION, default "serve" \u2014 to open the backhaul session.`);return t}function y(e){let n=ye(b(e,"URUN_BASE_URL")),t=b(e,"URUN_ORG_ID"),r=b(e,"URUN_APP"),o=(e.URUN_FUNCTION??"serve").trim()||"serve",s=(e.URUN_API_URL??"").trim(),a=s?w(s,"URUN_API_URL"):O,i=(e.URUN_JWT??"").trim();if(i)return{baseUrl:n,orgId:t,appId:r,fnName:o,apiUrl:a,auth:{lane:"jwt",jwt:i}};let c=(e.URUN_API_KEY??"").trim();if(c){let l=(e.URUN_GATEWAY_URL??"").trim(),p=l?w(l):void 0;return{baseUrl:n,orgId:t,appId:r,fnName:o,apiUrl:a,auth:{lane:"api-key",apiKey:c,gatewayUrl:p}}}throw new Error("neither URUN_API_KEY nor URUN_JWT is set. Set URUN_API_KEY (the org API key \u2014 the proxy vends short-lived, function-scoped client tokens from it via the SDK, so the key never reaches the agent process) or URUN_JWT (an explicit pre-vended token; when set it always wins). URUN_BASE_URL, URUN_ORG_ID and URUN_APP are also required.")}function ye(e,n="URUN_BASE_URL"){if(/\/v1\/*$/.test(new URL(e).pathname))throw new Error(`${n} must be the session-gateway base (e.g. https://api.urun.sh), got ${e} \u2014 a trailing /v1 is the org control-plane API form (that belongs in URUN_API_URL); session allocation 404s against it. Drop the /v1.`);return e}function w(e,n="URUN_GATEWAY_URL"){let t=new URL(e),r=t.hostname==="localhost"||t.hostname==="127.0.0.1"||t.hostname==="[::1]";if(t.protocol!=="https:"&&!r)throw new Error(`${n} must be https (got ${e}) \u2014 the org API key rides the request's Authorization header`);return e}function k(e){return{app:e.appId,org:e.orgId,fn:e.fnName,base_url:e.baseUrl,proxy_version:he}}function ge(e,n){return e.app===n.app&&e.org===n.org&&e.fn===n.fn&&e.base_url===n.base_url&&e.proxy_version===n.proxy_version}var we=250;async function A(e,n=we){try{let t=await fetch(`http://127.0.0.1:${e}/stats`,{signal:AbortSignal.timeout(n)});if(!t.ok)return null;let r=(await t.json()).identity;if(r==null||typeof r!="object")return null;let{app:o,org:s,fn:a,base_url:i,proxy_version:c}=r;return typeof o!="string"||typeof s!="string"||typeof a!="string"||typeof i!="string"||typeof c!="string"?null:{app:o,org:s,fn:a,base_url:i,proxy_version:c}}catch{return null}}var B=2e3;async function xe(e,n=B){try{let t=await fetch(`http://127.0.0.1:${e}/v1/models`,{signal:AbortSignal.timeout(n)});return t.ok?null:`GET /v1/models answered HTTP ${t.status}`}catch(t){return`GET /v1/models failed (${String(t instanceof Error?t.message:t)})`}}async function q(e,n,t=D,r=B){if(e!=null)return{mode:"spawn",port:e};let o=await A(t);if(o!==null&&ge(o,n)){let s=await xe(t,r);return s===null?{mode:"reuse",port:t,identity:o}:{mode:"spawn",port:0,reason:`a urun-openai proxy on port ${t} matches this invocation's identity but failed the serving-surface liveness check (${s}) \u2014 starting a fresh proxy on an ephemeral port instead of pointing the harness at it`}}return{mode:"spawn",port:0}}function V(e,n=de.homedir()){return le.join(n,".urun","logs",`compat-proxy-${e}.log`)}var P=["log","info","warn","error","debug","trace"];function X(e,n=process,t=console){let r=n.stdout.write,o=n.stderr.write,s=(i,...c)=>e.write(i,...c);n.stdout.write=s,n.stderr.write=s;let a=Object.fromEntries(P.map(i=>[i,t[i]]));for(let i of P)t[i]=(...c)=>{e.write(`${fe(...c)}
|
|
3
|
+
`)};return()=>{n.stdout.write=r,n.stderr.write=o;for(let i of P)t[i]=a[i]}}var Ee=new Set(["EPIPE","EIO","EBADF","ENXIO"]);function z(e){let n=e?.code;return typeof n=="string"&&Ee.has(n)}function E(e,n){try{return e.write(n),!0}catch(t){if(z(t))return!1;throw t}}function Q(e){let n={stdout:!1,stderr:!1},t=[];for(let r of["stdout","stderr"]){let o=e.streams[r],s=a=>{z(a)&&(n[r]=!0);let i=a?.code;try{e.note(`${new Date().toISOString()} urun compat: process.${r} died (${String(i??(a instanceof Error?a.message:a))}) \u2014 the terminal is gone; launcher output continues in this log only
|
|
4
|
+
`)}catch{}};o.on("error",s),t.push([o,s])}return{isDead:r=>n[r],uninstall:()=>{for(let[r,o]of t)r.off("error",o)}}}function Z(e){let n=t=>{let r=t instanceof Error?`${t.stack??`${t.name}: ${t.message}`}`:String(t);try{e.appendSync(e.logPath,`${new Date().toISOString()} launcher crashed (in-process proxy): ${r}
|
|
5
|
+
`)}catch{}e.restore();try{e.writeStderr(`urun compat: the in-process proxy crashed (${t instanceof Error?t.message:String(t)}) \u2014 terminating the harness (its backend is gone); details: ${e.logPath}
|
|
6
|
+
`)}catch(o){try{e.appendSync(e.logPath,`${new Date().toISOString()} urun compat: the crash line could not reach stderr (${String(o?.code??o)}) \u2014 the terminal is gone
|
|
7
|
+
`)}catch{}}e.killChild(),e.exit(1)};return e.proc.on("uncaughtException",n),e.proc.on("unhandledRejection",n),()=>{e.proc.off("uncaughtException",n),e.proc.off("unhandledRejection",n)}}function ee(e,n){let t="pass --port 0 for an OS-assigned ephemeral port";return n?`port ${e} is held by another urun-openai proxy serving app ${n.app} (org ${n.org}, fn ${n.fn}, version ${n.proxy_version}) \u2014 reuse it by pointing your agent at http://127.0.0.1:${e}, or ${t}`:`port ${e} is already in use and does not answer the urun-openai /stats identity probe \u2014 ${t}`}function ve(e){let n=e?.type;return n==="response.created"||n==="response.in_progress"}function Se(e){let n=e?.type;return n==="response.completed"||n==="error"}function ne(e){return async function(t){return(async function*(){for(let o=1;o<=2;o++){let{app:s,entry:a}=await e.sessionFor(t.model),i=!1,c=!1;try{let l=await e.createStream(a,t);for await(let p of l){if(Se(p)&&(i=!0),ve(p)){if(o>1)continue}else c=!0;yield p}}catch(l){if(o<2&&!c){await e.evict(s,a);continue}throw l}if(i)return;if(o<2&&!c){await e.evict(s,a);continue}return}})()}}function oe(e,n,t){let r=e[t];if(typeof r!="function")throw new Error(`app "${n}" has no function "${t}" (set URUN_FUNCTION)`);let o=r();if(typeof o.end!="function")throw new Error(`app "${n}" function "${t}" returned a session without end()`);return o}function se(e,n){let{baseUrl:t,orgId:r,fnName:o,auth:s}=e;if(s.lane==="jwt"){let p=re(n,{baseUrl:t,orgId:r,jwt:s.jwt}),f=oe(p,n,o);return{session:f,responses:new U(f)}}let{apiKey:a,gatewayUrl:i}=s,c=re(n,{baseUrl:t,orgId:r,getAccessToken:async()=>(await _e(a,{baseUrl:i,expiresIn:300,allowedFunctions:[`${n}/${o}`]})).token}),l=oe(c,n,o);return{session:l,responses:new U(l)}}function ke(e){let n=(u.env.URUN_CATALOG_URL??"").trim(),t=n?w(n,"URUN_CATALOG_URL"):"",r=(u.env.URUN_CATALOG_ANON_KEY??"").trim();(!t||!r)&&u.stderr.write(`urun compat: catalog oracle off (URUN_CATALOG_URL/URUN_CATALOG_ANON_KEY unset) \u2014 an undeployed uRun CATALOG model name falls through to the default app instead of a loud 404; deployed apps still resolve exactly, and /stats.models records every mapping
|
|
8
|
+
`);let o=e.auth,s=new T({defaultApp:e.appId,fnName:e.fnName,openSession:a=>se(e,a),closeSession:async a=>{await a.session.end()},listApps:o.lane==="api-key"?()=>$({apiUrl:e.apiUrl,apiKey:o.apiKey}):null,listCatalog:t&&r?()=>N({catalogUrl:t,anonKey:r}):null});return s.seed(e.appId,se(e,e.appId)),s}function Ae(e){return{createResponse:ne({sessionFor:n=>e.sessionFor(n),evict:(n,t)=>e.evict(n,t),createStream:(n,t)=>n.responses.responses.create(t)}),listModels:()=>e.modelList()}}async function Ie(e,n,t){let r=ae(e,n,{stdio:"inherit",env:t});return new Promise(o=>{r.once("exit",s=>o(s??1)),r.once("error",s=>{u.stderr.write(`failed to launch ${e}: ${String(s)}
|
|
9
|
+
`),o(127)})})}function Ne(){return Y(u.env,import.meta.url,be)}function ue(e){for(let[n,t]of Object.entries(R(e)))u.stdout.write(`export ${n}=${t}
|
|
10
|
+
`)}async function ie(e,n){let t=y(u.env),r=n?k(t):void 0,o=ke(t),s=L({clients:Ae(o),identity:r});try{await new Promise((i,c)=>{s.once("error",c),s.listen(e,"127.0.0.1",i)})}catch(i){throw await o.closeAll().catch(()=>{}),i.code==="EADDRINUSE"?new Error(ee(e,await A(e))):i}let a=s.address().port;return n&&(u.stdout.write(`urun openai proxy listening on http://127.0.0.1:${a}/v1
|
|
11
|
+
`),ue(a)),{port:a,close:async()=>{let i=new Promise(c=>s.close(()=>c()));s.closeAllConnections(),await i,await o.closeAll()}}}async function Oe(){let e=u.argv.slice(2),n=J(e),t=e.shift()??"proxy";if(t==="env")return ue(H(n??_(e))),0;if(t==="proxy"){let o=n??_(e),s=await ie(o,!0);return await new Promise(a=>{u.once("SIGINT",a),u.once("SIGTERM",a)}),await s.close(),0}let r=t==="run"?e.shift():t;{if(!r)throw new Error(`launch needs an agent (${Object.keys(x).join("|")}) or \`-- <cmd>\``);if(r==="pi"){let d=y(u.env);return Ie("pi",["-e",Ne(),...K(d.appId,e)],u.env)}let o,s,a="openai";if(r==="--"){if(o=e.shift()??"",s=e,!o)throw new Error("`-- <cmd>` needs a command to launch")}else{let d=x[r];if(!d)throw new Error(`unknown command/agent ${r}; commands: proxy | env; agents: ${Object.keys(x).join(" | ")} \u2014 or \`-- <cmd>\``);o=d.bin,s=[...d.args??[],...e],a=d.env}let i=await q(n,k(y(u.env))),c=null,l=i.port;i.mode==="reuse"?u.stdout.write(`reusing the running urun openai proxy on http://127.0.0.1:${l} (app ${i.identity.app}, fn ${i.identity.fn}, v${i.identity.proxy_version})
|
|
12
|
+
`):i.reason&&u.stderr.write(`urun compat: ${i.reason}
|
|
13
|
+
`);let p=null,f=null,g=null,m=null;i.mode!=="reuse"&&(c=await ie(i.port,!1),l=c.port,m=V(l),Pe(Re.dirname(m),{recursive:!0}),g=Ue(m,{flags:"a"}),f=Q({streams:u,note:d=>te(m,d)}).uninstall,g.on("error",d=>{p?.(),p=null,E(u.stderr,`urun compat: proxy log ${m} failed: ${String(d)} \u2014 proxy output continues on the terminal
|
|
14
|
+
`)}),u.stdout.write(`urun openai proxy on http://127.0.0.1:${l}/v1 \u2014 proxy logs: ${m}
|
|
15
|
+
`),p=X(g)),r==="codex"&&(s=F(l,y(u.env).appId,s));let v=ae(o,s,{stdio:"inherit",env:M(u.env,l,a)}),ce=m!==null?Z({logPath:m,appendSync:te,restore:()=>{p?.(),p=null},writeStderr:d=>u.stderr.write(d),killChild:()=>v.kill("SIGTERM"),exit:d=>u.exit(d),proc:u}):null,I=await new Promise(d=>{v.once("exit",S=>d(S??1)),v.once("error",S=>{p?.(),p=null,E(u.stderr,`failed to launch ${o}: ${String(S)}
|
|
16
|
+
`),d(127)})});ce?.();let h=null;try{c&&await c.close()}catch(d){h=d}finally{p?.(),p=null,f?.(),f=null,g?.end()}return h!==null&&E(u.stderr,`urun compat: proxy teardown failed after the harness exited (harness exit code ${I} preserved): ${String(h instanceof Error?h.message:h)}
|
|
17
|
+
`),I}}Oe().then(e=>u.exit(e),e=>{u.stderr.write(`${String(e instanceof Error?e.message:e)}
|
|
18
|
+
`),u.exit(1)});export{Ae as buildClients,ke as buildRouter};
|
package/dist/proxy/index.cjs
CHANGED
|
@@ -1,21 +1,27 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
data: ${JSON.stringify(
|
|
1
|
+
"use strict";var it=Object.defineProperty;var xt=Object.getOwnPropertyDescriptor;var vt=Object.getOwnPropertyNames;var At=Object.prototype.hasOwnProperty;var Rt=(t,n)=>{for(var e in n)it(t,e,{get:n[e],enumerable:!0})},St=(t,n,e,o)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of vt(n))!At.call(t,r)&&r!==e&&it(t,r,{get:()=>n[r],enumerable:!(o=xt(n,r))||o.enumerable});return t};var It=t=>St(it({},"__esModule",{value:!0}),t);var Ut={};Rt(Ut,{createOpenAIProxy:()=>kt});module.exports=It(Ut);var ht=require("http");var D=class extends Error{};var ut=class t{startedAt=Date.now();requests={};models={};ttftMs=[];tokRates=[];tokensOut=0;charsOut=0;localInBytes=0;naiveInBytes=0;request(n,e,o){this.requests[n]=(this.requests[n]??0)+1,this.localInBytes+=e,this.naiveInBytes+=o}modelEntry(n){let e=this.models[n];if(e)return e;let o=Object.keys(this.models).length>=Ot?"(other)":n;return this.models[o]??={requests:0,tokens_out:0}}model(n){this.modelEntry(n).requests+=1}track(n,e){let o=this,r=performance.now(),p=null,l=0;return(async function*(){for await(let d of n)d.type==="response.output_text.delta"&&typeof d.delta=="string"&&(p===null&&(p=performance.now(),o.ttftMs.push(p-r),o.ttftMs.length>512&&o.ttftMs.shift()),l+=1,o.tokensOut+=1,o.charsOut+=d.delta.length,e!==void 0&&(o.modelEntry(e).tokens_out+=1)),yield d;let a=(performance.now()-(p??r))/1e3;l>0&&a>0&&(o.tokRates.push(l/a),o.tokRates.length>512&&o.tokRates.shift())})()}static p50(n){if(!n.length)return null;let e=[...n].sort((o,r)=>o-r);return e[Math.floor(e.length/2)]}snapshot(){let n=Object.values(this.requests).reduce((e,o)=>e+o,0);return{uptime_s:Math.round((Date.now()-this.startedAt)/1e3),requests:this.requests,models:this.models,tokens_out:this.tokensOut,chars_out:this.charsOut,ttft_ms:{p50:t.p50(this.ttftMs),last:this.ttftMs.at(-1)??null},tok_per_s:{p50:t.p50(this.tokRates),last:this.tokRates.at(-1)??null},traffic:{local_request_bytes:this.localInBytes,naive_baseline:{request_bytes:this.naiveInBytes,connections:n},persistent_connections:1,history_bytes_saved:Math.max(0,this.naiveInBytes-this.localInBytes),history_bytes_saved_pct:this.naiveInBytes>0?Math.round((1-this.localInBytes/this.naiveInBytes)*1e3)/10:null}}}};function ct(t){t.writeHead(200,{"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive"})}function B(t,n,e){t.writeHead(n,{"content-type":"application/json"}),t.end(JSON.stringify(e))}function k(t,n,e,o="invalid_request_error"){B(t,n,{error:{message:e,type:o}})}function dt(t,n,e){if(n==="anthropic"){B(t,404,{type:"error",error:{type:"not_found_error",message:e.message}});return}B(t,404,{error:{message:e.message,type:"invalid_request_error",code:"model_not_found"}})}var Ot=256,bt=128;function ft(t){return typeof t.model!="string"||!t.model.trim()?"(default)":t.model.trim().slice(0,bt)}var yt=64*1024*1024,nt=class extends Error{};async function $t(t){let n=[],e=0;for await(let r of t){if(e+=r.length,e>yt)throw new nt(`request body exceeds ${yt} bytes`);n.push(r)}let o=Buffer.concat(n).toString("utf8");return o?JSON.parse(o):{}}function z(t,n,e,o){return{id:t,object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:n,choices:[{index:0,delta:e,finish_reason:o}]}}var Et=256;function Ct(t){if(typeof t=="string")return[{role:"user",content:t}];if(Array.isArray(t))return t;throw new Error("responses input must be a string or an array of messages/items")}var pt=class{conversations=new Map;thread(n,e){let o=Ct(e);if(n==null)return o;let r=this.conversations.get(String(n));if(!r)throw new Error(`unknown previous_response_id ${String(n)} (proxy restarts drop stored responses)`);return[...r,...o]}remember(n,e,o){this.conversations.set(n,[...e,{role:"assistant",content:o}]);for(let r of this.conversations.keys()){if(this.conversations.size<=Et)break;this.conversations.delete(r)}}};function V(t){let n=t?.output;return Array.isArray(n)?n.filter(e=>e.type==="function_call"):[]}function Q(t){return t.find(n=>n.type==="response.completed")?.response??null}function wt(t){let n=t?.output;if(!Array.isArray(n))return"";let e="";for(let o of n)if(!(o.type!=="reasoning"||!Array.isArray(o.content)))for(let r of o.content)r.type==="reasoning_text"&&(e+=String(r.text??""));return e}function Z(t){return t.type!=="response.function_call_arguments.delta"||typeof t.tool_index!="number"?null:{tool_index:t.tool_index,call_id:typeof t.call_id=="string"?t.call_id:void 0,name:typeof t.name=="string"?t.name:void 0,delta:typeof t.delta=="string"?t.delta:""}}var F=class{calls=new Map;add(n){let e=this.calls.get(n.tool_index),o=!e;return e||(e={args:""},this.calls.set(n.tool_index,e)),n.call_id&&(e.id=n.call_id),n.name&&(e.name=n.name),e.args+=n.delta,{call:e,isNew:o}}get size(){return this.calls.size}items(){return[...this.calls.entries()].map(([n,e])=>({type:"function_call",call_id:e.id??`call_${n}`,name:e.name??"",arguments:e.args}))}},Pt=["<tool_call>","<function="];function Mt(t){return Pt.find(n=>t.includes(n))}function L(t,n){return`serving row emitted a prose tool call (literal ${JSON.stringify(n)} in the assistant text) for a request that carried tools, and no structured tool_calls arrived \u2014 the tool-call parser is not configured on the model row "${t}" (see catalog parser_defaults)`}function K(t,n,e){if(!(!t||n>0))return Mt(e)}function Tt(t){if(Array.isArray(t))return t.map(n=>{let e=n.function;return!e||typeof e!="object"?n:{type:"function",name:e.name,description:e.description,parameters:e.parameters,strict:e.strict}})}var ot=class extends Error{};function Nt(t,n){return Array.isArray(n)?n.map(e=>{let o=e;if(o.type==="text")return{type:t==="assistant"?"output_text":"input_text",text:o.text};if(o.type==="image_url"){let r=o.image_url??{};return{type:"input_image",image_url:r.url,detail:r.detail}}throw new ot(`unsupported chat content part type "${String(o.type)}" \u2014 the proxy translates text and image_url parts`)}):n}function Bt(t){let n=[];for(let e of t){if(e.role==="tool"){n.push({type:"function_call_output",call_id:e.tool_call_id,output:typeof e.content=="string"?e.content:JSON.stringify(e.content??"")});continue}if(e.role==="assistant"&&Array.isArray(e.tool_calls)){typeof e.content=="string"&&e.content&&n.push({role:"assistant",content:e.content});for(let o of e.tool_calls){let r=o.function??{};n.push({type:"function_call",call_id:o.id,name:r.name,arguments:r.arguments})}continue}n.push({...e,content:Nt(e.role,e.content)})}return n}function at(t){return V(t).map((n,e)=>({index:e,id:n.call_id??n.id??`call_${e}`,type:"function",function:{name:n.name??"",arguments:n.arguments??"{}"}}))}function _t(t,n){let e=n?.output_text;return typeof e=="string"?e:t.filter(o=>o.type==="response.output_text.delta"&&typeof o.delta=="string").map(o=>o.delta).join("")}async function Jt(t,n,e,o,r){let p=t.stream===!0,l;try{l=e.thread(t.previous_response_id,t.input)}catch(i){k(o,400,String(i instanceof Error?i.message:i));return}t.previous_response_id!=null&&(r.naiveInBytes+=Buffer.byteLength(JSON.stringify(l))-Buffer.byteLength(JSON.stringify(t.input)));let a=`resp_${Math.random().toString(36).slice(2,14)}`,d=t.store!==!1,y=ft(t);r.model(y);let A=Array.isArray(t.tools)&&t.tools.length>0,R;try{R=await n.createResponse({model:t.model,input:l,stream:p,tools:t.tools,tool_choice:t.tool_choice,temperature:t.temperature,max_output_tokens:t.max_output_tokens})}catch(i){if(i instanceof D){dt(o,"openai",i);return}throw i}let f=[];if(p){ct(o);let i=c=>{o.write(`event: ${String(c.type??"message")}
|
|
2
|
+
data: ${JSON.stringify(c)}
|
|
3
3
|
|
|
4
|
-
`)},
|
|
4
|
+
`)},P=c=>c.response&&typeof c.response=="object"?{...c,response:{...c.response,id:a}}:c,v=`item_${a.slice(5)}`,$=`rs_${a.slice(5)}`,b=!1,E=!1,s=0,g=()=>{b||(b=!0,i({type:"response.created",response:{id:a,object:"response",status:"in_progress"}}))},M=!1,S=0,C="",T=()=>{M&&(M=!1,i({type:"response.reasoning_text.done",item_id:$,output_index:S,content_index:0,text:C}),i({type:"response.output_item.done",output_index:S,item:{id:$,type:"reasoning",summary:[],content:[{type:"reasoning_text",text:C}],status:"completed"}}))},m=!1,x=0,O="",q=c=>{m&&(m=!1,i({type:"response.output_text.done",item_id:v,output_index:x,content_index:0,text:O}),i({type:"response.content_part.done",item_id:v,output_index:x,content_index:0,part:{type:"output_text",text:O}}),i({type:"response.output_item.done",output_index:x,item:{id:v,type:"message",role:"assistant",status:c,content:[{type:"output_text",text:O}]}}))},N=new F,_=null,U=-1,G=c=>{if(!_)return;let h=_;_=null,i({type:"response.function_call_arguments.done",item_id:h.fcId,output_index:h.outputIndex,arguments:h.args}),i({type:"response.output_item.done",output_index:h.outputIndex,item:{id:h.fcId,type:"function_call",call_id:h.callId??h.fcId,name:h.name??"",arguments:h.args,status:c}})},H=!1;for await(let c of r.track(R,y)){f.push(c);let h=String(c.type??"");if(h==="response.created"||h==="response.in_progress"){b=!0,i(P(c));continue}if(h==="response.output_item.added"){E=!0,i(P(c));continue}if(h==="response.reasoning_text.delta"&&!E){g(),M||(M=!0,S=s++,i({type:"response.output_item.added",output_index:S,item:{id:$,type:"reasoning",summary:[],content:[],status:"in_progress"}})),C+=String(c.delta??""),i({type:"response.reasoning_text.delta",item_id:$,output_index:S,content_index:0,delta:c.delta});continue}if(h==="response.output_text.delta"&&!E){g(),T(),m||(m=!0,x=s++,i({type:"response.output_item.added",output_index:x,item:{id:v,type:"message",role:"assistant",status:"in_progress",content:[]}}),i({type:"response.content_part.added",item_id:v,output_index:x,content_index:0,part:{type:"output_text",text:""}})),O+=String(c.delta??""),i({type:h,item_id:v,output_index:x,content_index:0,delta:c.delta});continue}let u=E?null:Z(c);if(u){if(g(),T(),q("completed"),N.add(u),u.tool_index!==U){G("completed"),U=u.tool_index;let w=s++;_={fcId:`fc_${a.slice(5)}_${u.tool_index}`,outputIndex:w,callId:u.call_id,name:u.name,args:""},i({type:"response.output_item.added",output_index:w,item:{id:_.fcId,type:"function_call",call_id:_.callId??_.fcId,name:_.name??"",arguments:"",status:"in_progress"}})}_&&(u.call_id&&(_.callId=u.call_id),u.name&&(_.name=u.name),_.args+=u.delta,i({type:"response.function_call_arguments.delta",item_id:_.fcId,output_index:_.outputIndex,delta:u.delta}));continue}if(h==="response.completed"&&!E){let w=V(c.response),X=K(A,N.size+w.length,O);if(X){H=!0,i({type:"error",error:{type:"urun_error",code:"tool_call_parser_missing",message:L(y,X)}});break}T(),q("completed"),G("completed"),N.size===0&&w.forEach(Y=>{let W=s++,et=Y.id??Y.call_id??`fc_${W}`,rt=Y.arguments??"",mt={id:et,type:"function_call",call_id:Y.call_id??et,name:Y.name??""};i({type:"response.output_item.added",output_index:W,item:{...mt,arguments:"",status:"in_progress"}}),i({type:"response.function_call_arguments.delta",item_id:et,output_index:W,delta:rt}),i({type:"response.function_call_arguments.done",item_id:et,output_index:W,arguments:rt}),i({type:"response.output_item.done",output_index:W,item:{...mt,arguments:rt,status:"completed"}})}),i(P(c));continue}i(P(c))}T(),q("incomplete"),G("incomplete"),d&&!H&&e.remember(a,l,_t(f,Q(f))),o.write(`data: [DONE]
|
|
5
5
|
|
|
6
|
-
`),
|
|
6
|
+
`),o.end();return}let I=null;for await(let i of r.track(R,y)){if(f.push(i),i.type==="error"){k(o,502,JSON.stringify(i),"upstream_error");return}i.type==="response.completed"&&(I=i.response)}if(I==null){k(o,502,"upstream produced no response.completed event","upstream_error");return}let J=_t(f,I),j=K(A,V(I).length,J);if(j){k(o,502,L(y,j),"upstream_error");return}d&&e.remember(a,l,J),B(o,200,{...I,id:a})}async function jt(t,n,e,o){let r=t.messages;if(!Array.isArray(r)){k(e,400,"chat/completions requires a messages array");return}let p=String(t.model??"urun"),l=`chatcmpl-${Math.random().toString(36).slice(2,14)}`,a;try{a=Bt(r)}catch(s){if(s instanceof ot){k(e,400,s.message);return}throw s}let d=ft(t);o.model(d);let y=Array.isArray(t.tools)&&t.tools.length>0,A;try{A=await n.createResponse({model:t.model,input:a,stream:!0,tools:Tt(t.tools),tool_choice:t.tool_choice,temperature:t.temperature,max_output_tokens:t.max_completion_tokens??t.max_tokens})}catch(s){if(s instanceof D){dt(e,"openai",s);return}throw s}if(t.stream===!0){ct(e);let s=[],g=new F,M="";e.write(`data: ${JSON.stringify(z(l,p,{role:"assistant"},null))}
|
|
7
7
|
|
|
8
|
-
`);for await(let m of
|
|
8
|
+
`);for await(let m of o.track(A,d)){s.push(m);let x=Z(m);if(m.type==="response.output_text.delta"&&typeof m.delta=="string")M+=m.delta,e.write(`data: ${JSON.stringify(z(l,p,{content:m.delta},null))}
|
|
9
9
|
|
|
10
|
-
`);else if(m.type==="
|
|
10
|
+
`);else if(m.type==="response.reasoning_text.delta"&&typeof m.delta=="string")e.write(`data: ${JSON.stringify(z(l,p,{reasoning_content:m.delta},null))}
|
|
11
11
|
|
|
12
|
-
`),
|
|
12
|
+
`);else if(x){let{call:O,isNew:q}=g.add(x),N=q?{index:x.tool_index,id:O.id??`call_${x.tool_index}`,type:"function",function:{name:O.name??"",arguments:x.delta}}:{index:x.tool_index,function:{arguments:x.delta}};e.write(`data: ${JSON.stringify(z(l,p,{tool_calls:[N]},null))}
|
|
13
13
|
|
|
14
|
-
`)
|
|
14
|
+
`)}else if(m.type==="error"){e.write(`data: ${JSON.stringify({error:m})}
|
|
15
15
|
|
|
16
|
-
`),
|
|
16
|
+
`),e.end();return}}let S=at(Q(s)),C=K(y,g.size+S.length,M);if(C){e.write(`data: ${JSON.stringify({error:{type:"urun_error",code:"tool_call_parser_missing",message:L(d,C)}})}
|
|
17
17
|
|
|
18
|
-
`),
|
|
19
|
-
data: ${JSON.stringify({type:a,...m})}
|
|
18
|
+
`),e.end();return}g.size===0&&S.length>0&&e.write(`data: ${JSON.stringify(z(l,p,{tool_calls:S},null))}
|
|
20
19
|
|
|
21
|
-
`)
|
|
20
|
+
`);let T=g.size>0||S.length>0;e.write(`data: ${JSON.stringify(z(l,p,{},T?"tool_calls":"stop"))}
|
|
21
|
+
|
|
22
|
+
`),e.write(`data: [DONE]
|
|
23
|
+
|
|
24
|
+
`),e.end();return}let R="",f="",I=[],J=new F;for await(let s of o.track(A,d)){I.push(s),s.type==="response.output_text.delta"&&typeof s.delta=="string"&&(R+=s.delta),s.type==="response.reasoning_text.delta"&&typeof s.delta=="string"&&(f+=s.delta);let g=Z(s);if(g&&J.add(g),s.type==="error"){k(e,502,JSON.stringify(s),"upstream_error");return}}let j=Q(I),i=at(j),P=i.length>0?i:at({output:J.items()}),v=K(y,P.length,R);if(v){k(e,502,L(d,v),"upstream_error");return}let $=P.map(({index:s,...g})=>g),b={role:"assistant",content:R||null},E=f||wt(j);E&&(b.reasoning_content=E),$.length>0&&(b.tool_calls=$),B(e,200,{id:l,object:"chat.completion",created:Math.floor(Date.now()/1e3),model:p,choices:[{index:0,message:b,finish_reason:$.length>0?"tool_calls":"stop"}],usage:{prompt_tokens:0,completion_tokens:0,total_tokens:0}})}function qt(t){return typeof t=="string"?t:Array.isArray(t)?t.filter(n=>n.type==="text").map(n=>String(n.text??"")).join(""):""}var tt=class extends Error{};function st(t){return new tt(`unsupported anthropic content block type "${t}" \u2014 the proxy translates text, tool_use and tool_result blocks`)}function Dt(t){if(Array.isArray(t))return t.map(n=>{let e=n;return{type:"function",name:e.name,description:e.description,parameters:e.input_schema}})}function Ft(t){if(t==null)return;let n=t.type;if(n==="auto")return"auto";if(n==="none")return"none";if(n==="any")return"required";if(n==="tool")return{type:"function",name:t.name};throw new tt(`unsupported anthropic tool_choice type ${JSON.stringify(String(n))} \u2014 the proxy maps auto, none, any and tool`)}function zt(t){if(typeof t=="string")return t;if(t==null)return"";if(!Array.isArray(t))throw st(typeof t);let n="";for(let e of t){let o=String(e.type??"");if(o!=="text")throw st(`tool_result > ${o}`);n+=String(e.text??"")}return n}function Lt(t){let{role:n,content:e}=t;if(typeof e=="string")return[{role:n,content:e}];if(e==null)return[];if(!Array.isArray(e))throw st(typeof e);let o=[],r="",p=()=>{r&&(o.push({role:n,content:r}),r="")};for(let l of e){let a=String(l.type??"");if(a==="text")r+=String(l.text??"");else if(a==="tool_use")p(),o.push({type:"function_call",call_id:l.id,name:l.name,arguments:JSON.stringify(l.input??{})});else if(a==="tool_result")p(),o.push({type:"function_call_output",call_id:l.tool_use_id,output:zt(l.content)});else{if(a==="thinking"||a==="redacted_thinking")continue;throw st(a)}}return p(),o}function lt(t){return V(t).map((n,e)=>{let o;try{o=JSON.parse(n.arguments||"{}")}catch{throw new Error(`upstream function_call "${n.name??""}" arguments are not valid JSON`)}return{type:"tool_use",id:n.call_id??n.id??`toolu_${e}`,name:n.name??"",input:o}})}async function Kt(t,n,e,o){let r=t.messages;if(!Array.isArray(r)){k(e,400,"messages requires a messages array");return}let p=String(t.model??"urun"),l=`msg_${Math.random().toString(36).slice(2,14)}`,a=[],d;try{t.system&&a.push({role:"system",content:qt(t.system)});for(let s of r)a.push(...Lt(s));d=Ft(t.tool_choice)}catch(s){if(s instanceof tt){k(e,400,s.message);return}throw s}let y=ft(t);o.model(y);let A=Array.isArray(t.tools)&&t.tools.length>0,R;try{R=await n.createResponse({model:t.model,input:a,stream:!0,tools:Dt(t.tools),tool_choice:d,temperature:t.temperature,max_output_tokens:t.max_tokens})}catch(s){if(s instanceof D){dt(e,"anthropic",s);return}throw s}let f=(s,g)=>{e.write(`event: ${s}
|
|
25
|
+
data: ${JSON.stringify({type:s,...g})}
|
|
26
|
+
|
|
27
|
+
`)};if(t.stream===!0){let s=o.track(R,y);ct(e),f("message_start",{message:{id:l,type:"message",role:"assistant",content:[],model:p,stop_reason:null,usage:{input_tokens:0,output_tokens:0}}});let g=0,M="",S=0,C="none",T=()=>C,m=-1,x=-1,O=new F,q=[],N=()=>{C!=="none"&&(C="none",f("content_block_stop",{index:m}))},_=(u,w)=>{N(),C=u,m=S++,f("content_block_start",{index:m,content_block:w})};for await(let u of s){q.push(u);let w=Z(u);if(u.type==="response.reasoning_text.delta"&&typeof u.delta=="string")T()!=="thinking"&&_("thinking",{type:"thinking",thinking:""}),f("content_block_delta",{index:m,delta:{type:"thinking_delta",thinking:u.delta}});else if(u.type==="response.output_text.delta"&&typeof u.delta=="string")T()!=="text"&&_("text",{type:"text",text:""}),g+=1,M+=u.delta,f("content_block_delta",{index:m,delta:{type:"text_delta",text:u.delta}});else if(w){let{call:X}=O.add(w);(T()!=="tool"||w.tool_index!==x)&&(x=w.tool_index,_("tool",{type:"tool_use",id:X.id??`call_${w.tool_index}`,name:X.name??"",input:{}})),w.delta&&f("content_block_delta",{index:m,delta:{type:"input_json_delta",partial_json:w.delta}})}else if(u.type==="error"){f("error",{error:{type:"api_error",message:JSON.stringify(u)}}),e.end();return}}let U=Q(q),G=V(U),H=K(A,O.size+G.length,M);if(H){f("error",{error:{type:"api_error",message:L(y,H)}}),e.end();return}N();let c=[];if(O.size===0)try{c=lt(U)}catch(u){f("error",{error:{type:"api_error",message:String(u instanceof Error?u.message:u)}}),e.end();return}S===0&&c.length===0&&(_("text",{type:"text",text:""}),N()),c.forEach(u=>{let w=S++;f("content_block_start",{index:w,content_block:{...u,input:{}}}),f("content_block_delta",{index:w,delta:{type:"input_json_delta",partial_json:JSON.stringify(u.input??{})}}),f("content_block_stop",{index:w})});let h=O.size>0||c.length>0;f("message_delta",{delta:{stop_reason:h?"tool_use":"end_turn"},usage:{output_tokens:g}}),f("message_stop",{}),e.end();return}let I="",J="",j=[],i=new F;for await(let s of o.track(R,y)){j.push(s),s.type==="response.output_text.delta"&&typeof s.delta=="string"&&(I+=s.delta),s.type==="response.reasoning_text.delta"&&typeof s.delta=="string"&&(J+=s.delta);let g=Z(s);if(g&&i.add(g),s.type==="error"){k(e,502,JSON.stringify(s),"upstream_error");return}}let P=Q(j),v;try{v=lt(P),v.length===0&&i.size>0&&(v=lt({output:i.items()}))}catch(s){k(e,502,String(s instanceof Error?s.message:s),"upstream_error");return}let $=K(A,v.length,I);if($){k(e,502,L(y,$),"upstream_error");return}let b=[],E=J||wt(P);E&&b.push({type:"thinking",thinking:E}),(I||v.length===0)&&b.push({type:"text",text:I}),b.push(...v),B(e,200,{id:l,type:"message",role:"assistant",content:b,model:p,stop_reason:v.length>0?"tool_use":"end_turn",usage:{input_tokens:0,output_tokens:0}})}function kt(t){let{clients:n,apiKey:e,identity:o}=t,r=new pt,p=new ut;return(0,ht.createServer)((l,a)=>{(async()=>{let d=new URL(l.url??"/","http://localhost");if(l.method==="GET"&&d.pathname==="/healthz"){B(a,200,{ok:!0});return}if(l.method==="GET"&&d.pathname==="/stats"){B(a,200,o?{identity:o,...p.snapshot()}:p.snapshot());return}if(e&&(l.headers.authorization??"")!==`Bearer ${e}`){k(a,401,"invalid local proxy api key","authentication_error");return}if(l.method==="GET"&&d.pathname==="/v1/models"){B(a,200,await n.listModels());return}if(l.method!=="POST"){k(a,404,`no route for ${l.method} ${d.pathname}`);return}let y;try{y=await $t(l)}catch(R){if(R instanceof nt){k(a,413,R.message,"request_too_large");return}k(a,400,"request body is not valid JSON");return}let A=Buffer.byteLength(JSON.stringify(y));if(d.pathname==="/v1/responses"){p.request("responses",A,A),await Jt(y,n,r,a,p);return}if(d.pathname==="/v1/chat/completions"){p.request("chat_completions",A,A),await jt(y,n,a,p);return}if(d.pathname==="/v1/messages"){p.request("messages",A,A),await Kt(y,n,a,p);return}k(a,404,`no route for POST ${d.pathname}`)})().catch(d=>{a.headersSent?a.end():k(a,500,String(d),"proxy_error")})})}0&&(module.exports={createOpenAIProxy});
|
package/dist/proxy/index.d.cts
CHANGED
package/dist/proxy/index.d.ts
CHANGED
package/dist/proxy/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e}from"../chunk-
|
|
1
|
+
import{a as e}from"../chunk-47ZLHRBM.js";import"../chunk-5CEMLB6H.js";export{e as createOpenAIProxy};
|