@urun-sh/openai 0.2.49 → 0.2.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,26 +1,26 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var pe=Object.create;var x=Object.defineProperty;var le=Object.getOwnPropertyDescriptor;var de=Object.getOwnPropertyNames;var me=Object.getPrototypeOf,fe=Object.prototype.hasOwnProperty;var ge=(e,n)=>{for(var t in n)x(e,t,{get:n[t],enumerable:!0})},j=(e,n,t,r)=>{if(n&&typeof n=="object"||typeof n=="function")for(let o of de(n))!fe.call(e,o)&&o!==t&&x(e,o,{get:()=>n[o],enumerable:!(r=le(n,o))||r.enumerable});return e};var ye=(e,n,t)=>(t=e!=null?pe(me(e)):{},j(n||!e||!e.__esModule?x(t,"default",{value:e,enumerable:!0}):t,e)),_e=e=>j(x({},"__esModule",{value:!0}),e);var Me={};ge(Me,{buildClients:()=>ae,resolveSessionFromEnv:()=>ie});module.exports=_e(Me);var se=require("child_process"),m=ye(require("process"),1),R=require("@urun-sh/core");function q(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 G(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 D(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 he="llm-resp";async function*P(e,n){let t=`${he}:${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 D(s);return}}}var we="llm",A=class{constructor(n){this.session=n}session;get consumerId(){return this.session.consumerId}write(n){this.session.doc(we).set({requests:{[n.request_id]:{payload:n,consumer_id:n.consumer_id,stream:n.stream}}})}sendResponses(n,t){let r=G(n,t,this.consumerId);return this.write(r),P(this.session,t)}sendResponseCreate(n,t,r){let o=q(n,t,r,this.consumerId);return this.write(o),P(this.session,r)}};var K=0;function ke(){return K+=1,`req_${Date.now().toString(36)}_${K.toString(36)}`}var S=class{transport;constructor(n){this.transport=new A(n)}responses={create:async n=>{let t=ke(),r=this.transport.sendResponses(n,t);return Object.assign((async function*(){yield*r})(),{requestId:t})}}};async function F(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{object:"list",data:(await t.json()).map(o=>({id:`${o.model_id}:${o.variant}`,object:"model",created:0,owned_by:"urun"}))}}var X=require("http"),$=class e{startedAt=Date.now();requests={};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}track(n){let t=this,r=performance.now(),o=null,s=0;return(async function*(){for await(let a of n)a.type==="response.output_text.delta"&&typeof a.delta=="string"&&(o===null&&(o=performance.now(),t.ttftMs.push(o-r),t.ttftMs.length>512&&t.ttftMs.shift()),s+=1,t.tokensOut+=1,t.charsOut+=a.delta.length),yield a;let i=(performance.now()-(o??r))/1e3;s>0&&i>0&&(t.tokRates.push(s/i),t.tokRates.length>512&&t.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,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 L(e){e.writeHead(200,{"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive"})}function w(e,n,t){e.writeHead(n,{"content-type":"application/json"}),e.end(JSON.stringify(t))}function g(e,n,t,r="invalid_request_error"){w(e,n,{error:{message:t,type:r}})}var Y=64*1024*1024,E=class extends Error{};async function ve(e){let n=[],t=0;for await(let o of e){if(t+=o.length,t>Y)throw new E(`request body exceeds ${Y} bytes`);n.push(o)}let r=Buffer.concat(n).toString("utf8");return r?JSON.parse(r):{}}function b(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 Re=256;function xe(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 T=class{conversations=new Map;thread(n,t){let r=xe(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<=Re)break;this.conversations.delete(o)}}};function V(e){let n=e?.output;return Array.isArray(n)?n.filter(t=>t.type==="function_call"):[]}function v(e){return e.find(n=>n.type==="response.completed")?.response??null}function Ae(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 O=class extends Error{};function Se(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 O(`unsupported chat content part type "${String(r.type)}" \u2014 the proxy translates text and image_url parts`)}):n}function be(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:Se(t.role,t.content)})}return n}function z(e){return V(e).map((n,t)=>({index:t,id:n.call_id??n.id??`call_${t}`,type:"function",function:{name:n.name??"",arguments:n.arguments??"{}"}}))}function W(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 Ee(e,n,t,r,o){let s=e.stream===!0,i;try{i=t.thread(e.previous_response_id,e.input)}catch(u){g(r,400,String(u instanceof Error?u.message:u));return}e.previous_response_id!=null&&(o.naiveInBytes+=Buffer.byteLength(JSON.stringify(i))-Buffer.byteLength(JSON.stringify(e.input)));let a=`resp_${Math.random().toString(36).slice(2,14)}`,f=e.store!==!1,c=await n.createResponse({model:e.model,input:i,stream:s,tools:e.tools,temperature:e.temperature,max_output_tokens:e.max_output_tokens}),l=[];if(s){L(r);for await(let u of o.track(c)){l.push(u);let p=u.response&&typeof u.response=="object"?{...u,response:{...u.response,id:a}}:u;r.write(`event: ${String(u.type??"message")}
3
- data: ${JSON.stringify(p)}
2
+ "use strict";var pe=Object.create;var x=Object.defineProperty;var le=Object.getOwnPropertyDescriptor;var de=Object.getOwnPropertyNames;var me=Object.getPrototypeOf,fe=Object.prototype.hasOwnProperty;var ge=(e,n)=>{for(var t in n)x(e,t,{get:n[t],enumerable:!0})},B=(e,n,t,r)=>{if(n&&typeof n=="object"||typeof n=="function")for(let o of de(n))!fe.call(e,o)&&o!==t&&x(e,o,{get:()=>n[o],enumerable:!(r=le(n,o))||r.enumerable});return e};var ye=(e,n,t)=>(t=e!=null?pe(me(e)):{},B(n||!e||!e.__esModule?x(t,"default",{value:e,enumerable:!0}):t,e)),_e=e=>B(x({},"__esModule",{value:!0}),e);var je={};ge(je,{buildClients:()=>ae,resolveSessionFromEnv:()=>ie});module.exports=_e(je);var se=require("child_process"),g=ye(require("process"),1),R=require("@urun-sh/core");function q(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 K(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 D(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 he="llm-resp";async function*P(e,n){let t=`${he}:${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 D(s);return}}}var we="llm",S=class{constructor(n){this.session=n}session;get consumerId(){return this.session.consumerId}write(n){this.session.doc(we).set({requests:{[n.request_id]:{payload:n,consumer_id:n.consumer_id,stream:n.stream}}})}sendResponses(n,t){let r=K(n,t,this.consumerId);return this.write(r),P(this.session,t)}sendResponseCreate(n,t,r){let o=q(n,t,r,this.consumerId);return this.write(o),P(this.session,r)}};var G=0;function ke(){return G+=1,`req_${Date.now().toString(36)}_${G.toString(36)}`}var A=class{transport;constructor(n){this.transport=new S(n)}responses={create:async n=>{let t=ke(),r=this.transport.sendResponses(n,t);return Object.assign((async function*(){yield*r})(),{requestId:t})}}};async function F(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{object:"list",data:(await t.json()).map(o=>({id:`${o.model_id}:${o.variant}`,object:"model",created:0,owned_by:"urun"}))}}var X=require("http"),$=class e{startedAt=Date.now();requests={};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}track(n){let t=this,r=performance.now(),o=null,s=0;return(async function*(){for await(let a of n)a.type==="response.output_text.delta"&&typeof a.delta=="string"&&(o===null&&(o=performance.now(),t.ttftMs.push(o-r),t.ttftMs.length>512&&t.ttftMs.shift()),s+=1,t.tokensOut+=1,t.charsOut+=a.delta.length),yield a;let i=(performance.now()-(o??r))/1e3;s>0&&i>0&&(t.tokRates.push(s/i),t.tokRates.length>512&&t.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,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 M(e){e.writeHead(200,{"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive"})}function w(e,n,t){e.writeHead(n,{"content-type":"application/json"}),e.end(JSON.stringify(t))}function f(e,n,t,r="invalid_request_error"){w(e,n,{error:{message:t,type:r}})}var Y=64*1024*1024,b=class extends Error{};async function ve(e){let n=[],t=0;for await(let o of e){if(t+=o.length,t>Y)throw new b(`request body exceeds ${Y} bytes`);n.push(o)}let r=Buffer.concat(n).toString("utf8");return r?JSON.parse(r):{}}function E(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 Re=256;function xe(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 T=class{conversations=new Map;thread(n,t){let r=xe(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<=Re)break;this.conversations.delete(o)}}};function V(e){let n=e?.output;return Array.isArray(n)?n.filter(t=>t.type==="function_call"):[]}function v(e){return e.find(n=>n.type==="response.completed")?.response??null}function Se(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 U=class extends Error{};function Ae(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 U(`unsupported chat content part type "${String(r.type)}" \u2014 the proxy translates text and image_url parts`)}):n}function Ee(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:Ae(t.role,t.content)})}return n}function W(e){return V(e).map((n,t)=>({index:t,id:n.call_id??n.id??`call_${t}`,type:"function",function:{name:n.name??"",arguments:n.arguments??"{}"}}))}function z(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 be(e,n,t,r,o){let s=e.stream===!0,i;try{i=t.thread(e.previous_response_id,e.input)}catch(u){f(r,400,String(u instanceof Error?u.message:u));return}e.previous_response_id!=null&&(o.naiveInBytes+=Buffer.byteLength(JSON.stringify(i))-Buffer.byteLength(JSON.stringify(e.input)));let a=`resp_${Math.random().toString(36).slice(2,14)}`,l=e.store!==!1,p=await n.createResponse({model:e.model,input:i,stream:s,tools:e.tools,temperature:e.temperature,max_output_tokens:e.max_output_tokens}),m=[];if(s){M(r);for await(let u of o.track(p)){m.push(u);let c=u.response&&typeof u.response=="object"?{...u,response:{...u.response,id:a}}:u;r.write(`event: ${String(u.type??"message")}
3
+ data: ${JSON.stringify(c)}
4
4
 
5
- `)}f&&t.remember(a,i,W(l,v(l))),r.write(`data: [DONE]
5
+ `)}l&&t.remember(a,i,z(m,v(m))),r.write(`data: [DONE]
6
6
 
7
- `),r.end();return}let d=null;for await(let u of o.track(c)){if(l.push(u),u.type==="error"){g(r,502,JSON.stringify(u),"upstream_error");return}u.type==="response.completed"&&(d=u.response)}if(d==null){g(r,502,"upstream produced no response.completed event","upstream_error");return}let y=W(l,d);f&&t.remember(a,i,y),w(r,200,{...d,id:a})}async function Oe(e,n,t,r){let o=e.messages;if(!Array.isArray(o)){g(t,400,"chat/completions requires a messages array");return}let s=String(e.model??"urun"),i=`chatcmpl-${Math.random().toString(36).slice(2,14)}`,a;try{a=be(o)}catch(u){if(u instanceof O){g(t,400,u.message);return}throw u}let f=await n.createResponse({model:e.model,input:a,stream:!0,tools:Ae(e.tools),temperature:e.temperature,max_output_tokens:e.max_completion_tokens??e.max_tokens});if(e.stream===!0){L(t);let u=[];t.write(`data: ${JSON.stringify(b(i,s,{role:"assistant"},null))}
7
+ `),r.end();return}let d=null;for await(let u of o.track(p)){if(m.push(u),u.type==="error"){f(r,502,JSON.stringify(u),"upstream_error");return}u.type==="response.completed"&&(d=u.response)}if(d==null){f(r,502,"upstream produced no response.completed event","upstream_error");return}let y=z(m,d);l&&t.remember(a,i,y),w(r,200,{...d,id:a})}async function Ue(e,n,t,r){let o=e.messages;if(!Array.isArray(o)){f(t,400,"chat/completions requires a messages array");return}let s=String(e.model??"urun"),i=`chatcmpl-${Math.random().toString(36).slice(2,14)}`,a;try{a=Ee(o)}catch(u){if(u instanceof U){f(t,400,u.message);return}throw u}let l=await n.createResponse({model:e.model,input:a,stream:!0,tools:Se(e.tools),temperature:e.temperature,max_output_tokens:e.max_completion_tokens??e.max_tokens});if(e.stream===!0){M(t);let u=[];t.write(`data: ${JSON.stringify(E(i,s,{role:"assistant"},null))}
8
8
 
9
- `);for await(let h of r.track(f))if(u.push(h),h.type==="response.output_text.delta"&&typeof h.delta=="string")t.write(`data: ${JSON.stringify(b(i,s,{content:h.delta},null))}
9
+ `);for await(let h of r.track(l))if(u.push(h),h.type==="response.output_text.delta"&&typeof h.delta=="string")t.write(`data: ${JSON.stringify(E(i,s,{content:h.delta},null))}
10
10
 
11
11
  `);else if(h.type==="error"){t.write(`data: ${JSON.stringify({error:h})}
12
12
 
13
- `),t.end();return}let p=z(v(u));p.length>0&&t.write(`data: ${JSON.stringify(b(i,s,{tool_calls:p},null))}
13
+ `),t.end();return}let c=W(v(u));c.length>0&&t.write(`data: ${JSON.stringify(E(i,s,{tool_calls:c},null))}
14
14
 
15
- `),t.write(`data: ${JSON.stringify(b(i,s,{},p.length>0?"tool_calls":"stop"))}
15
+ `),t.write(`data: ${JSON.stringify(E(i,s,{},c.length>0?"tool_calls":"stop"))}
16
16
 
17
17
  `),t.write(`data: [DONE]
18
18
 
19
- `),t.end();return}let c="",l=[];for await(let u of r.track(f))if(l.push(u),u.type==="response.output_text.delta"&&typeof u.delta=="string"&&(c+=u.delta),u.type==="error"){g(t,502,JSON.stringify(u),"upstream_error");return}let d=z(v(l)).map(({index:u,...p})=>p),y={role:"assistant",content:c||null};d.length>0&&(y.tool_calls=d),w(t,200,{id:i,object:"chat.completion",created:Math.floor(Date.now()/1e3),model:s,choices:[{index:0,message:y,finish_reason:d.length>0?"tool_calls":"stop"}],usage:{prompt_tokens:0,completion_tokens:0,total_tokens:0}})}function Ue(e){return typeof e=="string"?e:Array.isArray(e)?e.filter(n=>n.type==="text").map(n=>String(n.text??"")).join(""):""}var k=class extends Error{constructor(n){super(`unsupported anthropic content block type "${n}" \u2014 the proxy translates text, tool_use and tool_result blocks`)}};function Ie(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 Ne(e){if(typeof e=="string")return e;if(e==null)return"";if(!Array.isArray(e))throw new k(typeof e);let n="";for(let t of e){let r=String(t.type??"");if(r!=="text")throw new k(`tool_result > ${r}`);n+=String(t.text??"")}return n}function Pe(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 new k(typeof t);let r=[],o="",s=()=>{o&&(r.push({role:n,content:o}),o="")};for(let i of t){let a=String(i.type??"");if(a==="text")o+=String(i.text??"");else if(a==="tool_use")s(),r.push({type:"function_call",call_id:i.id,name:i.name,arguments:JSON.stringify(i.input??{})});else if(a==="tool_result")s(),r.push({type:"function_call_output",call_id:i.tool_use_id,output:Ne(i.content)});else{if(a==="thinking"||a==="redacted_thinking")continue;throw new k(a)}}return s(),r}function H(e){return V(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 $e(e,n,t,r){let o=e.messages;if(!Array.isArray(o)){g(t,400,"messages requires a messages array");return}let s=String(e.model??"urun"),i=`msg_${Math.random().toString(36).slice(2,14)}`,a=[];try{e.system&&a.push({role:"system",content:Ue(e.system)});for(let p of o)a.push(...Pe(p))}catch(p){if(p instanceof k){g(t,400,p.message);return}throw p}let f=await n.createResponse({model:e.model,input:a,stream:!0,tools:Ie(e.tools),temperature:e.temperature,max_output_tokens:e.max_tokens}),c=(p,h)=>{t.write(`event: ${p}
20
- data: ${JSON.stringify({type:p,...h})}
19
+ `),t.end();return}let p="",m=[];for await(let u of r.track(l))if(m.push(u),u.type==="response.output_text.delta"&&typeof u.delta=="string"&&(p+=u.delta),u.type==="error"){f(t,502,JSON.stringify(u),"upstream_error");return}let d=W(v(m)).map(({index:u,...c})=>c),y={role:"assistant",content:p||null};d.length>0&&(y.tool_calls=d),w(t,200,{id:i,object:"chat.completion",created:Math.floor(Date.now()/1e3),model:s,choices:[{index:0,message:y,finish_reason:d.length>0?"tool_calls":"stop"}],usage:{prompt_tokens:0,completion_tokens:0,total_tokens:0}})}function Ie(e){return typeof e=="string"?e:Array.isArray(e)?e.filter(n=>n.type==="text").map(n=>String(n.text??"")).join(""):""}var k=class extends Error{constructor(n){super(`unsupported anthropic content block type "${n}" \u2014 the proxy translates text, tool_use and tool_result blocks`)}};function Oe(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 Ne(e){if(typeof e=="string")return e;if(e==null)return"";if(!Array.isArray(e))throw new k(typeof e);let n="";for(let t of e){let r=String(t.type??"");if(r!=="text")throw new k(`tool_result > ${r}`);n+=String(t.text??"")}return n}function Pe(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 new k(typeof t);let r=[],o="",s=()=>{o&&(r.push({role:n,content:o}),o="")};for(let i of t){let a=String(i.type??"");if(a==="text")o+=String(i.text??"");else if(a==="tool_use")s(),r.push({type:"function_call",call_id:i.id,name:i.name,arguments:JSON.stringify(i.input??{})});else if(a==="tool_result")s(),r.push({type:"function_call_output",call_id:i.tool_use_id,output:Ne(i.content)});else{if(a==="thinking"||a==="redacted_thinking")continue;throw new k(a)}}return s(),r}function H(e){return V(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 $e(e,n,t,r){let o=e.messages;if(!Array.isArray(o)){f(t,400,"messages requires a messages array");return}let s=String(e.model??"urun"),i=`msg_${Math.random().toString(36).slice(2,14)}`,a=[];try{e.system&&a.push({role:"system",content:Ie(e.system)});for(let c of o)a.push(...Pe(c))}catch(c){if(c instanceof k){f(t,400,c.message);return}throw c}let l=await n.createResponse({model:e.model,input:a,stream:!0,tools:Oe(e.tools),temperature:e.temperature,max_output_tokens:e.max_tokens}),p=(c,h)=>{t.write(`event: ${c}
20
+ data: ${JSON.stringify({type:c,...h})}
21
21
 
22
- `)};if(e.stream===!0){let p=r.track(f);L(t),c("message_start",{message:{id:i,type:"message",role:"assistant",content:[],model:s,stop_reason:null,usage:{input_tokens:0,output_tokens:0}}}),c("content_block_start",{index:0,content_block:{type:"text",text:""}});let h=0,J=[];for await(let _ of p)if(J.push(_),_.type==="response.output_text.delta"&&typeof _.delta=="string")h+=1,c("content_block_delta",{index:0,delta:{type:"text_delta",text:_.delta}});else if(_.type==="error"){c("error",{error:{type:"api_error",message:JSON.stringify(_)}}),t.end();return}let I;try{I=H(v(J))}catch(_){c("error",{error:{type:"api_error",message:String(_ instanceof Error?_.message:_)}}),t.end();return}c("content_block_stop",{index:0}),I.forEach((_,ce)=>{let N=1+ce;c("content_block_start",{index:N,content_block:{..._,input:{}}}),c("content_block_delta",{index:N,delta:{type:"input_json_delta",partial_json:JSON.stringify(_.input??{})}}),c("content_block_stop",{index:N})}),c("message_delta",{delta:{stop_reason:I.length>0?"tool_use":"end_turn"},usage:{output_tokens:h}}),c("message_stop",{}),t.end();return}let l="",d=[];for await(let p of r.track(f))if(d.push(p),p.type==="response.output_text.delta"&&typeof p.delta=="string"&&(l+=p.delta),p.type==="error"){g(t,502,JSON.stringify(p),"upstream_error");return}let y;try{y=H(v(d))}catch(p){g(t,502,String(p instanceof Error?p.message:p),"upstream_error");return}let u=[];(l||y.length===0)&&u.push({type:"text",text:l}),u.push(...y),w(t,200,{id:i,type:"message",role:"assistant",content:u,model:s,stop_reason:y.length>0?"tool_use":"end_turn",usage:{input_tokens:0,output_tokens:0}})}function Q(e){let{clients:n,apiKey:t}=e,r=new T,o=new $;return(0,X.createServer)((s,i)=>{(async()=>{let a=new URL(s.url??"/","http://localhost");if(s.method==="GET"&&a.pathname==="/healthz"){w(i,200,{ok:!0});return}if(s.method==="GET"&&a.pathname==="/stats"){w(i,200,o.snapshot());return}if(t&&(s.headers.authorization??"")!==`Bearer ${t}`){g(i,401,"invalid local proxy api key","authentication_error");return}if(s.method==="GET"&&a.pathname==="/v1/models"){w(i,200,await n.listModels());return}if(s.method!=="POST"){g(i,404,`no route for ${s.method} ${a.pathname}`);return}let f;try{f=await ve(s)}catch(l){if(l instanceof E){g(i,413,l.message,"request_too_large");return}g(i,400,"request body is not valid JSON");return}let c=Buffer.byteLength(JSON.stringify(f));if(a.pathname==="/v1/responses"){o.request("responses",c,c),await Ee(f,n,r,i,o);return}if(a.pathname==="/v1/chat/completions"){o.request("chat_completions",c,c),await Oe(f,n,i,o);return}if(a.pathname==="/v1/messages"){o.request("messages",c,c),await $e(f,n,i,o);return}g(i,404,`no route for POST ${a.pathname}`)})().catch(a=>{i.headersSent?i.end():g(i,500,String(a),"proxy_error")})})}var U={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 M(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 Z(e,n,t){let r={...e,...M(n,t)};return delete r.URUN_API_KEY,delete r.URUN_JWT,r}function ee(e){let n=Number(e);if(!Number.isInteger(n)||n<=0)throw new Error(`--port needs a positive integer, got ${e}`);return n}function te(e){if(e[0]!=="--port")return null;let n=ee(e[1]);return e.splice(0,2),n}function C(e){let n=e.indexOf("--port");if(n===-1)return 4141;let t=ee(e[n+1]);return e.splice(n,2),t}function ne(e){let n=new URL(e),t=n.hostname==="localhost"||n.hostname==="127.0.0.1"||n.hostname==="[::1]";if(n.protocol!=="https:"&&!t)throw new Error(`URUN_GATEWAY_URL must be https (got ${e}) \u2014 the org API key rides the mint call's Authorization header`);return e}function B(e){let n=(m.default.env[e]??"").trim();if(!n)throw new Error(`${e} is not set. The proxy needs URUN_BASE_URL, URUN_ORG_ID, URUN_APP and URUN_JWT (plus optional URUN_FUNCTION, default "serve") to open the backhaul session.`);return n}function re(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 ie(){let e=B("URUN_BASE_URL"),n=B("URUN_APP"),t=(m.default.env.URUN_FUNCTION??"serve").trim()||"serve",r=(m.default.env.URUN_API_KEY??"").trim(),o=(m.default.env.URUN_JWT??"").trim();if(!r&&!o)throw new Error("set URUN_API_KEY (the org API key \u2014 the CLI vends short-lived, function-scoped client tokens from it via the gateway) or URUN_JWT (an explicit pre-vended token). URUN_BASE_URL and URUN_APP are also required.");if(r){let a=(m.default.env.URUN_GATEWAY_URL??"").trim(),f=a?ne(a):void 0,c=(m.default.env.URUN_ORG_ID??"").trim(),l=(0,R.App)(n,{baseUrl:e,orgId:c,getAccessToken:async()=>(await(0,R.createClientToken)(r,{baseUrl:f,expiresIn:300,allowedFunctions:[`${n}/${t}`]})).token});return re(l,n,t)}let s=B("URUN_ORG_ID"),i=(0,R.App)(n,{baseUrl:e,orgId:s,jwt:o});return re(i,n,t)}function ae(e){let n=new S(e);return{createResponse:t=>n.responses.create(t),listModels:async()=>{let t=(m.default.env.URUN_CATALOG_URL??"").trim(),r=(m.default.env.URUN_CATALOG_ANON_KEY??"").trim();return!t||!r?{object:"list",data:[{id:"urun",object:"model",owned_by:"urun"}]}:F({catalogUrl:t,anonKey:r})}}}function ue(e){for(let[n,t]of Object.entries(M(e)))m.default.stdout.write(`export ${n}=${t}
23
- `)}async function oe(e){let n=ie(),t=Q({clients:ae(n)});return await new Promise((r,o)=>{t.once("error",o),t.listen(e,"127.0.0.1",r)}),m.default.stdout.write(`urun openai proxy listening on http://127.0.0.1:${e}/v1
24
- `),ue(e),{close:async()=>{let r=new Promise(o=>t.close(()=>o()));t.closeAllConnections(),await r,await n.end()}}}async function Le(){let e=m.default.argv.slice(2),n=te(e),t=e.shift()??"proxy";if(t==="env")return ue(n??C(e)),0;if(t==="proxy"){let o=n??C(e),s=await oe(o);return await new Promise(i=>{m.default.once("SIGINT",i),m.default.once("SIGTERM",i)}),await s.close(),0}let r=t==="run"?e.shift():t;{if(!r)throw new Error(`launch needs an agent (${Object.keys(U).join("|")}) or \`-- <cmd>\``);let o=n??4141,s,i,a="openai";if(r==="--"){if(s=e.shift()??"",i=e,!s)throw new Error("`-- <cmd>` needs a command to launch")}else{let d=U[r];if(!d)throw new Error(`unknown command/agent ${r}; commands: proxy | env; agents: ${Object.keys(U).join(" | ")} \u2014 or \`-- <cmd>\``);s=d.bin,i=[...d.args??[],...e],a=d.env}let f=await oe(o),c=(0,se.spawn)(s,i,{stdio:"inherit",env:Z(m.default.env,o,a)}),l=await new Promise(d=>{c.once("exit",y=>d(y??1)),c.once("error",y=>{m.default.stderr.write(`failed to launch ${s}: ${String(y)}
25
- `),d(127)})});return await f.close(),l}}Le().then(e=>m.default.exit(e),e=>{m.default.stderr.write(`${String(e instanceof Error?e.message:e)}
26
- `),m.default.exit(1)});0&&(module.exports={buildClients,resolveSessionFromEnv});
22
+ `)};if(e.stream===!0){let c=r.track(l);M(t),p("message_start",{message:{id:i,type:"message",role:"assistant",content:[],model:s,stop_reason:null,usage:{input_tokens:0,output_tokens:0}}}),p("content_block_start",{index:0,content_block:{type:"text",text:""}});let h=0,J=[];for await(let _ of c)if(J.push(_),_.type==="response.output_text.delta"&&typeof _.delta=="string")h+=1,p("content_block_delta",{index:0,delta:{type:"text_delta",text:_.delta}});else if(_.type==="error"){p("error",{error:{type:"api_error",message:JSON.stringify(_)}}),t.end();return}let O;try{O=H(v(J))}catch(_){p("error",{error:{type:"api_error",message:String(_ instanceof Error?_.message:_)}}),t.end();return}p("content_block_stop",{index:0}),O.forEach((_,ce)=>{let N=1+ce;p("content_block_start",{index:N,content_block:{..._,input:{}}}),p("content_block_delta",{index:N,delta:{type:"input_json_delta",partial_json:JSON.stringify(_.input??{})}}),p("content_block_stop",{index:N})}),p("message_delta",{delta:{stop_reason:O.length>0?"tool_use":"end_turn"},usage:{output_tokens:h}}),p("message_stop",{}),t.end();return}let m="",d=[];for await(let c of r.track(l))if(d.push(c),c.type==="response.output_text.delta"&&typeof c.delta=="string"&&(m+=c.delta),c.type==="error"){f(t,502,JSON.stringify(c),"upstream_error");return}let y;try{y=H(v(d))}catch(c){f(t,502,String(c instanceof Error?c.message:c),"upstream_error");return}let u=[];(m||y.length===0)&&u.push({type:"text",text:m}),u.push(...y),w(t,200,{id:i,type:"message",role:"assistant",content:u,model:s,stop_reason:y.length>0?"tool_use":"end_turn",usage:{input_tokens:0,output_tokens:0}})}function Q(e){let{clients:n,apiKey:t}=e,r=new T,o=new $;return(0,X.createServer)((s,i)=>{(async()=>{let a=new URL(s.url??"/","http://localhost");if(s.method==="GET"&&a.pathname==="/healthz"){w(i,200,{ok:!0});return}if(s.method==="GET"&&a.pathname==="/stats"){w(i,200,o.snapshot());return}if(t&&(s.headers.authorization??"")!==`Bearer ${t}`){f(i,401,"invalid local proxy api key","authentication_error");return}if(s.method==="GET"&&a.pathname==="/v1/models"){w(i,200,await n.listModels());return}if(s.method!=="POST"){f(i,404,`no route for ${s.method} ${a.pathname}`);return}let l;try{l=await ve(s)}catch(m){if(m instanceof b){f(i,413,m.message,"request_too_large");return}f(i,400,"request body is not valid JSON");return}let p=Buffer.byteLength(JSON.stringify(l));if(a.pathname==="/v1/responses"){o.request("responses",p,p),await be(l,n,r,i,o);return}if(a.pathname==="/v1/chat/completions"){o.request("chat_completions",p,p),await Ue(l,n,i,o);return}if(a.pathname==="/v1/messages"){o.request("messages",p,p),await $e(l,n,i,o);return}f(i,404,`no route for POST ${a.pathname}`)})().catch(a=>{i.headersSent?i.end():f(i,500,String(a),"proxy_error")})})}var I={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 j(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 Z(e,n,t){let r={...e,...j(n,t)};return delete r.URUN_API_KEY,delete r.URUN_JWT,r}function ee(e){let n=Number(e);if(!Number.isInteger(n)||n<=0)throw new Error(`--port needs a positive integer, got ${e}`);return n}function te(e){if(e[0]!=="--port")return null;let n=ee(e[1]);return e.splice(0,2),n}function C(e){let n=e.indexOf("--port");if(n===-1)return 4141;let t=ee(e[n+1]);return e.splice(n,2),t}function L(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 ne(e){let n=L(e,"URUN_BASE_URL"),t=L(e,"URUN_ORG_ID"),r=L(e,"URUN_APP"),o=(e.URUN_FUNCTION??"serve").trim()||"serve",s=(e.URUN_JWT??"").trim();if(s)return{baseUrl:n,orgId:t,appId:r,fnName:o,auth:{lane:"jwt",jwt:s}};let i=(e.URUN_API_KEY??"").trim();if(i){let a=(e.URUN_GATEWAY_URL??"").trim(),l=a?Te(a):void 0;return{baseUrl:n,orgId:t,appId:r,fnName:o,auth:{lane:"api-key",apiKey:i,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 Te(e){let n=new URL(e),t=n.hostname==="localhost"||n.hostname==="127.0.0.1"||n.hostname==="[::1]";if(n.protocol!=="https:"&&!t)throw new Error(`URUN_GATEWAY_URL must be https (got ${e}) \u2014 the org API key rides the mint call's Authorization header`);return e}function re(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 ie(){let{baseUrl:e,orgId:n,appId:t,fnName:r,auth:o}=ne(g.default.env);if(o.lane==="jwt"){let l=(0,R.App)(t,{baseUrl:e,orgId:n,jwt:o.jwt});return re(l,t,r)}let{apiKey:s,gatewayUrl:i}=o,a=(0,R.App)(t,{baseUrl:e,orgId:n,getAccessToken:async()=>(await(0,R.createClientToken)(s,{baseUrl:i,expiresIn:300,allowedFunctions:[`${t}/${r}`]})).token});return re(a,t,r)}function ae(e){let n=new A(e);return{createResponse:t=>n.responses.create(t),listModels:async()=>{let t=(g.default.env.URUN_CATALOG_URL??"").trim(),r=(g.default.env.URUN_CATALOG_ANON_KEY??"").trim();return!t||!r?{object:"list",data:[{id:"urun",object:"model",owned_by:"urun"}]}:F({catalogUrl:t,anonKey:r})}}}function ue(e){for(let[n,t]of Object.entries(j(e)))g.default.stdout.write(`export ${n}=${t}
23
+ `)}async function oe(e){let n=ie(),t=Q({clients:ae(n)});return await new Promise((r,o)=>{t.once("error",o),t.listen(e,"127.0.0.1",r)}),g.default.stdout.write(`urun openai proxy listening on http://127.0.0.1:${e}/v1
24
+ `),ue(e),{close:async()=>{let r=new Promise(o=>t.close(()=>o()));t.closeAllConnections(),await r,await n.end()}}}async function Le(){let e=g.default.argv.slice(2),n=te(e),t=e.shift()??"proxy";if(t==="env")return ue(n??C(e)),0;if(t==="proxy"){let o=n??C(e),s=await oe(o);return await new Promise(i=>{g.default.once("SIGINT",i),g.default.once("SIGTERM",i)}),await s.close(),0}let r=t==="run"?e.shift():t;{if(!r)throw new Error(`launch needs an agent (${Object.keys(I).join("|")}) or \`-- <cmd>\``);let o=n??4141,s,i,a="openai";if(r==="--"){if(s=e.shift()??"",i=e,!s)throw new Error("`-- <cmd>` needs a command to launch")}else{let d=I[r];if(!d)throw new Error(`unknown command/agent ${r}; commands: proxy | env; agents: ${Object.keys(I).join(" | ")} \u2014 or \`-- <cmd>\``);s=d.bin,i=[...d.args??[],...e],a=d.env}let l=await oe(o),p=(0,se.spawn)(s,i,{stdio:"inherit",env:Z(g.default.env,o,a)}),m=await new Promise(d=>{p.once("exit",y=>d(y??1)),p.once("error",y=>{g.default.stderr.write(`failed to launch ${s}: ${String(y)}
25
+ `),d(127)})});return await l.close(),m}}Le().then(e=>g.default.exit(e),e=>{g.default.stderr.write(`${String(e instanceof Error?e.message:e)}
26
+ `),g.default.exit(1)});0&&(module.exports={buildClients,resolveSessionFromEnv});
package/dist/proxy/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import{c as _,d as g}from"../chunk-GUQC3NSG.js";import{a as E}from"../chunk-YDXG2QGW.js";import{spawn as I}from"child_process";import r from"process";import{App as P,createClientToken as O}from"@urun-sh/core";var d={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 v(n,e="openai"){if(e==="anthropic")return{ANTHROPIC_BASE_URL:`http://127.0.0.1:${n}`,ANTHROPIC_API_KEY:"urun-local"};let t=`http://127.0.0.1:${n}/v1`;return{OPENAI_BASE_URL:t,OPENAI_API_BASE:t,OPENAI_API_KEY:"urun-local"}}function h(n,e,t){let o={...n,...v(e,t)};return delete o.URUN_API_KEY,delete o.URUN_JWT,o}function R(n){let e=Number(n);if(!Number.isInteger(e)||e<=0)throw new Error(`--port needs a positive integer, got ${n}`);return e}function y(n){if(n[0]!=="--port")return null;let e=R(n[1]);return n.splice(0,2),e}function w(n){let e=n.indexOf("--port");if(e===-1)return 4141;let t=R(n[e+1]);return n.splice(e,2),t}function N(n){let e=new URL(n),t=e.hostname==="localhost"||e.hostname==="127.0.0.1"||e.hostname==="[::1]";if(e.protocol!=="https:"&&!t)throw new Error(`URUN_GATEWAY_URL must be https (got ${n}) \u2014 the org API key rides the mint call's Authorization header`);return n}function f(n){let e=(r.env[n]??"").trim();if(!e)throw new Error(`${n} is not set. The proxy needs URUN_BASE_URL, URUN_ORG_ID, URUN_APP and URUN_JWT (plus optional URUN_FUNCTION, default "serve") to open the backhaul session.`);return e}function A(n,e,t){let o=n[t];if(typeof o!="function")throw new Error(`app "${e}" has no function "${t}" (set URUN_FUNCTION)`);let s=o();if(typeof s.end!="function")throw new Error(`app "${e}" function "${t}" returned a session without end()`);return s}function T(){let n=f("URUN_BASE_URL"),e=f("URUN_APP"),t=(r.env.URUN_FUNCTION??"serve").trim()||"serve",o=(r.env.URUN_API_KEY??"").trim(),s=(r.env.URUN_JWT??"").trim();if(!o&&!s)throw new Error("set URUN_API_KEY (the org API key \u2014 the CLI vends short-lived, function-scoped client tokens from it via the gateway) or URUN_JWT (an explicit pre-vended token). URUN_BASE_URL and URUN_APP are also required.");if(o){let u=(r.env.URUN_GATEWAY_URL??"").trim(),l=u?N(u):void 0,p=(r.env.URUN_ORG_ID??"").trim(),U=P(e,{baseUrl:n,orgId:p,getAccessToken:async()=>(await O(o,{baseUrl:l,expiresIn:300,allowedFunctions:[`${e}/${t}`]})).token});return A(U,e,t)}let i=f("URUN_ORG_ID"),c=P(e,{baseUrl:n,orgId:i,jwt:s});return A(c,e,t)}function k(n){let e=new _(n);return{createResponse:t=>e.responses.create(t),listModels:async()=>{let t=(r.env.URUN_CATALOG_URL??"").trim(),o=(r.env.URUN_CATALOG_ANON_KEY??"").trim();return!t||!o?{object:"list",data:[{id:"urun",object:"model",owned_by:"urun"}]}:g({catalogUrl:t,anonKey:o})}}}function x(n){for(let[e,t]of Object.entries(v(n)))r.stdout.write(`export ${e}=${t}
3
- `)}async function b(n){let e=T(),t=E({clients:k(e)});return await new Promise((o,s)=>{t.once("error",s),t.listen(n,"127.0.0.1",o)}),r.stdout.write(`urun openai proxy listening on http://127.0.0.1:${n}/v1
4
- `),x(n),{close:async()=>{let o=new Promise(s=>t.close(()=>s()));t.closeAllConnections(),await o,await e.end()}}}async function L(){let n=r.argv.slice(2),e=y(n),t=n.shift()??"proxy";if(t==="env")return x(e??w(n)),0;if(t==="proxy"){let s=e??w(n),i=await b(s);return await new Promise(c=>{r.once("SIGINT",c),r.once("SIGTERM",c)}),await i.close(),0}let o=t==="run"?n.shift():t;{if(!o)throw new Error(`launch needs an agent (${Object.keys(d).join("|")}) or \`-- <cmd>\``);let s=e??4141,i,c,u="openai";if(o==="--"){if(i=n.shift()??"",c=n,!i)throw new Error("`-- <cmd>` needs a command to launch")}else{let a=d[o];if(!a)throw new Error(`unknown command/agent ${o}; commands: proxy | env; agents: ${Object.keys(d).join(" | ")} \u2014 or \`-- <cmd>\``);i=a.bin,c=[...a.args??[],...n],u=a.env}let l=await b(s),p=I(i,c,{stdio:"inherit",env:h(r.env,s,u)}),U=await new Promise(a=>{p.once("exit",m=>a(m??1)),p.once("error",m=>{r.stderr.write(`failed to launch ${i}: ${String(m)}
5
- `),a(127)})});return await l.close(),U}}L().then(n=>r.exit(n),n=>{r.stderr.write(`${String(n instanceof Error?n.message:n)}
6
- `),r.exit(1)});export{k as buildClients,T as resolveSessionFromEnv};
2
+ import{c as h,d as v}from"../chunk-GUQC3NSG.js";import{a as g}from"../chunk-YDXG2QGW.js";import{spawn as k}from"child_process";import s from"process";import{App as R,createClientToken as O}from"@urun-sh/core";var d={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 w(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 E(e,n,t){let o={...e,...w(n,t)};return delete o.URUN_API_KEY,delete o.URUN_JWT,o}function y(e){let n=Number(e);if(!Number.isInteger(n)||n<=0)throw new Error(`--port needs a positive integer, got ${e}`);return n}function _(e){if(e[0]!=="--port")return null;let n=y(e[1]);return e.splice(0,2),n}function f(e){let n=e.indexOf("--port");if(n===-1)return 4141;let t=y(e[n+1]);return e.splice(n,2),t}function U(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 N(e){let n=U(e,"URUN_BASE_URL"),t=U(e,"URUN_ORG_ID"),o=U(e,"URUN_APP"),r=(e.URUN_FUNCTION??"serve").trim()||"serve",i=(e.URUN_JWT??"").trim();if(i)return{baseUrl:n,orgId:t,appId:o,fnName:r,auth:{lane:"jwt",jwt:i}};let a=(e.URUN_API_KEY??"").trim();if(a){let c=(e.URUN_GATEWAY_URL??"").trim(),u=c?b(c):void 0;return{baseUrl:n,orgId:t,appId:o,fnName:r,auth:{lane:"api-key",apiKey:a,gatewayUrl:u}}}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 b(e){let n=new URL(e),t=n.hostname==="localhost"||n.hostname==="127.0.0.1"||n.hostname==="[::1]";if(n.protocol!=="https:"&&!t)throw new Error(`URUN_GATEWAY_URL must be https (got ${e}) \u2014 the org API key rides the mint call's Authorization header`);return e}function P(e,n,t){let o=e[t];if(typeof o!="function")throw new Error(`app "${n}" has no function "${t}" (set URUN_FUNCTION)`);let r=o();if(typeof r.end!="function")throw new Error(`app "${n}" function "${t}" returned a session without end()`);return r}function T(){let{baseUrl:e,orgId:n,appId:t,fnName:o,auth:r}=N(s.env);if(r.lane==="jwt"){let u=R(t,{baseUrl:e,orgId:n,jwt:r.jwt});return P(u,t,o)}let{apiKey:i,gatewayUrl:a}=r,c=R(t,{baseUrl:e,orgId:n,getAccessToken:async()=>(await O(i,{baseUrl:a,expiresIn:300,allowedFunctions:[`${t}/${o}`]})).token});return P(c,t,o)}function $(e){let n=new h(e);return{createResponse:t=>n.responses.create(t),listModels:async()=>{let t=(s.env.URUN_CATALOG_URL??"").trim(),o=(s.env.URUN_CATALOG_ANON_KEY??"").trim();return!t||!o?{object:"list",data:[{id:"urun",object:"model",owned_by:"urun"}]}:v({catalogUrl:t,anonKey:o})}}}function S(e){for(let[n,t]of Object.entries(w(e)))s.stdout.write(`export ${n}=${t}
3
+ `)}async function A(e){let n=T(),t=g({clients:$(n)});return await new Promise((o,r)=>{t.once("error",r),t.listen(e,"127.0.0.1",o)}),s.stdout.write(`urun openai proxy listening on http://127.0.0.1:${e}/v1
4
+ `),S(e),{close:async()=>{let o=new Promise(r=>t.close(()=>r()));t.closeAllConnections(),await o,await n.end()}}}async function L(){let e=s.argv.slice(2),n=_(e),t=e.shift()??"proxy";if(t==="env")return S(n??f(e)),0;if(t==="proxy"){let r=n??f(e),i=await A(r);return await new Promise(a=>{s.once("SIGINT",a),s.once("SIGTERM",a)}),await i.close(),0}let o=t==="run"?e.shift():t;{if(!o)throw new Error(`launch needs an agent (${Object.keys(d).join("|")}) or \`-- <cmd>\``);let r=n??4141,i,a,c="openai";if(o==="--"){if(i=e.shift()??"",a=e,!i)throw new Error("`-- <cmd>` needs a command to launch")}else{let p=d[o];if(!p)throw new Error(`unknown command/agent ${o}; commands: proxy | env; agents: ${Object.keys(d).join(" | ")} \u2014 or \`-- <cmd>\``);i=p.bin,a=[...p.args??[],...e],c=p.env}let u=await A(r),m=k(i,a,{stdio:"inherit",env:E(s.env,r,c)}),x=await new Promise(p=>{m.once("exit",l=>p(l??1)),m.once("error",l=>{s.stderr.write(`failed to launch ${i}: ${String(l)}
5
+ `),p(127)})});return await u.close(),x}}L().then(e=>s.exit(e),e=>{s.stderr.write(`${String(e instanceof Error?e.message:e)}
6
+ `),s.exit(1)});export{$ as buildClients,T as resolveSessionFromEnv};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@urun-sh/openai",
3
- "version": "0.2.49",
3
+ "version": "0.2.50",
4
4
  "description": "OpenAI-compatible Realtime + Responses SDK over uRun session primitives (not websockets).",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -40,7 +40,7 @@
40
40
  "build:bin": "bun build --compile --external @roamhq/wrtc --external werift --external opusscript src/proxy/cli.ts --outfile dist/bin/urun-openai"
41
41
  },
42
42
  "peerDependencies": {
43
- "@urun-sh/core": "^0.2.49"
43
+ "@urun-sh/core": "^0.2.50"
44
44
  },
45
45
  "dependencies": {
46
46
  "openai": "4.104.0"