@urun-sh/openai 0.2.54 → 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.
@@ -21,9 +21,29 @@ interface UrunStreamLike {
21
21
  interface UrunSessionLike {
22
22
  /** Per-leg consumer identity (core: transport.consumerId). */
23
23
  readonly consumerId: string;
24
+ /**
25
+ * The uRun session's stable id, when the SDK session exposes one. Used as
26
+ * the serve-side session-affinity tag (urun-python #1556) so consecutive
27
+ * turns continue the engine's retained sequence state. Optional: a session
28
+ * object without it gets a per-transport tag minted once instead (the
29
+ * transport's lifetime IS the session's lifetime).
30
+ */
31
+ readonly sessionId?: string;
24
32
  doc(key: string): UrunDocLike;
25
33
  stream(name: string): UrunStreamLike;
26
- close?(): Promise<void> | void;
34
+ /**
35
+ * Core's OWN terminal release (`Session.end()`): ends the owner session and
36
+ * awaits the control-plane release. Optional here because the transport
37
+ * legs (decode/encode/Responses) never terminate a session — the OWNERS do,
38
+ * and each requires it loudly (proxy `sessionOf`, pi `makeSessionFactory`).
39
+ *
40
+ * NOTE (was a silent no-op until #298): this used to be declared as
41
+ * `close?()`, which `@urun-sh/core`'s Session does not have at all — every
42
+ * `session.close?.()` optional-chained to nothing, so "releasing" a session
43
+ * only dropped the local handle while the backend session and its capacity
44
+ * lease stayed alive. Core's surface is `end()` / `disconnect()`.
45
+ */
46
+ end?(): Promise<unknown>;
27
47
  }
28
48
  /**
29
49
  * One OpenAI chat-completions-chunk-style tool_call delta fragment as the
@@ -15,9 +15,12 @@ interface UrunStreamLike {
15
15
  interface UrunSessionLike {
16
16
 
17
17
  readonly consumerId: string;
18
+
19
+ readonly sessionId?: string;
18
20
  doc(key: string): UrunDocLike;
19
21
  stream(name: string): UrunStreamLike;
20
- close?(): Promise<void> | void;
22
+
23
+ end?(): Promise<unknown>;
21
24
  }
22
25
 
23
26
  interface LaneToolCallDelta {
@@ -1,4 +1,4 @@
1
- import{b as V}from"./chunk-PS4BLX7J.js";import{createServer as yt}from"http";var ut=class e{startedAt=Date.now();requests={};models={};ttftMs=[];tokRates=[];tokensOut=0;charsOut=0;localInBytes=0;naiveInBytes=0;request(n,t,o){this.requests[n]=(this.requests[n]??0)+1,this.localInBytes+=t,this.naiveInBytes+=o}modelEntry(n){let t=this.models[n];if(t)return t;let o=Object.keys(this.models).length>=ht?"(other)":n;return this.models[o]??={requests:0,tokens_out:0}}model(n){this.modelEntry(n).requests+=1}track(n,t){let o=this,a=performance.now(),c=null,u=0;return(async function*(){for await(let d of n)d.type==="response.output_text.delta"&&typeof d.delta=="string"&&(c===null&&(c=performance.now(),o.ttftMs.push(c-a),o.ttftMs.length>512&&o.ttftMs.shift()),u+=1,o.tokensOut+=1,o.charsOut+=d.delta.length,t!==void 0&&(o.modelEntry(t).tokens_out+=1)),yield d;let i=(performance.now()-(c??a))/1e3;u>0&&i>0&&(o.tokRates.push(u/i),o.tokRates.length>512&&o.tokRates.shift())})()}static p50(n){if(!n.length)return null;let t=[...n].sort((o,a)=>o-a);return t[Math.floor(t.length/2)]}snapshot(){let n=Object.values(this.requests).reduce((t,o)=>t+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: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 ct(e){e.writeHead(200,{"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive"})}function J(e,n,t){e.writeHead(n,{"content-type":"application/json"}),e.end(JSON.stringify(t))}function w(e,n,t,o="invalid_request_error"){J(e,n,{error:{message:t,type:o}})}function pt(e,n,t){if(n==="anthropic"){J(e,404,{type:"error",error:{type:"not_found_error",message:t.message}});return}J(e,404,{error:{message:t.message,type:"invalid_request_error",code:"model_not_found"}})}var ht=256,kt=128;function dt(e){return typeof e.model!="string"||!e.model.trim()?"(default)":e.model.trim().slice(0,kt)}var mt=64*1024*1024,nt=class extends Error{};async function wt(e){let n=[],t=0;for await(let a of e){if(t+=a.length,t>mt)throw new nt(`request body exceeds ${mt} bytes`);n.push(a)}let o=Buffer.concat(n).toString("utf8");return o?JSON.parse(o):{}}function F(e,n,t,o){return{id:e,object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:n,choices:[{index:0,delta:t,finish_reason:o}]}}var xt=256;function Rt(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 lt=class{conversations=new Map;thread(n,t){let o=Rt(t);if(n==null)return o;let a=this.conversations.get(String(n));if(!a)throw new Error(`unknown previous_response_id ${String(n)} (proxy restarts drop stored responses)`);return[...a,...o]}remember(n,t,o){this.conversations.set(n,[...t,{role:"assistant",content:o}]);for(let a of this.conversations.keys()){if(this.conversations.size<=xt)break;this.conversations.delete(a)}}};function Q(e){let n=e?.output;return Array.isArray(n)?n.filter(t=>t.type==="function_call"):[]}function W(e){return e.find(n=>n.type==="response.completed")?.response??null}function _t(e){let n=e?.output;if(!Array.isArray(n))return"";let t="";for(let o of n)if(!(o.type!=="reasoning"||!Array.isArray(o.content)))for(let a of o.content)a.type==="reasoning_text"&&(t+=String(a.text??""));return t}function Z(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 z=class{calls=new Map;add(n){let t=this.calls.get(n.tool_index),o=!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:o}}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}))}},vt=["<tool_call>","<function="];function At(e){return vt.find(n=>e.includes(n))}function D(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 K(e,n,t){if(!(!e||n>0))return At(t)}function St(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 ot=class extends Error{};function It(e,n){return Array.isArray(n)?n.map(t=>{let o=t;if(o.type==="text")return{type:e==="assistant"?"output_text":"input_text",text:o.text};if(o.type==="image_url"){let a=o.image_url??{};return{type:"input_image",image_url:a.url,detail:a.detail}}throw new ot(`unsupported chat content part type "${String(o.type)}" \u2014 the proxy translates text and image_url parts`)}):n}function Ot(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 o of t.tool_calls){let a=o.function??{};n.push({type:"function_call",call_id:o.id,name:a.name,arguments:a.arguments})}continue}n.push({...t,content:It(t.role,t.content)})}return n}function it(e){return Q(e).map((n,t)=>({index:t,id:n.call_id??n.id??`call_${t}`,type:"function",function:{name:n.name??"",arguments:n.arguments??"{}"}}))}function gt(e,n){let t=n?.output_text;return typeof t=="string"?t:e.filter(o=>o.type==="response.output_text.delta"&&typeof o.delta=="string").map(o=>o.delta).join("")}async function Et(e,n,t,o,a){let c=e.stream===!0,u;try{u=t.thread(e.previous_response_id,e.input)}catch(s){w(o,400,String(s instanceof Error?s.message:s));return}e.previous_response_id!=null&&(a.naiveInBytes+=Buffer.byteLength(JSON.stringify(u))-Buffer.byteLength(JSON.stringify(e.input)));let i=`resp_${Math.random().toString(36).slice(2,14)}`,d=e.store!==!1,_=dt(e);a.model(_);let v=Array.isArray(e.tools)&&e.tools.length>0,A;try{A=await n.createResponse({model:e.model,input:u,stream:c,tools:e.tools,tool_choice:e.tool_choice,temperature:e.temperature,max_output_tokens:e.max_output_tokens})}catch(s){if(s instanceof V){pt(o,"openai",s);return}throw s}let f=[];if(c){ct(o);let s=p=>{o.write(`event: ${String(p.type??"message")}
1
+ import{b as V}from"./chunk-5CEMLB6H.js";import{createServer as yt}from"http";var ut=class e{startedAt=Date.now();requests={};models={};ttftMs=[];tokRates=[];tokensOut=0;charsOut=0;localInBytes=0;naiveInBytes=0;request(n,t,o){this.requests[n]=(this.requests[n]??0)+1,this.localInBytes+=t,this.naiveInBytes+=o}modelEntry(n){let t=this.models[n];if(t)return t;let o=Object.keys(this.models).length>=ht?"(other)":n;return this.models[o]??={requests:0,tokens_out:0}}model(n){this.modelEntry(n).requests+=1}track(n,t){let o=this,a=performance.now(),c=null,u=0;return(async function*(){for await(let d of n)d.type==="response.output_text.delta"&&typeof d.delta=="string"&&(c===null&&(c=performance.now(),o.ttftMs.push(c-a),o.ttftMs.length>512&&o.ttftMs.shift()),u+=1,o.tokensOut+=1,o.charsOut+=d.delta.length,t!==void 0&&(o.modelEntry(t).tokens_out+=1)),yield d;let i=(performance.now()-(c??a))/1e3;u>0&&i>0&&(o.tokRates.push(u/i),o.tokRates.length>512&&o.tokRates.shift())})()}static p50(n){if(!n.length)return null;let t=[...n].sort((o,a)=>o-a);return t[Math.floor(t.length/2)]}snapshot(){let n=Object.values(this.requests).reduce((t,o)=>t+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: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 ct(e){e.writeHead(200,{"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive"})}function J(e,n,t){e.writeHead(n,{"content-type":"application/json"}),e.end(JSON.stringify(t))}function w(e,n,t,o="invalid_request_error"){J(e,n,{error:{message:t,type:o}})}function pt(e,n,t){if(n==="anthropic"){J(e,404,{type:"error",error:{type:"not_found_error",message:t.message}});return}J(e,404,{error:{message:t.message,type:"invalid_request_error",code:"model_not_found"}})}var ht=256,kt=128;function dt(e){return typeof e.model!="string"||!e.model.trim()?"(default)":e.model.trim().slice(0,kt)}var mt=64*1024*1024,nt=class extends Error{};async function wt(e){let n=[],t=0;for await(let a of e){if(t+=a.length,t>mt)throw new nt(`request body exceeds ${mt} bytes`);n.push(a)}let o=Buffer.concat(n).toString("utf8");return o?JSON.parse(o):{}}function F(e,n,t,o){return{id:e,object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:n,choices:[{index:0,delta:t,finish_reason:o}]}}var xt=256;function Rt(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 lt=class{conversations=new Map;thread(n,t){let o=Rt(t);if(n==null)return o;let a=this.conversations.get(String(n));if(!a)throw new Error(`unknown previous_response_id ${String(n)} (proxy restarts drop stored responses)`);return[...a,...o]}remember(n,t,o){this.conversations.set(n,[...t,{role:"assistant",content:o}]);for(let a of this.conversations.keys()){if(this.conversations.size<=xt)break;this.conversations.delete(a)}}};function Q(e){let n=e?.output;return Array.isArray(n)?n.filter(t=>t.type==="function_call"):[]}function W(e){return e.find(n=>n.type==="response.completed")?.response??null}function _t(e){let n=e?.output;if(!Array.isArray(n))return"";let t="";for(let o of n)if(!(o.type!=="reasoning"||!Array.isArray(o.content)))for(let a of o.content)a.type==="reasoning_text"&&(t+=String(a.text??""));return t}function Z(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 z=class{calls=new Map;add(n){let t=this.calls.get(n.tool_index),o=!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:o}}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}))}},vt=["<tool_call>","<function="];function At(e){return vt.find(n=>e.includes(n))}function D(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 K(e,n,t){if(!(!e||n>0))return At(t)}function St(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 ot=class extends Error{};function It(e,n){return Array.isArray(n)?n.map(t=>{let o=t;if(o.type==="text")return{type:e==="assistant"?"output_text":"input_text",text:o.text};if(o.type==="image_url"){let a=o.image_url??{};return{type:"input_image",image_url:a.url,detail:a.detail}}throw new ot(`unsupported chat content part type "${String(o.type)}" \u2014 the proxy translates text and image_url parts`)}):n}function Ot(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 o of t.tool_calls){let a=o.function??{};n.push({type:"function_call",call_id:o.id,name:a.name,arguments:a.arguments})}continue}n.push({...t,content:It(t.role,t.content)})}return n}function it(e){return Q(e).map((n,t)=>({index:t,id:n.call_id??n.id??`call_${t}`,type:"function",function:{name:n.name??"",arguments:n.arguments??"{}"}}))}function gt(e,n){let t=n?.output_text;return typeof t=="string"?t:e.filter(o=>o.type==="response.output_text.delta"&&typeof o.delta=="string").map(o=>o.delta).join("")}async function Et(e,n,t,o,a){let c=e.stream===!0,u;try{u=t.thread(e.previous_response_id,e.input)}catch(s){w(o,400,String(s instanceof Error?s.message:s));return}e.previous_response_id!=null&&(a.naiveInBytes+=Buffer.byteLength(JSON.stringify(u))-Buffer.byteLength(JSON.stringify(e.input)));let i=`resp_${Math.random().toString(36).slice(2,14)}`,d=e.store!==!1,_=dt(e);a.model(_);let v=Array.isArray(e.tools)&&e.tools.length>0,A;try{A=await n.createResponse({model:e.model,input:u,stream:c,tools:e.tools,tool_choice:e.tool_choice,temperature:e.temperature,max_output_tokens:e.max_output_tokens})}catch(s){if(s instanceof V){pt(o,"openai",s);return}throw s}let f=[];if(c){ct(o);let s=p=>{o.write(`event: ${String(p.type??"message")}
2
2
  data: ${JSON.stringify(p)}
3
3
 
4
4
  `)},C=p=>p.response&&typeof p.response=="object"?{...p,response:{...p.response,id:i}}:p,R=`item_${i.slice(5)}`,b=`rs_${i.slice(5)}`,E=!1,$=!1,r=0,g=()=>{E||(E=!0,s({type:"response.created",response:{id:i,object:"response",status:"in_progress"}}))},T=!1,S=0,M="",N=()=>{T&&(T=!1,s({type:"response.reasoning_text.done",item_id:b,output_index:S,content_index:0,text:M}),s({type:"response.output_item.done",output_index:S,item:{id:b,type:"reasoning",summary:[],content:[{type:"reasoning_text",text:M}],status:"completed"}}))},m=!1,x=0,O="",j=p=>{m&&(m=!1,s({type:"response.output_text.done",item_id:R,output_index:x,content_index:0,text:O}),s({type:"response.content_part.done",item_id:R,output_index:x,content_index:0,part:{type:"output_text",text:O}}),s({type:"response.output_item.done",output_index:x,item:{id:R,type:"message",role:"assistant",status:p,content:[{type:"output_text",text:O}]}}))},B=new z,y=null,L=-1,H=p=>{if(!y)return;let h=y;y=null,s({type:"response.function_call_arguments.done",item_id:h.fcId,output_index:h.outputIndex,arguments:h.args}),s({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:p}})},U=!1;for await(let p of a.track(A,_)){f.push(p);let h=String(p.type??"");if(h==="response.created"||h==="response.in_progress"){E=!0,s(C(p));continue}if(h==="response.output_item.added"){$=!0,s(C(p));continue}if(h==="response.reasoning_text.delta"&&!$){g(),T||(T=!0,S=r++,s({type:"response.output_item.added",output_index:S,item:{id:b,type:"reasoning",summary:[],content:[],status:"in_progress"}})),M+=String(p.delta??""),s({type:"response.reasoning_text.delta",item_id:b,output_index:S,content_index:0,delta:p.delta});continue}if(h==="response.output_text.delta"&&!$){g(),N(),m||(m=!0,x=r++,s({type:"response.output_item.added",output_index:x,item:{id:R,type:"message",role:"assistant",status:"in_progress",content:[]}}),s({type:"response.content_part.added",item_id:R,output_index:x,content_index:0,part:{type:"output_text",text:""}})),O+=String(p.delta??""),s({type:h,item_id:R,output_index:x,content_index:0,delta:p.delta});continue}let l=$?null:Z(p);if(l){if(g(),N(),j("completed"),B.add(l),l.tool_index!==L){H("completed"),L=l.tool_index;let k=r++;y={fcId:`fc_${i.slice(5)}_${l.tool_index}`,outputIndex:k,callId:l.call_id,name:l.name,args:""},s({type:"response.output_item.added",output_index:k,item:{id:y.fcId,type:"function_call",call_id:y.callId??y.fcId,name:y.name??"",arguments:"",status:"in_progress"}})}y&&(l.call_id&&(y.callId=l.call_id),l.name&&(y.name=l.name),y.args+=l.delta,s({type:"response.function_call_arguments.delta",item_id:y.fcId,output_index:y.outputIndex,delta:l.delta}));continue}if(h==="response.completed"&&!$){let k=Q(p.response),X=K(v,B.size+k.length,O);if(X){U=!0,s({type:"error",error:{type:"urun_error",code:"tool_call_parser_missing",message:D(_,X)}});break}N(),j("completed"),H("completed"),B.size===0&&k.forEach(Y=>{let G=r++,et=Y.id??Y.call_id??`fc_${G}`,st=Y.arguments??"",ft={id:et,type:"function_call",call_id:Y.call_id??et,name:Y.name??""};s({type:"response.output_item.added",output_index:G,item:{...ft,arguments:"",status:"in_progress"}}),s({type:"response.function_call_arguments.delta",item_id:et,output_index:G,delta:st}),s({type:"response.function_call_arguments.done",item_id:et,output_index:G,arguments:st}),s({type:"response.output_item.done",output_index:G,item:{...ft,arguments:st,status:"completed"}})}),s(C(p));continue}s(C(p))}N(),j("incomplete"),H("incomplete"),d&&!U&&t.remember(i,u,gt(f,W(f))),o.write(`data: [DONE]
@@ -1 +1 @@
1
- var g="https://api.urun.sh/v1";function l(a){return a.toLowerCase().replace(/[^\p{L}\p{N}-]/gu,"-").replace(/^-+|-+$/g,"")}var r=class extends Error{};async function m(a){let e=a.fetchImpl??fetch,t=`${a.apiUrl.replace(/\/+$/,"")}/apps`,s=await e(t,{headers:{Authorization:`Bearer ${a.apiKey}`,Accept:"application/json"}});if(!s.ok)throw new Error(`org apps listing failed: GET ${t} \u2192 ${s.status}`);let i=await s.json();if(!Array.isArray(i.apps))throw new Error(`org apps listing returned no "apps" array (GET ${t})`);if(i.truncated===!0)throw new Error(`org apps listing was truncated (GET ${t} returned ${i.apps.length} of more) \u2014 model discovery would silently omit deployed apps`);return i.apps}var c=6e4,u=class{constructor(e){this.opts=e}opts;pool=new Map;appsCache=null;seed(e,t){this.pool.set(e,Promise.resolve(t))}async deployedApps(){if(!this.opts.listApps)return[];let e=this.opts.appsTtlMs??c;if(this.appsCache&&Date.now()-this.appsCache.at<e)return this.appsCache.apps;let t=await this.opts.listApps();return this.appsCache={at:Date.now(),apps:t},t}servable(e){return e.filter(t=>t.function_name===this.opts.fnName&&t.deployment_status==="active").map(t=>t.app_slug)}async availableIds(){let e=new Set([this.opts.defaultApp]);if(this.opts.listApps)for(let t of this.servable(await this.deployedApps()))e.add(t);for(let t of this.pool.keys())e.add(t);return[this.opts.defaultApp,...[...e].filter(t=>t!==this.opts.defaultApp).sort()]}async resolveApp(e){let t=(e??"").trim();if(!t||t==="urun")return this.opts.defaultApp;let s=l(t);if(s===this.opts.defaultApp)return this.opts.defaultApp;if(this.pool.has(s))return s;if(this.opts.listApps){let i=await this.deployedApps(),p=this.servable(i);if(p.includes(s))return s;let o=p.filter(n=>n.startsWith(`${s}-`));if(o.length===1)return o[0];if(o.length>1)throw new r(`model "${t}" is ambiguous across deployed apps ${o.join(", ")} \u2014 name the exact app slug (or catalog id:variant)`);let d=i.find(n=>n.app_slug===s||n.app_slug.startsWith(`${s}-`));if(d)throw new r(`model "${t}" maps to app "${d.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 p=(await this.opts.listCatalog()).find(o=>t===o.model_id||t===`${o.model_id}:${o.variant}`||s===l(o.model_id)||s===l(`${o.model_id}-${o.variant}`));if(p)throw new r(`model "${t}" is in the uRun catalog but not deployed \u2014 deploy it with \`urun serve ${p.model_id}\`; available models: ${(await this.availableIds()).join(", ")}`)}return this.opts.defaultApp}async sessionFor(e){let t=await this.resolveApp(e),s=this.pool.get(t);return s||(s=Promise.resolve(this.opts.openSession(t)),this.pool.set(t,s),s.catch(()=>this.pool.delete(t))),{app:t,entry:await s}}async modelList(){return{object:"list",data:(await this.availableIds()).map(t=>({id:t,object:"model",created:0,owned_by:"urun"}))}}async closeAll(){let e=[...this.pool.values()];this.pool.clear();let t=[];if(await Promise.all(e.map(async s=>{try{await this.opts.closeSession(await s)}catch(i){t.push(String(i instanceof Error?i.message:i))}})),t.length>0)throw new Error(`failed to close ${t.length} pooled session(s): ${t.join("; ")}`)}};export{g as a,r as b,m as c,u as d};
1
+ var f="https://api.urun.sh/v1";function l(a){return a.toLowerCase().replace(/[^\p{L}\p{N}-]/gu,"-").replace(/^-+|-+$/g,"")}var r=class extends Error{};async function m(a){let e=a.fetchImpl??fetch,t=`${a.apiUrl.replace(/\/+$/,"")}/apps`,s=await e(t,{headers:{Authorization:`Bearer ${a.apiKey}`,Accept:"application/json"}});if(!s.ok)throw new Error(`org apps listing failed: GET ${t} \u2192 ${s.status}`);let i=await s.json();if(!Array.isArray(i.apps))throw new Error(`org apps listing returned no "apps" array (GET ${t})`);if(i.truncated===!0)throw new Error(`org apps listing was truncated (GET ${t} returned ${i.apps.length} of more) \u2014 model discovery would silently omit deployed apps`);return i.apps}var u=6e4,c=class{constructor(e){this.opts=e}opts;pool=new Map;appsCache=null;seed(e,t){this.pool.set(e,Promise.resolve(t))}async deployedApps(){if(!this.opts.listApps)return[];let e=this.opts.appsTtlMs??u;if(this.appsCache&&Date.now()-this.appsCache.at<e)return this.appsCache.apps;let t=await this.opts.listApps();return this.appsCache={at:Date.now(),apps:t},t}servable(e){return e.filter(t=>t.function_name===this.opts.fnName&&t.deployment_status==="active").map(t=>t.app_slug)}async availableIds(){let e=new Set([this.opts.defaultApp]);if(this.opts.listApps)for(let t of this.servable(await this.deployedApps()))e.add(t);for(let t of this.pool.keys())e.add(t);return[this.opts.defaultApp,...[...e].filter(t=>t!==this.opts.defaultApp).sort()]}async resolveApp(e){let t=(e??"").trim();if(!t||t==="urun")return this.opts.defaultApp;let s=l(t);if(s===this.opts.defaultApp)return this.opts.defaultApp;if(this.pool.has(s))return s;if(this.opts.listApps){let i=await this.deployedApps(),p=this.servable(i);if(p.includes(s))return s;let o=p.filter(n=>n.startsWith(`${s}-`));if(o.length===1)return o[0];if(o.length>1)throw new r(`model "${t}" is ambiguous across deployed apps ${o.join(", ")} \u2014 name the exact app slug (or catalog id:variant)`);let d=i.find(n=>n.app_slug===s||n.app_slug.startsWith(`${s}-`));if(d)throw new r(`model "${t}" maps to app "${d.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 p=(await this.opts.listCatalog()).find(o=>t===o.model_id||t===`${o.model_id}:${o.variant}`||s===l(o.model_id)||s===l(`${o.model_id}-${o.variant}`));if(p)throw new r(`model "${t}" is in the uRun catalog but not deployed \u2014 deploy it with \`urun serve ${p.model_id}\`; available models: ${(await this.availableIds()).join(", ")}`)}return this.opts.defaultApp}async sessionFor(e){let t=await this.resolveApp(e),s=this.pool.get(t);return s||(s=Promise.resolve(this.opts.openSession(t)),this.pool.set(t,s),s.catch(()=>this.pool.delete(t))),{app:t,entry:await s}}async evict(e,t){let s=this.pool.get(e);!s||await s.then(p=>p,()=>null)!==t||this.pool.get(e)!==s||(this.pool.delete(e),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 e=[...this.pool.values()];this.pool.clear();let t=[];if(await Promise.all(e.map(async s=>{try{await this.opts.closeSession(await s)}catch(i){t.push(String(i instanceof Error?i.message:i))}})),t.length>0)throw new Error(`failed to close ${t.length} pooled session(s): ${t.join("; ")}`)}};export{f as a,r as b,m as c,c as d};
@@ -1 +1 @@
1
- function g(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,o=n.body??{};return{type:"error",error:{type:"urun_error",code:n.code??null,message:o.message??"unknown error"}}}return{type:"error",error:{type:"urun_error",code:null,message:String(e)}}}function y(e,n,o,t){let r=e.response??{},i={request_id:o,consumer_id:t,stream:!0,kind:"chat",messages:n};return typeof r.instructions=="string"&&(i.instructions=r.instructions),Array.isArray(r.modalities)&&(i.modalities=r.modalities),typeof r.temperature=="number"&&(i.temperature=r.temperature),typeof r.max_output_tokens=="number"&&(i.max_output_tokens=r.max_output_tokens),r.tools!==void 0&&(i.tools=r.tools),i}function _(e,n,o){let t={request_id:n,consumer_id:o,stream:!!e.stream,kind:"responses",input:e.input};return e.model&&(t.model=e.model),e.tools!==void 0&&(t.tools=e.tools),e.tool_choice!==void 0&&(t.tool_choice=e.tool_choice),typeof e.temperature=="number"&&(t.temperature=e.temperature),typeof e.max_output_tokens=="number"&&(t.max_output_tokens=e.max_output_tokens),t}var w="llm-resp";async function*d(e,n){let o=`${w}:${n}`,t=`resp_${n}`;yield{type:"response.created",response:{id:t,status:"in_progress"}};let r=new Map;for await(let i of e.stream(o).messages()){let s=i;if(s.t==="delta"){if(typeof s.delta=="string"&&(yield{type:"response.output_text.delta",item_id:t,delta:s.delta}),typeof s.reasoning=="string"&&(yield{type:"response.reasoning_text.delta",item_id:t,delta:s.reasoning}),Array.isArray(s.tool_calls))for(let u of s.tool_calls){let p=typeof u.index=="number"?u.index:0,a=r.get(p)??{};u.id&&(a.id=u.id),u.function?.name&&(a.name=u.function.name),r.set(p,a),yield{type:"response.function_call_arguments.delta",item_id:`fc_${n}_${p}`,tool_index:p,call_id:a.id,name:a.name,delta:u.function?.arguments??""}}}else if(s.t==="response"){yield{type:"response.completed",response:{id:t,status:"completed",...s.body}};return}else if(s.t==="error"){yield g(s);return}}}var b="llm",l=class{constructor(n){this.session=n}session;get consumerId(){return this.session.consumerId}write(n){this.session.doc(b).set({requests:{[n.request_id]:{payload:n,consumer_id:n.consumer_id,stream:n.stream}}})}sendResponses(n,o){let t=_(n,o,this.consumerId);return this.write(t),d(this.session,o)}sendResponseCreate(n,o,t){let r=y(n,o,t,this.consumerId);return this.write(r),d(this.session,t)}};var f=0;function v(){return f+=1,`req_${Date.now().toString(36)}_${f.toString(36)}`}var k=class{transport;constructor(n){this.transport=new l(n)}responses={create:async n=>{let o=v(),t=this.transport.sendResponses(n,o);return Object.assign((async function*(){yield*t})(),{requestId:o})}}};export{g as a,l as b,k as c};
1
+ function g(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,o=n.body??{};return{type:"error",error:{type:"urun_error",code:n.code??null,message:o.message??"unknown error"}}}return{type:"error",error:{type:"urun_error",code:null,message:String(e)}}}function y(e,n,o,t){let r=e.response??{},i={request_id:o,consumer_id:t,stream:!0,kind:"chat",messages:n};return typeof r.instructions=="string"&&(i.instructions=r.instructions),Array.isArray(r.modalities)&&(i.modalities=r.modalities),typeof r.temperature=="number"&&(i.temperature=r.temperature),typeof r.max_output_tokens=="number"&&(i.max_output_tokens=r.max_output_tokens),r.tools!==void 0&&(i.tools=r.tools),i}function _(e,n,o){let t={request_id:n,consumer_id:o,stream:!!e.stream,kind:"responses",input:e.input};return e.model&&(t.model=e.model),e.tools!==void 0&&(t.tools=e.tools),e.tool_choice!==void 0&&(t.tool_choice=e.tool_choice),typeof e.temperature=="number"&&(t.temperature=e.temperature),typeof e.max_output_tokens=="number"&&(t.max_output_tokens=e.max_output_tokens),t}var w="llm-resp";async function*d(e,n){let o=`${w}:${n}`,t=`resp_${n}`;yield{type:"response.created",response:{id:t,status:"in_progress"}};let r=new Map;for await(let i of e.stream(o).messages()){let s=i;if(s.t==="delta"){if(typeof s.delta=="string"&&(yield{type:"response.output_text.delta",item_id:t,delta:s.delta}),typeof s.reasoning=="string"&&(yield{type:"response.reasoning_text.delta",item_id:t,delta:s.reasoning}),Array.isArray(s.tool_calls))for(let a of s.tool_calls){let p=typeof a.index=="number"?a.index:0,u=r.get(p)??{};a.id&&(u.id=a.id),a.function?.name&&(u.name=a.function.name),r.set(p,u),yield{type:"response.function_call_arguments.delta",item_id:`fc_${n}_${p}`,tool_index:p,call_id:u.id,name:u.name,delta:a.function?.arguments??""}}}else if(s.t==="response"){yield{type:"response.completed",response:{id:t,status:"completed",...s.body}};return}else if(s.t==="error"){yield g(s);return}}}var b="llm",m=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(b).set({requests:{[n.request_id]:{payload:n,consumer_id:n.consumer_id,stream:n.stream}}})}sendResponses(n,o){let t=_(n,o,this.consumerId);return this.write(t),d(this.session,o)}sendResponseCreate(n,o,t){let r=y(n,o,t,this.consumerId);return this.write(r),d(this.session,t)}};var f=0;function v(){return f+=1,`req_${Date.now().toString(36)}_${f.toString(36)}`}var k=class{transport;constructor(n){this.transport=new m(n)}responses={create:async n=>{let o=v(),t=this.transport.sendResponses(n,o);return Object.assign((async function*(){yield*t})(),{requestId:o})}}};export{g as a,m as b,k as c};
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var D=Object.create;var f=Object.defineProperty;var $=Object.getOwnPropertyDescriptor;var j=Object.getOwnPropertyNames;var q=Object.getPrototypeOf,H=Object.prototype.hasOwnProperty;var N=(n,e)=>{for(var t in e)f(n,t,{get:e[t],enumerable:!0})},S=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of j(e))!H.call(n,o)&&o!==t&&f(n,o,{get:()=>e[o],enumerable:!(r=$(e,o))||r.enumerable});return n};var v=(n,e,t)=>(t=n!=null?D(q(n)):{},S(e||!n||!n.__esModule?f(t,"default",{value:n,enumerable:!0}):t,n)),W=n=>S(f({},"__esModule",{value:!0}),n);var Q={};N(Q,{SUPPORTED_REALTIME_CLIENT_EVENTS:()=>h,SUPPORTED_RESPONSES_EVENTS:()=>b,UrunRealtime:()=>y,UrunResponses:()=>w,isSupportedClientEvent:()=>P,isSupportedResponsesEvent:()=>O,listModels:()=>L,nodeAudioBackend:()=>x,toErrorEvent:()=>p,weriftAudioBackend:()=>R});module.exports=W(Q);function E(n,e,t,r){let o=n.response??{},s={request_id:t,consumer_id:r,stream:!0,kind:"chat",messages:e};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 A(n,e,t){let r={request_id:e,consumer_id:t,stream:!!n.stream,kind:"responses",input:n.input};return n.model&&(r.model=n.model),n.tools!==void 0&&(r.tools=n.tools),n.tool_choice!==void 0&&(r.tool_choice=n.tool_choice),typeof n.temperature=="number"&&(r.temperature=n.temperature),typeof n.max_output_tokens=="number"&&(r.max_output_tokens=n.max_output_tokens),r}function p(n){if(n instanceof Error)return{type:"error",error:{type:"urun_error",code:n.name||null,message:n.message}};if(n&&typeof n=="object"&&n.t==="error"){let e=n,t=e.body??{};return{type:"error",error:{type:"urun_error",code:e.code??null,message:t.message??"unknown error"}}}return{type:"error",error:{type:"urun_error",code:null,message:String(n)}}}var F="llm-resp";async function*_(n,e){let t=`${F}:${e}`,r=`resp_${e}`;yield{type:"response.created",response:{id:r,status:"in_progress"}};let o=new Map;for await(let s of n.stream(t).messages()){let a=s;if(a.t==="delta"){if(typeof a.delta=="string"&&(yield{type:"response.output_text.delta",item_id:r,delta:a.delta}),typeof a.reasoning=="string"&&(yield{type:"response.reasoning_text.delta",item_id:r,delta:a.reasoning}),Array.isArray(a.tool_calls))for(let u of a.tool_calls){let i=typeof u.index=="number"?u.index:0,c=o.get(i)??{};u.id&&(c.id=u.id),u.function?.name&&(c.name=u.function.name),o.set(i,c),yield{type:"response.function_call_arguments.delta",item_id:`fc_${e}_${i}`,tool_index:i,call_id:c.id,name:c.name,delta:u.function?.arguments??""}}}else if(a.t==="response"){yield{type:"response.completed",response:{id:r,status:"completed",...a.body}};return}else if(a.t==="error"){yield p(a);return}}}var K="llm",l=class{constructor(e){this.session=e}session;get consumerId(){return this.session.consumerId}write(e){this.session.doc(K).set({requests:{[e.request_id]:{payload:e,consumer_id:e.consumer_id,stream:e.stream}}})}sendResponses(e,t){let r=A(e,t,this.consumerId);return this.write(r),_(this.session,t)}sendResponseCreate(e,t,r){let o=E(e,t,r,this.consumerId);return this.write(o),_(this.session,r)}};var k=class{constructor(e,t){this.backend=e;this.opts=t}backend;opts;source=null;sink=null;outHandlers=new Set;async startOutbound(){return this.source=this.backend.createSource(),this.source.track}appendInputAudio(e){if(!this.source)throw new Error("startOutbound() not called");let t=Buffer.from(e,"base64"),r=Math.floor(t.byteLength/2),o=new Int16Array(r);for(let s=0;s<r;s++)o[s]=t.readInt16LE(s*2);this.source.onData(o)}async startInbound(e){if(e==null)throw new Error('startInbound: no downstream audio track \u2014 the runtime audio producer has not been consumed yet (session.stream("rt-audio-out").track is null)');this.sink=this.backend.createSink(e),this.sink.onframe=t=>{let r=Buffer.from(t.samples.buffer,t.samples.byteOffset,t.samples.byteLength).toString("base64");for(let o of this.outHandlers)o(r)}}onOutputAudio(e){return this.outHandlers.add(e),()=>this.outHandlers.delete(e)}},V=24e3,m=480,Y=111;async function z(){let n=await import("opusscript"),e=n.default??n;return new e(V,1,2048)}async function R(){let n=await import("werift"),e=await z();return{createSource:()=>{let t=new n.MediaStreamTrack({kind:"audio"}),r=Math.random()*4294967295>>>0,o=Math.random()*65535&65535,s=Math.random()*4294967295>>>0,a=new Int16Array(0);return{track:t,onData:u=>{let i=new Int16Array(a.length+u.length);i.set(a,0),i.set(u,a.length);let c=0;for(;i.length-c>=m;){let g=i.subarray(c,c+m);c+=m;let B=Buffer.from(g.buffer,g.byteOffset,g.byteLength),C=e.encode(B,m);o=o+1&65535,s=s+m>>>0;let M=new n.RtpHeader({version:2,payloadType:Y,sequenceNumber:o,timestamp:s,ssrc:r,marker:!1}),U=new n.RtpPacket(M,C);t.writeRtp(U)}a=i.slice(c)}}},createSink:t=>{let r={onframe:null};return t.onReceiveRtp.subscribe(s=>{let a;try{a=e.decode(s.payload)}catch{return}let u=new Int16Array(a.length/2);for(let i=0;i<u.length;i++)u[i]=a.readInt16LE(i*2);r.onframe?.({samples:u})}),r}}}async function x(){let n=await import("@roamhq/wrtc");return{createSource:()=>{let e=new n.nonstandard.RTCAudioSource;return{track:e.createTrack(),onData:r=>e.onData({samples:r,sampleRate:24e3})}},createSink:e=>{let t={onframe:null},r=new n.nonstandard.RTCAudioSink(e);return r.ondata=o=>{t.onframe?.(o)},t}}}var I=0;function X(){return I+=1,`rt_${Date.now().toString(36)}_${I.toString(36)}`}var y=class{constructor(e,t={}){this.session=e;this.opts=t;this.transport=new l(e)}session;opts;transport;handlers=new Set;conversation=[];active=null;audio=null;currentRequestId=null;async enableAudio(){if(!this.opts.audioBackend)throw new Error("audioBackend required for audio");this.audio=new k(this.opts.audioBackend,{sampleRate:24e3});let e=await this.audio.startOutbound();await this.session.stream("rt-audio-in").attach(e),this.audio.onOutputAudio(r=>this.emit({type:"response.audio.delta",delta:r}));let t=await this.awaitDownstreamAudioTrack();await this.audio.startInbound(t)}awaitDownstreamAudioTrack(e=1e4){let t=this.session.stream("rt-audio-out");return t.track!=null?Promise.resolve(t.track):new Promise((r,o)=>{let s,a=setTimeout(()=>{s?.(),o(new Error(`enableAudio: no downstream audio track within ${e}ms (runtime produced no voice OUT / SFU audio consumer never attached)`))},e),u=i=>{i!=null&&(clearTimeout(a),s?.(),r(i))};s=t.on?.("track",u),t.track!=null&&u(t.track)})}on(e,t){return this.handlers.add(t),()=>this.handlers.delete(t)}emit(e){for(let t of this.handlers)t(e)}send(e){switch(e.type){case"conversation.item.create":{let t=(e.item?.content??[]).map(r=>r.text??"").join("");this.conversation.push({role:e.item?.role??"user",content:t});return}case"response.create":{let t=X();this.currentRequestId=t;let r=this.transport.sendResponseCreate({type:"response.create",response:e.response},this.conversation,t);this.active=(async()=>{try{for await(let o of r)this.emit(o)}catch(o){this.emit(p(o))}})();return}case"input_audio_buffer.append":this.audio?.appendInputAudio(e.audio);return;case"input_audio_buffer.commit":case"input_audio_buffer.clear":return;case"response.cancel":return;default:return}}async drain(){this.active&&await this.active}};var T=0;function G(){return T+=1,`req_${Date.now().toString(36)}_${T.toString(36)}`}var w=class{transport;constructor(e){this.transport=new l(e)}responses={create:async e=>{let t=G(),r=this.transport.sendResponses(e,t);return Object.assign((async function*(){yield*r})(),{requestId:t})}}};async function J(n){let t=await(n.fetchImpl??fetch)(`${n.catalogUrl}/model_catalog?select=model_id,variant`,{headers:{apikey:n.anonKey,Authorization:`Bearer ${n.anonKey}`}});if(!t.ok)throw new Error(`model_catalog fetch failed: ${t.status}`);return await t.json()}async function L(n){return{object:"list",data:(await J(n)).map(t=>({id:`${t.model_id}:${t.variant}`,object:"model",created:0,owned_by:"urun"}))}}var h=["session.update","conversation.item.create","response.create","response.cancel","input_audio_buffer.append","input_audio_buffer.commit","input_audio_buffer.clear"],b=["response.created","response.output_text.delta","response.output_item.added","response.function_call_arguments.delta","response.image_generation_call.partial_image","response.completed","error"];function P(n){return h.includes(n)}function O(n){return b.includes(n)}0&&(module.exports={SUPPORTED_REALTIME_CLIENT_EVENTS,SUPPORTED_RESPONSES_EVENTS,UrunRealtime,UrunResponses,isSupportedClientEvent,isSupportedResponsesEvent,listModels,nodeAudioBackend,toErrorEvent,weriftAudioBackend});
1
+ "use strict";var D=Object.create;var f=Object.defineProperty;var $=Object.getOwnPropertyDescriptor;var j=Object.getOwnPropertyNames;var q=Object.getPrototypeOf,H=Object.prototype.hasOwnProperty;var N=(n,e)=>{for(var t in e)f(n,t,{get:e[t],enumerable:!0})},S=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of j(e))!H.call(n,o)&&o!==t&&f(n,o,{get:()=>e[o],enumerable:!(r=$(e,o))||r.enumerable});return n};var _=(n,e,t)=>(t=n!=null?D(q(n)):{},S(e||!n||!n.__esModule?f(t,"default",{value:n,enumerable:!0}):t,n)),W=n=>S(f({},"__esModule",{value:!0}),n);var Q={};N(Q,{SUPPORTED_REALTIME_CLIENT_EVENTS:()=>h,SUPPORTED_RESPONSES_EVENTS:()=>b,UrunRealtime:()=>y,UrunResponses:()=>g,isSupportedClientEvent:()=>P,isSupportedResponsesEvent:()=>O,listModels:()=>L,nodeAudioBackend:()=>x,toErrorEvent:()=>p,weriftAudioBackend:()=>R});module.exports=W(Q);function E(n,e,t,r){let o=n.response??{},s={request_id:t,consumer_id:r,stream:!0,kind:"chat",messages:e};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 A(n,e,t){let r={request_id:e,consumer_id:t,stream:!!n.stream,kind:"responses",input:n.input};return n.model&&(r.model=n.model),n.tools!==void 0&&(r.tools=n.tools),n.tool_choice!==void 0&&(r.tool_choice=n.tool_choice),typeof n.temperature=="number"&&(r.temperature=n.temperature),typeof n.max_output_tokens=="number"&&(r.max_output_tokens=n.max_output_tokens),r}function p(n){if(n instanceof Error)return{type:"error",error:{type:"urun_error",code:n.name||null,message:n.message}};if(n&&typeof n=="object"&&n.t==="error"){let e=n,t=e.body??{};return{type:"error",error:{type:"urun_error",code:e.code??null,message:t.message??"unknown error"}}}return{type:"error",error:{type:"urun_error",code:null,message:String(n)}}}var F="llm-resp";async function*v(n,e){let t=`${F}:${e}`,r=`resp_${e}`;yield{type:"response.created",response:{id:r,status:"in_progress"}};let o=new Map;for await(let s of n.stream(t).messages()){let a=s;if(a.t==="delta"){if(typeof a.delta=="string"&&(yield{type:"response.output_text.delta",item_id:r,delta:a.delta}),typeof a.reasoning=="string"&&(yield{type:"response.reasoning_text.delta",item_id:r,delta:a.reasoning}),Array.isArray(a.tool_calls))for(let u of a.tool_calls){let i=typeof u.index=="number"?u.index:0,c=o.get(i)??{};u.id&&(c.id=u.id),u.function?.name&&(c.name=u.function.name),o.set(i,c),yield{type:"response.function_call_arguments.delta",item_id:`fc_${e}_${i}`,tool_index:i,call_id:c.id,name:c.name,delta:u.function?.arguments??""}}}else if(a.t==="response"){yield{type:"response.completed",response:{id:r,status:"completed",...a.body}};return}else if(a.t==="error"){yield p(a);return}}}var K="llm",l=class{constructor(e){this.session=e;this.sessionTag=e.sessionId??globalThis.crypto.randomUUID()}session;sessionTag;get consumerId(){return this.session.consumerId}write(e){e.session_tag=this.sessionTag,this.session.doc(K).set({requests:{[e.request_id]:{payload:e,consumer_id:e.consumer_id,stream:e.stream}}})}sendResponses(e,t){let r=A(e,t,this.consumerId);return this.write(r),v(this.session,t)}sendResponseCreate(e,t,r){let o=E(e,t,r,this.consumerId);return this.write(o),v(this.session,r)}};var k=class{constructor(e,t){this.backend=e;this.opts=t}backend;opts;source=null;sink=null;outHandlers=new Set;async startOutbound(){return this.source=this.backend.createSource(),this.source.track}appendInputAudio(e){if(!this.source)throw new Error("startOutbound() not called");let t=Buffer.from(e,"base64"),r=Math.floor(t.byteLength/2),o=new Int16Array(r);for(let s=0;s<r;s++)o[s]=t.readInt16LE(s*2);this.source.onData(o)}async startInbound(e){if(e==null)throw new Error('startInbound: no downstream audio track \u2014 the runtime audio producer has not been consumed yet (session.stream("rt-audio-out").track is null)');this.sink=this.backend.createSink(e),this.sink.onframe=t=>{let r=Buffer.from(t.samples.buffer,t.samples.byteOffset,t.samples.byteLength).toString("base64");for(let o of this.outHandlers)o(r)}}onOutputAudio(e){return this.outHandlers.add(e),()=>this.outHandlers.delete(e)}},V=24e3,m=480,Y=111;async function z(){let n=await import("opusscript"),e=n.default??n;return new e(V,1,2048)}async function R(){let n=await import("werift"),e=await z();return{createSource:()=>{let t=new n.MediaStreamTrack({kind:"audio"}),r=Math.random()*4294967295>>>0,o=Math.random()*65535&65535,s=Math.random()*4294967295>>>0,a=new Int16Array(0);return{track:t,onData:u=>{let i=new Int16Array(a.length+u.length);i.set(a,0),i.set(u,a.length);let c=0;for(;i.length-c>=m;){let w=i.subarray(c,c+m);c+=m;let B=Buffer.from(w.buffer,w.byteOffset,w.byteLength),C=e.encode(B,m);o=o+1&65535,s=s+m>>>0;let M=new n.RtpHeader({version:2,payloadType:Y,sequenceNumber:o,timestamp:s,ssrc:r,marker:!1}),U=new n.RtpPacket(M,C);t.writeRtp(U)}a=i.slice(c)}}},createSink:t=>{let r={onframe:null};return t.onReceiveRtp.subscribe(s=>{let a;try{a=e.decode(s.payload)}catch{return}let u=new Int16Array(a.length/2);for(let i=0;i<u.length;i++)u[i]=a.readInt16LE(i*2);r.onframe?.({samples:u})}),r}}}async function x(){let n=await import("@roamhq/wrtc");return{createSource:()=>{let e=new n.nonstandard.RTCAudioSource;return{track:e.createTrack(),onData:r=>e.onData({samples:r,sampleRate:24e3})}},createSink:e=>{let t={onframe:null},r=new n.nonstandard.RTCAudioSink(e);return r.ondata=o=>{t.onframe?.(o)},t}}}var T=0;function X(){return T+=1,`rt_${Date.now().toString(36)}_${T.toString(36)}`}var y=class{constructor(e,t={}){this.session=e;this.opts=t;this.transport=new l(e)}session;opts;transport;handlers=new Set;conversation=[];active=null;audio=null;currentRequestId=null;async enableAudio(){if(!this.opts.audioBackend)throw new Error("audioBackend required for audio");this.audio=new k(this.opts.audioBackend,{sampleRate:24e3});let e=await this.audio.startOutbound();await this.session.stream("rt-audio-in").attach(e),this.audio.onOutputAudio(r=>this.emit({type:"response.audio.delta",delta:r}));let t=await this.awaitDownstreamAudioTrack();await this.audio.startInbound(t)}awaitDownstreamAudioTrack(e=1e4){let t=this.session.stream("rt-audio-out");return t.track!=null?Promise.resolve(t.track):new Promise((r,o)=>{let s,a=setTimeout(()=>{s?.(),o(new Error(`enableAudio: no downstream audio track within ${e}ms (runtime produced no voice OUT / SFU audio consumer never attached)`))},e),u=i=>{i!=null&&(clearTimeout(a),s?.(),r(i))};s=t.on?.("track",u),t.track!=null&&u(t.track)})}on(e,t){return this.handlers.add(t),()=>this.handlers.delete(t)}emit(e){for(let t of this.handlers)t(e)}send(e){switch(e.type){case"conversation.item.create":{let t=(e.item?.content??[]).map(r=>r.text??"").join("");this.conversation.push({role:e.item?.role??"user",content:t});return}case"response.create":{let t=X();this.currentRequestId=t;let r=this.transport.sendResponseCreate({type:"response.create",response:e.response},this.conversation,t);this.active=(async()=>{try{for await(let o of r)this.emit(o)}catch(o){this.emit(p(o))}})();return}case"input_audio_buffer.append":this.audio?.appendInputAudio(e.audio);return;case"input_audio_buffer.commit":case"input_audio_buffer.clear":return;case"response.cancel":return;default:return}}async drain(){this.active&&await this.active}};var I=0;function G(){return I+=1,`req_${Date.now().toString(36)}_${I.toString(36)}`}var g=class{transport;constructor(e){this.transport=new l(e)}responses={create:async e=>{let t=G(),r=this.transport.sendResponses(e,t);return Object.assign((async function*(){yield*r})(),{requestId:t})}}};async function J(n){let t=await(n.fetchImpl??fetch)(`${n.catalogUrl}/model_catalog?select=model_id,variant`,{headers:{apikey:n.anonKey,Authorization:`Bearer ${n.anonKey}`}});if(!t.ok)throw new Error(`model_catalog fetch failed: ${t.status}`);return await t.json()}async function L(n){return{object:"list",data:(await J(n)).map(t=>({id:`${t.model_id}:${t.variant}`,object:"model",created:0,owned_by:"urun"}))}}var h=["session.update","conversation.item.create","response.create","response.cancel","input_audio_buffer.append","input_audio_buffer.commit","input_audio_buffer.clear"],b=["response.created","response.output_text.delta","response.output_item.added","response.function_call_arguments.delta","response.image_generation_call.partial_image","response.completed","error"];function P(n){return h.includes(n)}function O(n){return b.includes(n)}0&&(module.exports={SUPPORTED_REALTIME_CLIENT_EVENTS,SUPPORTED_RESPONSES_EVENTS,UrunRealtime,UrunResponses,isSupportedClientEvent,isSupportedResponsesEvent,listModels,nodeAudioBackend,toErrorEvent,weriftAudioBackend});
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { a as UrunSessionLike, L as LaneMessage } from './ResponsesClient-DF39QXq1.cjs';
2
- export { U as UrunResponses } from './ResponsesClient-DF39QXq1.cjs';
1
+ import { a as UrunSessionLike, L as LaneMessage } from './ResponsesClient-DrccxHTc.cjs';
2
+ export { U as UrunResponses } from './ResponsesClient-DrccxHTc.cjs';
3
3
  export { RealtimeClientEvent, RealtimeServerEvent } from 'openai/resources/beta/realtime/realtime';
4
4
  export { ResponseStreamEvent } from 'openai/resources/responses/responses';
5
5
 
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { a as UrunSessionLike, L as LaneMessage } from './ResponsesClient-DF39QXq1.js';
2
- export { U as UrunResponses } from './ResponsesClient-DF39QXq1.js';
1
+ import { a as UrunSessionLike, L as LaneMessage } from './ResponsesClient-DrccxHTc.js';
2
+ export { U as UrunResponses } from './ResponsesClient-DrccxHTc.js';
3
3
  export { RealtimeClientEvent, RealtimeServerEvent } from 'openai/resources/beta/realtime/realtime';
4
4
  export { ResponseStreamEvent } from 'openai/resources/responses/responses';
5
5
 
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{b as _}from"./chunk-OLE2YJO3.js";import{a as f,b as v,c as g}from"./chunk-DYBS3NLC.js";var p=class{constructor(t,e){this.backend=t;this.opts=e}backend;opts;source=null;sink=null;outHandlers=new Set;async startOutbound(){return this.source=this.backend.createSource(),this.source.track}appendInputAudio(t){if(!this.source)throw new Error("startOutbound() not called");let e=Buffer.from(t,"base64"),n=Math.floor(e.byteLength/2),r=new Int16Array(n);for(let a=0;a<n;a++)r[a]=e.readInt16LE(a*2);this.source.onData(r)}async startInbound(t){if(t==null)throw new Error('startInbound: no downstream audio track \u2014 the runtime audio producer has not been consumed yet (session.stream("rt-audio-out").track is null)');this.sink=this.backend.createSink(t),this.sink.onframe=e=>{let n=Buffer.from(e.samples.buffer,e.samples.byteOffset,e.samples.byteLength).toString("base64");for(let r of this.outHandlers)r(n)}}onOutputAudio(t){return this.outHandlers.add(t),()=>this.outHandlers.delete(t)}},T=24e3,c=480,x=111;async function I(){let o=await import("opusscript"),t=o.default??o;return new t(T,1,2048)}async function P(){let o=await import("werift"),t=await I();return{createSource:()=>{let e=new o.MediaStreamTrack({kind:"audio"}),n=Math.random()*4294967295>>>0,r=Math.random()*65535&65535,a=Math.random()*4294967295>>>0,i=new Int16Array(0);return{track:e,onData:u=>{let s=new Int16Array(i.length+u.length);s.set(i,0),s.set(u,i.length);let d=0;for(;s.length-d>=c;){let l=s.subarray(d,d+c);d+=c;let A=Buffer.from(l.buffer,l.byteOffset,l.byteLength),E=t.encode(A,c);r=r+1&65535,a=a+c>>>0;let b=new o.RtpHeader({version:2,payloadType:x,sequenceNumber:r,timestamp:a,ssrc:n,marker:!1}),R=new o.RtpPacket(b,E);e.writeRtp(R)}i=s.slice(d)}}},createSink:e=>{let n={onframe:null};return e.onReceiveRtp.subscribe(a=>{let i;try{i=t.decode(a.payload)}catch{return}let u=new Int16Array(i.length/2);for(let s=0;s<u.length;s++)u[s]=i.readInt16LE(s*2);n.onframe?.({samples:u})}),n}}}async function B(){let o=await import("@roamhq/wrtc");return{createSource:()=>{let t=new o.nonstandard.RTCAudioSource;return{track:t.createTrack(),onData:n=>t.onData({samples:n,sampleRate:24e3})}},createSink:t=>{let e={onframe:null},n=new o.nonstandard.RTCAudioSink(t);return n.ondata=r=>{e.onframe?.(r)},e}}}var h=0;function O(){return h+=1,`rt_${Date.now().toString(36)}_${h.toString(36)}`}var w=class{constructor(t,e={}){this.session=t;this.opts=e;this.transport=new v(t)}session;opts;transport;handlers=new Set;conversation=[];active=null;audio=null;currentRequestId=null;async enableAudio(){if(!this.opts.audioBackend)throw new Error("audioBackend required for audio");this.audio=new p(this.opts.audioBackend,{sampleRate:24e3});let t=await this.audio.startOutbound();await this.session.stream("rt-audio-in").attach(t),this.audio.onOutputAudio(n=>this.emit({type:"response.audio.delta",delta:n}));let e=await this.awaitDownstreamAudioTrack();await this.audio.startInbound(e)}awaitDownstreamAudioTrack(t=1e4){let e=this.session.stream("rt-audio-out");return e.track!=null?Promise.resolve(e.track):new Promise((n,r)=>{let a,i=setTimeout(()=>{a?.(),r(new Error(`enableAudio: no downstream audio track within ${t}ms (runtime produced no voice OUT / SFU audio consumer never attached)`))},t),u=s=>{s!=null&&(clearTimeout(i),a?.(),n(s))};a=e.on?.("track",u),e.track!=null&&u(e.track)})}on(t,e){return this.handlers.add(e),()=>this.handlers.delete(e)}emit(t){for(let e of this.handlers)e(t)}send(t){switch(t.type){case"conversation.item.create":{let e=(t.item?.content??[]).map(n=>n.text??"").join("");this.conversation.push({role:t.item?.role??"user",content:e});return}case"response.create":{let e=O();this.currentRequestId=e;let n=this.transport.sendResponseCreate({type:"response.create",response:t.response},this.conversation,e);this.active=(async()=>{try{for await(let r of n)this.emit(r)}catch(r){this.emit(f(r))}})();return}case"input_audio_buffer.append":this.audio?.appendInputAudio(t.audio);return;case"input_audio_buffer.commit":case"input_audio_buffer.clear":return;case"response.cancel":return;default:return}}async drain(){this.active&&await this.active}};var S=["session.update","conversation.item.create","response.create","response.cancel","input_audio_buffer.append","input_audio_buffer.commit","input_audio_buffer.clear"],y=["response.created","response.output_text.delta","response.output_item.added","response.function_call_arguments.delta","response.image_generation_call.partial_image","response.completed","error"];function L(o){return S.includes(o)}function C(o){return y.includes(o)}export{S as SUPPORTED_REALTIME_CLIENT_EVENTS,y as SUPPORTED_RESPONSES_EVENTS,w as UrunRealtime,g as UrunResponses,L as isSupportedClientEvent,C as isSupportedResponsesEvent,_ as listModels,B as nodeAudioBackend,f as toErrorEvent,P as weriftAudioBackend};
1
+ import{b as _}from"./chunk-OLE2YJO3.js";import{a as f,b as v,c as g}from"./chunk-HQVV5UN5.js";var p=class{constructor(t,e){this.backend=t;this.opts=e}backend;opts;source=null;sink=null;outHandlers=new Set;async startOutbound(){return this.source=this.backend.createSource(),this.source.track}appendInputAudio(t){if(!this.source)throw new Error("startOutbound() not called");let e=Buffer.from(t,"base64"),n=Math.floor(e.byteLength/2),r=new Int16Array(n);for(let a=0;a<n;a++)r[a]=e.readInt16LE(a*2);this.source.onData(r)}async startInbound(t){if(t==null)throw new Error('startInbound: no downstream audio track \u2014 the runtime audio producer has not been consumed yet (session.stream("rt-audio-out").track is null)');this.sink=this.backend.createSink(t),this.sink.onframe=e=>{let n=Buffer.from(e.samples.buffer,e.samples.byteOffset,e.samples.byteLength).toString("base64");for(let r of this.outHandlers)r(n)}}onOutputAudio(t){return this.outHandlers.add(t),()=>this.outHandlers.delete(t)}},T=24e3,c=480,x=111;async function I(){let o=await import("opusscript"),t=o.default??o;return new t(T,1,2048)}async function P(){let o=await import("werift"),t=await I();return{createSource:()=>{let e=new o.MediaStreamTrack({kind:"audio"}),n=Math.random()*4294967295>>>0,r=Math.random()*65535&65535,a=Math.random()*4294967295>>>0,i=new Int16Array(0);return{track:e,onData:u=>{let s=new Int16Array(i.length+u.length);s.set(i,0),s.set(u,i.length);let d=0;for(;s.length-d>=c;){let l=s.subarray(d,d+c);d+=c;let A=Buffer.from(l.buffer,l.byteOffset,l.byteLength),E=t.encode(A,c);r=r+1&65535,a=a+c>>>0;let b=new o.RtpHeader({version:2,payloadType:x,sequenceNumber:r,timestamp:a,ssrc:n,marker:!1}),R=new o.RtpPacket(b,E);e.writeRtp(R)}i=s.slice(d)}}},createSink:e=>{let n={onframe:null};return e.onReceiveRtp.subscribe(a=>{let i;try{i=t.decode(a.payload)}catch{return}let u=new Int16Array(i.length/2);for(let s=0;s<u.length;s++)u[s]=i.readInt16LE(s*2);n.onframe?.({samples:u})}),n}}}async function B(){let o=await import("@roamhq/wrtc");return{createSource:()=>{let t=new o.nonstandard.RTCAudioSource;return{track:t.createTrack(),onData:n=>t.onData({samples:n,sampleRate:24e3})}},createSink:t=>{let e={onframe:null},n=new o.nonstandard.RTCAudioSink(t);return n.ondata=r=>{e.onframe?.(r)},e}}}var h=0;function O(){return h+=1,`rt_${Date.now().toString(36)}_${h.toString(36)}`}var w=class{constructor(t,e={}){this.session=t;this.opts=e;this.transport=new v(t)}session;opts;transport;handlers=new Set;conversation=[];active=null;audio=null;currentRequestId=null;async enableAudio(){if(!this.opts.audioBackend)throw new Error("audioBackend required for audio");this.audio=new p(this.opts.audioBackend,{sampleRate:24e3});let t=await this.audio.startOutbound();await this.session.stream("rt-audio-in").attach(t),this.audio.onOutputAudio(n=>this.emit({type:"response.audio.delta",delta:n}));let e=await this.awaitDownstreamAudioTrack();await this.audio.startInbound(e)}awaitDownstreamAudioTrack(t=1e4){let e=this.session.stream("rt-audio-out");return e.track!=null?Promise.resolve(e.track):new Promise((n,r)=>{let a,i=setTimeout(()=>{a?.(),r(new Error(`enableAudio: no downstream audio track within ${t}ms (runtime produced no voice OUT / SFU audio consumer never attached)`))},t),u=s=>{s!=null&&(clearTimeout(i),a?.(),n(s))};a=e.on?.("track",u),e.track!=null&&u(e.track)})}on(t,e){return this.handlers.add(e),()=>this.handlers.delete(e)}emit(t){for(let e of this.handlers)e(t)}send(t){switch(t.type){case"conversation.item.create":{let e=(t.item?.content??[]).map(n=>n.text??"").join("");this.conversation.push({role:t.item?.role??"user",content:e});return}case"response.create":{let e=O();this.currentRequestId=e;let n=this.transport.sendResponseCreate({type:"response.create",response:t.response},this.conversation,e);this.active=(async()=>{try{for await(let r of n)this.emit(r)}catch(r){this.emit(f(r))}})();return}case"input_audio_buffer.append":this.audio?.appendInputAudio(t.audio);return;case"input_audio_buffer.commit":case"input_audio_buffer.clear":return;case"response.cancel":return;default:return}}async drain(){this.active&&await this.active}};var S=["session.update","conversation.item.create","response.create","response.cancel","input_audio_buffer.append","input_audio_buffer.commit","input_audio_buffer.clear"],y=["response.created","response.output_text.delta","response.output_item.added","response.function_call_arguments.delta","response.image_generation_call.partial_image","response.completed","error"];function L(o){return S.includes(o)}function C(o){return y.includes(o)}export{S as SUPPORTED_REALTIME_CLIENT_EVENTS,y as SUPPORTED_RESPONSES_EVENTS,w as UrunRealtime,g as UrunResponses,L as isSupportedClientEvent,C as isSupportedResponsesEvent,_ as listModels,B as nodeAudioBackend,f as toErrorEvent,P as weriftAudioBackend};
@@ -1,4 +1,4 @@
1
- "use strict";var xe=Object.create;var M=Object.defineProperty;var ke=Object.getOwnPropertyDescriptor;var be=Object.getOwnPropertyNames;var Ae=Object.getPrototypeOf,Se=Object.prototype.hasOwnProperty;var Ee=(t,e)=>{for(var n in e)M(t,n,{get:e[n],enumerable:!0})},ee=(t,e,n,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of be(e))!Se.call(t,r)&&r!==n&&M(t,r,{get:()=>e[r],enumerable:!(o=ke(e,r))||o.enumerable});return t};var te=(t,e,n)=>(n=t!=null?xe(Ae(t)):{},ee(e||!t||!t.__esModule?M(n,"default",{value:t,enumerable:!0}):n,t)),Re=t=>ee(M({},"__esModule",{value:!0}),t);var tt={};Ee(tt,{SessionPool:()=>O,URUN_API:()=>Y,coalesceSameRole:()=>he,createFileDiagnosticSink:()=>me,createUrunExtension:()=>_e,default:()=>et,makeSessionFactory:()=>fe,makeStreamSimple:()=>we,piDiagnosticLogPath:()=>ge,resolveSessionEnv:()=>de,toResponsesInput:()=>ye});module.exports=Re(tt);var Te=()=>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,_=Te();var ce=require("@earendil-works/pi-ai"),R=require("fs"),ue=te(require("os"),1),j=require("path");function ne(t,e,n,o){let r=t.response??{},l={request_id:n,consumer_id:o,stream:!0,kind:"chat",messages:e};return typeof r.instructions=="string"&&(l.instructions=r.instructions),Array.isArray(r.modalities)&&(l.modalities=r.modalities),typeof r.temperature=="number"&&(l.temperature=r.temperature),typeof r.max_output_tokens=="number"&&(l.max_output_tokens=r.max_output_tokens),r.tools!==void 0&&(l.tools=r.tools),l}function oe(t,e,n){let o={request_id:e,consumer_id:n,stream:!!t.stream,kind:"responses",input:t.input};return t.model&&(o.model=t.model),t.tools!==void 0&&(o.tools=t.tools),t.tool_choice!==void 0&&(o.tool_choice=t.tool_choice),typeof t.temperature=="number"&&(o.temperature=t.temperature),typeof t.max_output_tokens=="number"&&(o.max_output_tokens=t.max_output_tokens),o}function re(t){if(t instanceof Error)return{type:"error",error:{type:"urun_error",code:t.name||null,message:t.message}};if(t&&typeof t=="object"&&t.t==="error"){let e=t,n=e.body??{};return{type:"error",error:{type:"urun_error",code:e.code??null,message:n.message??"unknown error"}}}return{type:"error",error:{type:"urun_error",code:null,message:String(t)}}}var Ue="llm-resp";async function*G(t,e){let n=`${Ue}:${e}`,o=`resp_${e}`;yield{type:"response.created",response:{id:o,status:"in_progress"}};let r=new Map;for await(let l of t.stream(n).messages()){let i=l;if(i.t==="delta"){if(typeof i.delta=="string"&&(yield{type:"response.output_text.delta",item_id:o,delta:i.delta}),typeof i.reasoning=="string"&&(yield{type:"response.reasoning_text.delta",item_id:o,delta:i.reasoning}),Array.isArray(i.tool_calls))for(let p of i.tool_calls){let m=typeof p.index=="number"?p.index:0,a=r.get(m)??{};p.id&&(a.id=p.id),p.function?.name&&(a.name=p.function.name),r.set(m,a),yield{type:"response.function_call_arguments.delta",item_id:`fc_${e}_${m}`,tool_index:m,call_id:a.id,name:a.name,delta:p.function?.arguments??""}}}else if(i.t==="response"){yield{type:"response.completed",response:{id:o,status:"completed",...i.body}};return}else if(i.t==="error"){yield re(i);return}}}var Ie="llm",N=class{constructor(e){this.session=e}session;get consumerId(){return this.session.consumerId}write(e){this.session.doc(Ie).set({requests:{[e.request_id]:{payload:e,consumer_id:e.consumer_id,stream:e.stream}}})}sendResponses(e,n){let o=oe(e,n,this.consumerId);return this.write(o),G(this.session,n)}sendResponseCreate(e,n,o){let r=ne(e,n,o,this.consumerId);return this.write(r),G(this.session,o)}};var se=0;function Pe(){return se+=1,`req_${Date.now().toString(36)}_${se.toString(36)}`}var D=class{transport;constructor(e){this.transport=new N(e)}responses={create:async e=>{let n=Pe(),o=this.transport.sendResponses(e,n);return Object.assign((async function*(){yield*o})(),{requestId:n})}}};var B="https://api.urun.sh/v1";async function ie(t){let e=t.fetchImpl??fetch,n=`${t.apiUrl.replace(/\/+$/,"")}/apps`,o=await e(n,{headers:{Authorization:`Bearer ${t.apiKey}`,Accept:"application/json"}});if(!o.ok)throw new Error(`org apps listing failed: GET ${n} \u2192 ${o.status}`);let r=await o.json();if(!Array.isArray(r.apps))throw new Error(`org apps listing returned no "apps" array (GET ${n})`);if(r.truncated===!0)throw new Error(`org apps listing was truncated (GET ${n} returned ${r.apps.length} of more) \u2014 model discovery would silently omit deployed apps`);return r.apps}async function ae(t){let e=await ie(t),n=e.filter(o=>o.function_name===t.fnName&&o.deployment_status==="active").map(o=>o.app_slug);if(n.length===0)throw new Error(`urun pi extension: the org has no active deployed app exposing "${t.fnName}" (GET ${t.apiUrl}/apps returned ${e.length} app(s), none servable) \u2014 deploy one with \`urun serve <model>\` first`);return n.sort()}var Y="urun-serve",Ce="serve",Le=131072,$e=16384,le=3,Me=42e4,Ne=6e4,De=15e3;function Oe(t){let e=(t.URUN_API_KEY??"").trim();if(!e)throw new Error("urun pi extension: URUN_API_KEY is required \u2014 model discovery lists the org's deployed serve apps via the org API (URUN_JWT alone cannot list apps)");return{apiKey:e,apiUrl:(t.URUN_API_URL??"").trim()||B,fnName:(t.URUN_FUNCTION??"").trim()||Ce}}function de(t){let e=(t.URUN_BASE_URL??"").trim(),n=(t.URUN_ORG_ID??"").trim();if(!e)throw new Error("urun pi extension: URUN_BASE_URL is required to open a session");if(/\/v1\/*$/.test(new URL(e).pathname))throw new Error(`urun pi extension: URUN_BASE_URL must be the session-gateway base (e.g. https://api.urun.sh), got ${e} \u2014 a trailing /v1 is the org API form (URUN_API_URL); session allocation 404s against it. Drop the /v1.`);if(!n)throw new Error("urun pi extension: URUN_ORG_ID is required to open a session");let o=(t.URUN_JWT??"").trim();if(o)return{baseUrl:e,orgId:n,auth:{lane:"jwt",jwt:o}};let r=(t.URUN_API_KEY??"").trim();if(!r)throw new Error("urun pi extension: URUN_JWT or URUN_API_KEY is required to open a session");let l=(t.URUN_GATEWAY_URL??"").trim()||void 0;return{baseUrl:e,orgId:n,auth:{lane:"api-key",apiKey:r,gatewayUrl:l}}}function me(t){let e=null;return n=>{e===null&&((0,R.mkdirSync)((0,j.dirname)(t),{recursive:!0}),e=(0,R.openSync)(t,"a"));let o=n.detail?` ${JSON.stringify(n.detail)}`:"";(0,R.writeSync)(e,`${new Date().toISOString()} [${n.level}] [urun] ${n.message}${o}
2
- `)}}function ge(t=ue.default.homedir()){return(0,j.join)(t,".urun","logs","pi-extension.log")}function fe(t){let e=me(ge());return async(n,o,r)=>{let{baseUrl:l,orgId:i,auth:p}=de(n),{App:m,createClientToken:a}=await t(),v=(p.lane==="jwt"?m(o,{baseUrl:l,orgId:i,jwt:p.jwt,diagnosticSink:e}):m(o,{baseUrl:l,orgId:i,diagnosticSink:e,getAccessToken:async()=>(await a(p.apiKey,{baseUrl:p.gatewayUrl,expiresIn:300,allowedFunctions:[`${o}/${r}`]})).token}))[r];if(typeof v!="function")throw new Error(`urun pi extension: app "${o}" has no function "${r}"`);let h=v(),T=h.connect;return typeof T=="function"&&await T.call(h),h}}var je=fe(async()=>{let{createRequire:t}=await import("module"),e=t(_);if(typeof globalThis.RTCPeerConnection>"u")try{e.resolve("werift")}catch{throw new Error('urun pi extension: token streams require a WebRTC data channel, and this Node runtime has no RTCPeerConnection and no "werift" backend installed (@urun-sh/core\'s optional Node WebRTC backend \u2014 it was probably stripped by a --no-optional install). Install werift (`npm i werift`) and retry.')}return e("@urun-sh/core")});function Fe(t){try{Promise.resolve(t.close?.()).catch(()=>{})}catch{}}var O=class{constructor(e,n,o){this.open=e;this.env=n;this.fnName=o}open;env;fnName;pool=new Map;acquire(e){let n=this.pool.get(e);if(!n){let o=Promise.resolve(this.open(this.env,e,this.fnName)).then(r=>({session:r,responses:new D(r)}));n=o,this.pool.set(e,o),o.catch(()=>{this.pool.get(e)===o&&this.pool.delete(e)})}return n}evict(e){let n=this.pool.get(e);n&&(this.pool.delete(e),n.then(o=>Fe(o.session),()=>{}))}closeAll(){for(let e of[...this.pool.keys()])this.evict(e)}};function ye(t){let e=[];t.systemPrompt&&e.push({role:"system",content:t.systemPrompt});for(let n of t.messages){if(n.role==="toolResult"){e.push({type:"function_call_output",call_id:n.toolCallId,output:qe(n.content)});continue}if(n.role==="assistant"&&Array.isArray(n.content)){let r="",l=()=>{r&&(e.push({role:"assistant",content:r}),r="")};for(let i of n.content)if(i.type==="text")r+=String(i.text??"");else if(i.type==="toolCall")l(),e.push({type:"function_call",call_id:String(i.id??""),name:String(i.name??""),arguments:JSON.stringify(i.arguments??{})});else{if(i.type==="thinking")continue;throw new Error(`urun pi extension: unsupported assistant content part "${String(i.type)}"`)}l();continue}let o=n.role==="assistant"?"assistant":"user";e.push({role:o,content:Ke(n.content)})}return he(e)}function he(t){let e=[];for(let n of t){let o=e[e.length-1];o&&"role"in o&&"role"in n&&o.role===n.role?o.content=[o.content,n.content].filter(r=>r.length>0).join(`
1
+ "use strict";var be=Object.create;var D=Object.defineProperty;var Ae=Object.getOwnPropertyDescriptor;var Se=Object.getOwnPropertyNames;var Re=Object.getPrototypeOf,Ee=Object.prototype.hasOwnProperty;var Te=(t,e)=>{for(var n in e)D(t,n,{get:e[n],enumerable:!0})},Z=(t,e,n,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Se(e))!Ee.call(t,r)&&r!==n&&D(t,r,{get:()=>e[r],enumerable:!(o=Ae(e,r))||o.enumerable});return t};var ee=(t,e,n)=>(n=t!=null?be(Re(t)):{},Z(e||!t||!t.__esModule?D(n,"default",{value:t,enumerable:!0}):n,t)),Ie=t=>Z(D({},"__esModule",{value:!0}),t);var nt={};Te(nt,{SessionPool:()=>K,URUN_API:()=>Y,coalesceSameRole:()=>we,createFileDiagnosticSink:()=>ge,createUrunExtension:()=>ve,default:()=>tt,makeSessionFactory:()=>ye,makeStreamSimple:()=>_e,piDiagnosticLogPath:()=>fe,resolveSessionEnv:()=>me,toResponsesInput:()=>he});module.exports=Ie(nt);var Ue=()=>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,x=Ue();var ue=require("@earendil-works/pi-ai"),C=require("fs"),de=ee(require("os"),1),W=require("path");function te(t,e,n,o){let r=t.response??{},l={request_id:n,consumer_id:o,stream:!0,kind:"chat",messages:e};return typeof r.instructions=="string"&&(l.instructions=r.instructions),Array.isArray(r.modalities)&&(l.modalities=r.modalities),typeof r.temperature=="number"&&(l.temperature=r.temperature),typeof r.max_output_tokens=="number"&&(l.max_output_tokens=r.max_output_tokens),r.tools!==void 0&&(l.tools=r.tools),l}function ne(t,e,n){let o={request_id:e,consumer_id:n,stream:!!t.stream,kind:"responses",input:t.input};return t.model&&(o.model=t.model),t.tools!==void 0&&(o.tools=t.tools),t.tool_choice!==void 0&&(o.tool_choice=t.tool_choice),typeof t.temperature=="number"&&(o.temperature=t.temperature),typeof t.max_output_tokens=="number"&&(o.max_output_tokens=t.max_output_tokens),o}function oe(t){if(t instanceof Error)return{type:"error",error:{type:"urun_error",code:t.name||null,message:t.message}};if(t&&typeof t=="object"&&t.t==="error"){let e=t,n=e.body??{};return{type:"error",error:{type:"urun_error",code:e.code??null,message:n.message??"unknown error"}}}return{type:"error",error:{type:"urun_error",code:null,message:String(t)}}}var Pe="llm-resp";async function*B(t,e){let n=`${Pe}:${e}`,o=`resp_${e}`;yield{type:"response.created",response:{id:o,status:"in_progress"}};let r=new Map;for await(let l of t.stream(n).messages()){let i=l;if(i.t==="delta"){if(typeof i.delta=="string"&&(yield{type:"response.output_text.delta",item_id:o,delta:i.delta}),typeof i.reasoning=="string"&&(yield{type:"response.reasoning_text.delta",item_id:o,delta:i.reasoning}),Array.isArray(i.tool_calls))for(let p of i.tool_calls){let m=typeof p.index=="number"?p.index:0,a=r.get(m)??{};p.id&&(a.id=p.id),p.function?.name&&(a.name=p.function.name),r.set(m,a),yield{type:"response.function_call_arguments.delta",item_id:`fc_${e}_${m}`,tool_index:m,call_id:a.id,name:a.name,delta:p.function?.arguments??""}}}else if(i.t==="response"){yield{type:"response.completed",response:{id:o,status:"completed",...i.body}};return}else if(i.t==="error"){yield oe(i);return}}}var Ce="llm",j=class{constructor(e){this.session=e;this.sessionTag=e.sessionId??globalThis.crypto.randomUUID()}session;sessionTag;get consumerId(){return this.session.consumerId}write(e){e.session_tag=this.sessionTag,this.session.doc(Ce).set({requests:{[e.request_id]:{payload:e,consumer_id:e.consumer_id,stream:e.stream}}})}sendResponses(e,n){let o=ne(e,n,this.consumerId);return this.write(o),B(this.session,n)}sendResponseCreate(e,n,o){let r=te(e,n,o,this.consumerId);return this.write(r),B(this.session,o)}};var re=0;function $e(){return re+=1,`req_${Date.now().toString(36)}_${re.toString(36)}`}var F=class{transport;constructor(e){this.transport=new j(e)}responses={create:async e=>{let n=$e(),o=this.transport.sendResponses(e,n);return Object.assign((async function*(){yield*o})(),{requestId:n})}}};var H="https://api.urun.sh/v1";async function se(t){let e=t.fetchImpl??fetch,n=`${t.apiUrl.replace(/\/+$/,"")}/apps`,o=await e(n,{headers:{Authorization:`Bearer ${t.apiKey}`,Accept:"application/json"}});if(!o.ok)throw new Error(`org apps listing failed: GET ${n} \u2192 ${o.status}`);let r=await o.json();if(!Array.isArray(r.apps))throw new Error(`org apps listing returned no "apps" array (GET ${n})`);if(r.truncated===!0)throw new Error(`org apps listing was truncated (GET ${n} returned ${r.apps.length} of more) \u2014 model discovery would silently omit deployed apps`);return r.apps}async function ie(t){let e=await se(t),n=e.filter(o=>o.function_name===t.fnName&&o.deployment_status==="active").map(o=>o.app_slug);if(n.length===0)throw new Error(`urun pi extension: the org has no active deployed app exposing "${t.fnName}" (GET ${t.apiUrl}/apps returned ${e.length} app(s), none servable) \u2014 deploy one with \`urun serve <model>\` first`);return n.sort()}var Y="urun-serve",Le="serve",Me=131072,Ne=16384,ae=3,Oe=42e4,De=6e4,le=2,je=15e3;function Fe(t){let e=(t.URUN_API_KEY??"").trim();if(!e)throw new Error("urun pi extension: URUN_API_KEY is required \u2014 model discovery lists the org's deployed serve apps via the org API (URUN_JWT alone cannot list apps)");return{apiKey:e,apiUrl:(t.URUN_API_URL??"").trim()||H,fnName:(t.URUN_FUNCTION??"").trim()||Le}}function me(t){let e=(t.URUN_BASE_URL??"").trim(),n=(t.URUN_ORG_ID??"").trim();if(!e)throw new Error("urun pi extension: URUN_BASE_URL is required to open a session");if(/\/v1\/*$/.test(new URL(e).pathname))throw new Error(`urun pi extension: URUN_BASE_URL must be the session-gateway base (e.g. https://api.urun.sh), got ${e} \u2014 a trailing /v1 is the org API form (URUN_API_URL); session allocation 404s against it. Drop the /v1.`);if(!n)throw new Error("urun pi extension: URUN_ORG_ID is required to open a session");let o=(t.URUN_JWT??"").trim();if(o)return{baseUrl:e,orgId:n,auth:{lane:"jwt",jwt:o}};let r=(t.URUN_API_KEY??"").trim();if(!r)throw new Error("urun pi extension: URUN_JWT or URUN_API_KEY is required to open a session");let l=(t.URUN_GATEWAY_URL??"").trim()||void 0;return{baseUrl:e,orgId:n,auth:{lane:"api-key",apiKey:r,gatewayUrl:l}}}function ge(t){let e=null;return n=>{e===null&&((0,C.mkdirSync)((0,W.dirname)(t),{recursive:!0}),e=(0,C.openSync)(t,"a"));let o=n.detail?` ${JSON.stringify(n.detail)}`:"";(0,C.writeSync)(e,`${new Date().toISOString()} [${n.level}] [urun] ${n.message}${o}
2
+ `)}}function fe(t=de.default.homedir()){return(0,W.join)(t,".urun","logs","pi-extension.log")}function ye(t){let e=ge(fe());return async(n,o,r)=>{let{baseUrl:l,orgId:i,auth:p}=me(n),{App:m,createClientToken:a}=await t(),_=(p.lane==="jwt"?m(o,{baseUrl:l,orgId:i,jwt:p.jwt,diagnosticSink:e}):m(o,{baseUrl:l,orgId:i,diagnosticSink:e,getAccessToken:async()=>(await a(p.apiKey,{baseUrl:p.gatewayUrl,expiresIn:300,allowedFunctions:[`${o}/${r}`]})).token}))[r];if(typeof _!="function")throw new Error(`urun pi extension: app "${o}" has no function "${r}"`);let y=_();if(typeof y.end!="function")throw new Error(`urun pi extension: app "${o}" function "${r}" returned a session without end()`);let T=y.connect;return typeof T=="function"&&await T.call(y),y}}var Ke=ye(async()=>{let{createRequire:t}=await import("module"),e=t(x);if(typeof globalThis.RTCPeerConnection>"u")try{e.resolve("werift")}catch{throw new Error('urun pi extension: token streams require a WebRTC data channel, and this Node runtime has no RTCPeerConnection and no "werift" backend installed (@urun-sh/core\'s optional Node WebRTC backend \u2014 it was probably stripped by a --no-optional install). Install werift (`npm i werift`) and retry.')}return e("@urun-sh/core")});function qe(t){try{Promise.resolve(t.end()).catch(()=>{})}catch{}}var K=class{constructor(e,n,o){this.open=e;this.env=n;this.fnName=o}open;env;fnName;pool=new Map;acquire(e){let n=this.pool.get(e);if(!n){let o=Promise.resolve(this.open(this.env,e,this.fnName)).then(r=>({session:r,responses:new F(r)}));n=o,this.pool.set(e,o),o.catch(()=>{this.pool.get(e)===o&&this.pool.delete(e)})}return n}evict(e){let n=this.pool.get(e);n&&(this.pool.delete(e),n.then(o=>qe(o.session),()=>{}))}closeAll(){for(let e of[...this.pool.keys()])this.evict(e)}};function he(t){let e=[];t.systemPrompt&&e.push({role:"system",content:t.systemPrompt});for(let n of t.messages){if(n.role==="toolResult"){e.push({type:"function_call_output",call_id:n.toolCallId,output:Je(n.content)});continue}if(n.role==="assistant"&&Array.isArray(n.content)){let r="",l=()=>{r&&(e.push({role:"assistant",content:r}),r="")};for(let i of n.content)if(i.type==="text")r+=String(i.text??"");else if(i.type==="toolCall")l(),e.push({type:"function_call",call_id:String(i.id??""),name:String(i.name??""),arguments:JSON.stringify(i.arguments??{})});else{if(i.type==="thinking")continue;throw new Error(`urun pi extension: unsupported assistant content part "${String(i.type)}"`)}l();continue}let o=n.role==="assistant"?"assistant":"user";e.push({role:o,content:We(n.content)})}return we(e)}function we(t){let e=[];for(let n of t){let o=e[e.length-1];o&&"role"in o&&"role"in n&&o.role===n.role?o.content=[o.content,n.content].filter(r=>r.length>0).join(`
3
3
 
4
- `):e.push({...n})}return e}function Ke(t){return typeof t=="string"?t:Array.isArray(t)?t.map(e=>e&&typeof e=="object"&&"text"in e?String(e.text):"").join(""):""}function qe(t){if(typeof t=="string")return t;if(!Array.isArray(t))return"";let e="";for(let n of t){let o=String(n.type??"");if(o!=="text")throw new Error(`urun pi extension: unsupported toolResult content part "${o}" \u2014 the serve lane carries text tool results only`);e+=String(n.text??"")}return e}function We(t){if(!(!Array.isArray(t)||t.length===0))return t.map(e=>({type:"function",name:e.name,description:e.description,parameters:e.parameters}))}function pe(t,e){if(!e.trim())return{};try{return JSON.parse(e)}catch{throw new Error(`uRun serve error: tool call "${t}" arguments are not valid JSON: ${e}`)}}function Je(t){let e=t?.output;return Array.isArray(e)?e.filter(n=>n.type==="function_call"):[]}function Ge(t){let e=t?.output;if(!Array.isArray(e))return"";let n="";for(let o of e)if(!(o.type!=="reasoning"||!Array.isArray(o.content)))for(let r of o.content)r.type==="reasoning_text"&&(n+=String(r.text??""));return n}var Be=["<tool_call>","<function="];function Ye(t,e){let n=Be.find(o=>e.includes(o));if(n)return new Error(`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 He(t){let e=t instanceof Error?t.message:String(t),n=t?.code;return/\b529\b/.test(e)||/overloaded/i.test(e)||n===529||n==="529"}function Xe(t){return new Promise(e=>setTimeout(e,t))}function ze(t,e,n,o){return new Promise((r,l)=>{let i=!1,p=s=>{i||(i=!0,clearTimeout(m),o?.removeEventListener("abort",a),s())},m=setTimeout(()=>p(()=>l(n())),e),a=()=>p(()=>l(new Error("aborted")));if(o?.aborted){a();return}o?.addEventListener("abort",a,{once:!0}),Promise.resolve(t).then(s=>p(()=>r(s)),s=>p(()=>l(s)))})}async function*Qe(t,e){let n=t[Symbol.asyncIterator](),o,r=new Promise((l,i)=>{o=()=>i(new Error("aborted")),e.addEventListener("abort",o,{once:!0})});try{for(;;){if(e.aborted)throw new Error("aborted");let l=await Promise.race([n.next(),r]);if(l.done)return;yield l.value}}finally{o&&e.removeEventListener("abort",o),n.return?.(void 0)}}function Ve(t,e){let n=t?.sendMessage;if(typeof n=="function")try{n.call(t,{customType:"urun-status",content:e,display:!0},{triggerTurn:!1})}catch{}}function we(t,e={},n){let o=e.connectDeadlineMs??Me,r=e.stallTimeoutMs??Ne,l=e.phaseHeartbeatMs??De;return(i,p,m)=>{let a=(0,ce.createAssistantMessageEventStream)(),s={role:"assistant",content:[],api:i.api,provider:i.provider,model:i.id,usage:{input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},stopReason:"stop",timestamp:Date.now()},v=new AbortController,h=m?.signal,T=!1,P=()=>{T=!0,v.abort()};h&&(h.aborted?P():h.addEventListener("abort",P,{once:!0}));let F=!1,S,H=()=>{S&&clearTimeout(S),S=setTimeout(()=>{F=!0,v.abort()},r)},K=()=>{S&&clearTimeout(S),S=void 0},x=null,k=null,f=null,X="",C=!1,q=()=>{if(!k)return;let d=k;k=null,a.push({type:"thinking_end",contentIndex:s.content.indexOf(d),content:d.thinking,partial:s})},z=()=>{if(!x)return;let d=x;x=null,a.push({type:"text_end",contentIndex:s.content.indexOf(d),content:d.text,partial:s})},W=()=>{if(!f)return;let{call:d,args:y,contentIndex:b}=f;f=null,d.arguments=pe(d.name,y),a.push({type:"toolcall_end",contentIndex:b,toolCall:d,partial:s})},ve=d=>{let y={type:"toolCall",id:String(d.call_id??d.id??`call_${s.content.length}`),name:String(d.name??""),arguments:{}};s.content.push(y);let b=s.content.length-1;a.push({type:"toolcall_start",contentIndex:b,partial:s});let U=typeof d.arguments=="string"?d.arguments:"";U&&a.push({type:"toolcall_delta",contentIndex:b,delta:U,partial:s}),y.arguments=pe(y.name,U),a.push({type:"toolcall_end",contentIndex:b,toolCall:y,partial:s})};return(async()=>{a.push({type:"start",partial:s});let d=!1,y,b=()=>{y&&clearInterval(y),y=void 0},U=Date.now();y=setInterval(()=>{let A=Math.round((Date.now()-U)/1e3);Ve(n,`uRun: still opening the "${i.id}" session\u2026 (${A}s \u2014 serve apps scale to zero, first turn can cold-start ~6min)`)},l);try{let{responses:A}=await ze(t.acquire(i.id),o,()=>new Error(`uRun session for "${i.id}" did not connect within ${Math.round(o/1e3)}s \u2014 likely cold-starting (scaled to zero) or queued behind capacity. Retry shortly.`),v.signal);b();let J=ye(p),L,$;for(let u=1;u<=le;u++)try{let w=await A.responses.create({model:i.id,input:J,stream:!0,tools:We(p.tools),max_output_tokens:i.maxTokens});H();for await(let I of Qe(w,v.signal)){H();let g=I;if(g.type==="response.output_text.delta"){let c=typeof g.delta=="string"?g.delta:"";c&&(C=!0,q(),W(),x||(x={type:"text",text:""},s.content.push(x),a.push({type:"text_start",contentIndex:s.content.length-1,partial:s})),x.text+=c,X+=c,a.push({type:"text_delta",contentIndex:s.content.indexOf(x),delta:c,partial:s}))}else if(g.type==="response.reasoning_text.delta"){let c=typeof g.delta=="string"?g.delta:"";c&&(C=!0,k||(k={type:"thinking",thinking:""},s.content.push(k),a.push({type:"thinking_start",contentIndex:s.content.length-1,partial:s})),k.thinking+=c,a.push({type:"thinking_delta",contentIndex:s.content.indexOf(k),delta:c,partial:s}))}else if(g.type==="response.function_call_arguments.delta"&&typeof g.tool_index=="number"){let c=g;if(C=!0,q(),z(),!f||f.toolIndex!==c.tool_index){W();let Z={type:"toolCall",id:c.call_id??`call_${c.tool_index}`,name:c.name??"",arguments:{}};s.content.push(Z),f={call:Z,args:"",contentIndex:s.content.length-1,toolIndex:c.tool_index},a.push({type:"toolcall_start",contentIndex:f.contentIndex,partial:s})}c.call_id&&(f.call.id=c.call_id),c.name&&(f.call.name=c.name);let E=typeof c.delta=="string"?c.delta:"";E&&(f.args+=E,a.push({type:"toolcall_delta",contentIndex:f.contentIndex,delta:E,partial:s}))}else if(g.type==="response.completed"){L=g.response;break}else if(g.type==="error"){let c=g.error,E=new Error(`uRun serve error: ${c?.message??"unknown error"}`);throw E.code=c?.code??null,E}}$=void 0;break}catch(w){if($=w,v.signal.aborted)throw w;if(u<le&&He(w)&&!C){await Xe(u*500);continue}throw w}if($)throw $;if(K(),q(),z(),W(),!s.content.some(u=>u.type==="toolCall"))for(let u of Je(L))ve(u);if(!s.content.some(u=>u.type==="thinking")){let u=Ge(L);if(u){let w={type:"thinking",thinking:""};s.content.push(w);let I=s.content.length-1;a.push({type:"thinking_start",contentIndex:I,partial:s}),w.thinking=u,a.push({type:"thinking_delta",contentIndex:I,delta:u,partial:s}),a.push({type:"thinking_end",contentIndex:I,content:u,partial:s})}}let Q=s.content.filter(u=>u.type==="toolCall").length;if((p.tools?.length??0)>0&&Q===0){let u=Ye(i.id,X);if(u)throw u}let V=Q>0?"toolUse":L?.status==="incomplete"?"length":"stop";s.stopReason=V,a.push({type:"done",reason:V,message:s}),a.end(s)}catch(A){if(d=!0,K(),T||h?.aborted&&!F)s.stopReason="aborted",s.errorMessage="aborted by user",a.push({type:"error",reason:"aborted",error:s});else{let J=F?`uRun stream stalled \u2014 no output for ${Math.round(r/1e3)}s; the model may be hung. Retry, or Ctrl-C to abort.`:A instanceof Error?A.message:String(A);s.stopReason="error",s.errorMessage=J,a.push({type:"error",reason:"error",error:s})}a.end(s)}finally{K(),b(),h&&h.removeEventListener("abort",P),d&&t.evict(i.id)}})(),a}}function Ze(t){return{id:t,name:`uRun ${t}`,api:Y,reasoning:!0,input:["text"],cost:{input:0,output:0,cacheRead:0,cacheWrite:0},contextWindow:Le,maxTokens:$e}}function _e(t={}){return async e=>{let n=t.env??process.env,{apiKey:o,apiUrl:r,fnName:l}=Oe(n),i=await ae({apiUrl:r,apiKey:o,fnName:l,fetchImpl:t.fetchImpl}),p=new O(t.openSession??je,n,l);e.on("session_shutdown",()=>p.closeAll());let m={name:"uRun",api:Y,baseUrl:"urun://session",apiKey:"$URUN_API_KEY",models:i.map(Ze),streamSimple:we(p,t.timing??{},e)};e.registerProvider("urun",m)}}var et=_e();0&&(module.exports={SessionPool,URUN_API,coalesceSameRole,createFileDiagnosticSink,createUrunExtension,makeSessionFactory,makeStreamSimple,piDiagnosticLogPath,resolveSessionEnv,toResponsesInput});
4
+ `):e.push({...n})}return e}function We(t){return typeof t=="string"?t:Array.isArray(t)?t.map(e=>e&&typeof e=="object"&&"text"in e?String(e.text):"").join(""):""}function Je(t){if(typeof t=="string")return t;if(!Array.isArray(t))return"";let e="";for(let n of t){let o=String(n.type??"");if(o!=="text")throw new Error(`urun pi extension: unsupported toolResult content part "${o}" \u2014 the serve lane carries text tool results only`);e+=String(n.text??"")}return e}function Ge(t){if(!(!Array.isArray(t)||t.length===0))return t.map(e=>({type:"function",name:e.name,description:e.description,parameters:e.parameters}))}function pe(t,e){if(!e.trim())return{};try{return JSON.parse(e)}catch{throw new Error(`uRun serve error: tool call "${t}" arguments are not valid JSON: ${e}`)}}function Be(t){let e=t?.output;return Array.isArray(e)?e.filter(n=>n.type==="function_call"):[]}function He(t){let e=t?.output;if(!Array.isArray(e))return"";let n="";for(let o of e)if(!(o.type!=="reasoning"||!Array.isArray(o.content)))for(let r of o.content)r.type==="reasoning_text"&&(n+=String(r.text??""));return n}var Ye=["<tool_call>","<function="];function Xe(t,e){let n=Ye.find(o=>e.includes(o));if(n)return new Error(`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)`)}var q=class extends Error{};function ze(t){let e=t instanceof Error?t.message:String(t),n=t?.code;return/\b529\b/.test(e)||/overloaded/i.test(e)||n===529||n==="529"}function Qe(t){return new Promise(e=>setTimeout(e,t))}function Ve(t,e,n,o){return new Promise((r,l)=>{let i=!1,p=s=>{i||(i=!0,clearTimeout(m),o?.removeEventListener("abort",a),s())},m=setTimeout(()=>p(()=>l(n())),e),a=()=>p(()=>l(new Error("aborted")));if(o?.aborted){a();return}o?.addEventListener("abort",a,{once:!0}),Promise.resolve(t).then(s=>p(()=>r(s)),s=>p(()=>l(s)))})}async function*Ze(t,e){let n=t[Symbol.asyncIterator](),o,r=new Promise((l,i)=>{o=()=>i(new Error("aborted")),e.addEventListener("abort",o,{once:!0})});try{for(;;){if(e.aborted)throw new Error("aborted");let l=await Promise.race([n.next(),r]);if(l.done)return;yield l.value}}finally{o&&e.removeEventListener("abort",o),n.return?.(void 0)}}function ce(t,e){let n=t?.sendMessage;if(typeof n=="function")try{n.call(t,{customType:"urun-status",content:e,display:!0},{triggerTurn:!1})}catch{}}function _e(t,e={},n){let o=e.connectDeadlineMs??Oe,r=e.stallTimeoutMs??De,l=e.phaseHeartbeatMs??je;return(i,p,m)=>{let a=(0,ue.createAssistantMessageEventStream)(),s={role:"assistant",content:[],api:i.api,provider:i.provider,model:i.id,usage:{input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},stopReason:"stop",timestamp:Date.now()},_=new AbortController,y=m?.signal,T=!1,N=()=>{T=!0,_.abort()};y&&(y.aborted?N():y.addEventListener("abort",N,{once:!0}));let $=!1,I,X=()=>{I&&clearTimeout(I),I=setTimeout(()=>{$=!0,_.abort()},r)},O=()=>{I&&clearTimeout(I),I=void 0},k=null,b=null,h=null,z="",L=!1,J=()=>{if(!b)return;let d=b;b=null,a.push({type:"thinking_end",contentIndex:s.content.indexOf(d),content:d.thinking,partial:s})},Q=()=>{if(!k)return;let d=k;k=null,a.push({type:"text_end",contentIndex:s.content.indexOf(d),content:d.text,partial:s})},G=()=>{if(!h)return;let{call:d,args:w,contentIndex:A}=h;h=null,d.arguments=pe(d.name,w),a.push({type:"toolcall_end",contentIndex:A,toolCall:d,partial:s})},xe=d=>{let w={type:"toolCall",id:String(d.call_id??d.id??`call_${s.content.length}`),name:String(d.name??""),arguments:{}};s.content.push(w);let A=s.content.length-1;a.push({type:"toolcall_start",contentIndex:A,partial:s});let M=typeof d.arguments=="string"?d.arguments:"";M&&a.push({type:"toolcall_delta",contentIndex:A,delta:M,partial:s}),w.arguments=pe(w.name,M),a.push({type:"toolcall_end",contentIndex:A,toolCall:w,partial:s})};return(async()=>{a.push({type:"start",partial:s});let d=!1,w,A=()=>{w&&clearInterval(w),w=void 0},M=Date.now();w=setInterval(()=>{let v=Math.round((Date.now()-M)/1e3);ce(n,`uRun: still opening the "${i.id}" session\u2026 (${v}s \u2014 serve apps scale to zero, first turn can cold-start ~6min)`)},l);let ke=async v=>{let{responses:S}=await Ve(t.acquire(i.id),o,()=>new Error(`uRun session for "${i.id}" did not connect within ${Math.round(o/1e3)}s \u2014 likely cold-starting (scaled to zero) or queued behind capacity. Retry shortly.`),_.signal);A();let U,R;for(let c=1;c<=ae;c++)try{let f=await S.responses.create({model:i.id,input:v,stream:!0,tools:Ge(p.tools),max_output_tokens:i.maxTokens});X();for await(let E of Ze(f,_.signal)){X();let g=E;if(g.type==="response.output_text.delta"){let u=typeof g.delta=="string"?g.delta:"";u&&(L=!0,J(),G(),k||(k={type:"text",text:""},s.content.push(k),a.push({type:"text_start",contentIndex:s.content.length-1,partial:s})),k.text+=u,z+=u,a.push({type:"text_delta",contentIndex:s.content.indexOf(k),delta:u,partial:s}))}else if(g.type==="response.reasoning_text.delta"){let u=typeof g.delta=="string"?g.delta:"";u&&(L=!0,b||(b={type:"thinking",thinking:""},s.content.push(b),a.push({type:"thinking_start",contentIndex:s.content.length-1,partial:s})),b.thinking+=u,a.push({type:"thinking_delta",contentIndex:s.content.indexOf(b),delta:u,partial:s}))}else if(g.type==="response.function_call_arguments.delta"&&typeof g.tool_index=="number"){let u=g;if(L=!0,J(),Q(),!h||h.toolIndex!==u.tool_index){G();let V={type:"toolCall",id:u.call_id??`call_${u.tool_index}`,name:u.name??"",arguments:{}};s.content.push(V),h={call:V,args:"",contentIndex:s.content.length-1,toolIndex:u.tool_index},a.push({type:"toolcall_start",contentIndex:h.contentIndex,partial:s})}u.call_id&&(h.call.id=u.call_id),u.name&&(h.call.name=u.name);let P=typeof u.delta=="string"?u.delta:"";P&&(h.args+=P,a.push({type:"toolcall_delta",contentIndex:h.contentIndex,delta:P,partial:s}))}else if(g.type==="response.completed"){U=g.response;break}else if(g.type==="error"){let u=g.error,P=new Error(`uRun serve error: ${u?.message??"unknown error"}`);throw P.code=u?.code??null,P}}if(!U)throw new q(`uRun backhaul for "${i.id}" closed before the turn completed \u2014 the serving session ended mid-turn (its pod was restarted, drained or deleted).`);R=void 0;break}catch(f){if(R=f,_.signal.aborted)throw f;if(c<ae&&ze(f)&&!L){await Qe(c*500);continue}throw f}if(R)throw R;return U};try{let v=he(p),S;for(let c=1;c<=le;c++)try{S=await ke(v);break}catch(f){let E=$||f instanceof q;if(c>=le||!E||L||T)throw f;O(),t.evict(i.id),$=!1,_=new AbortController,ce(n,`uRun: the "${i.id}" session ended mid-turn \u2014 re-homing to a fresh assignment and replaying the turn\u2026`)}if(O(),J(),Q(),G(),!s.content.some(c=>c.type==="toolCall"))for(let c of Be(S))xe(c);if(!s.content.some(c=>c.type==="thinking")){let c=He(S);if(c){let f={type:"thinking",thinking:""};s.content.push(f);let E=s.content.length-1;a.push({type:"thinking_start",contentIndex:E,partial:s}),f.thinking=c,a.push({type:"thinking_delta",contentIndex:E,delta:c,partial:s}),a.push({type:"thinking_end",contentIndex:E,content:c,partial:s})}}let U=s.content.filter(c=>c.type==="toolCall").length;if((p.tools?.length??0)>0&&U===0){let c=Xe(i.id,z);if(c)throw c}let R=U>0?"toolUse":S?.status==="incomplete"?"length":"stop";s.stopReason=R,a.push({type:"done",reason:R,message:s}),a.end(s)}catch(v){if(d=!0,O(),T||y?.aborted&&!$)s.stopReason="aborted",s.errorMessage="aborted by user",a.push({type:"error",reason:"aborted",error:s});else{let S=$?`uRun stream stalled \u2014 no output for ${Math.round(r/1e3)}s; the model may be hung. Retry, or Ctrl-C to abort.`:v instanceof Error?v.message:String(v);s.stopReason="error",s.errorMessage=S,a.push({type:"error",reason:"error",error:s})}a.end(s)}finally{O(),A(),y&&y.removeEventListener("abort",N),d&&t.evict(i.id)}})(),a}}function et(t){return{id:t,name:`uRun ${t}`,api:Y,reasoning:!0,input:["text"],cost:{input:0,output:0,cacheRead:0,cacheWrite:0},contextWindow:Me,maxTokens:Ne}}function ve(t={}){return async e=>{let n=t.env??process.env,{apiKey:o,apiUrl:r,fnName:l}=Fe(n),i=await ie({apiUrl:r,apiKey:o,fnName:l,fetchImpl:t.fetchImpl}),p=new K(t.openSession??Ke,n,l);e.on("session_shutdown",()=>p.closeAll());let m={name:"uRun",api:Y,baseUrl:"urun://session",apiKey:"$URUN_API_KEY",models:i.map(et),streamSimple:_e(p,t.timing??{},e)};e.registerProvider("urun",m)}}var tt=ve();0&&(module.exports={SessionPool,URUN_API,coalesceSameRole,createFileDiagnosticSink,createUrunExtension,makeSessionFactory,makeStreamSimple,piDiagnosticLogPath,resolveSessionEnv,toResponsesInput});
@@ -1,6 +1,6 @@
1
1
  import { ExtensionAPI } from '@earendil-works/pi-coding-agent';
2
2
  import { Api, Model, Context, SimpleStreamOptions, AssistantMessageEventStream } from '@earendil-works/pi-ai';
3
- import { a as UrunSessionLike, U as UrunResponses } from '../ResponsesClient-DF39QXq1.cjs';
3
+ import { a as UrunSessionLike, U as UrunResponses } from '../ResponsesClient-DrccxHTc.cjs';
4
4
 
5
5
  /**
6
6
  * Pi coding-agent extension: register the `urun` model provider, with one pi
@@ -53,12 +53,13 @@ import { a as UrunSessionLike, U as UrunResponses } from '../ResponsesClient-DF3
53
53
  * 3. ABORT/CANCEL (loud contract): the Responses lane has NO request-cancel
54
54
  * primitive (`SdkTransport.sendResponses` writes an envelope and the
55
55
  * decode loop just reads the reply lane), so Ctrl-C / the stall watchdog
56
- * stop consuming AND evict+close the pooled session tearing down the
57
- * WebRTC transport is what stops server-side generation. A clean turn
58
- * keeps its session for the next turn; a failed/aborted/stalled turn
59
- * always reopens.
60
- * 4. cleanup: pooled sessions are released (`session.close()`) on pi's
61
- * `session_shutdown` lifecycle event.
56
+ * stop consuming AND evict+END the pooled session (core's own
57
+ * `Session.end()`) — tearing down the WebRTC transport is what stops
58
+ * server-side generation. A clean turn keeps its session for the next
59
+ * turn; a failed/aborted/stalled turn always reopens — and a turn whose
60
+ * session DIED re-homes once and replays (see REHOME_ATTEMPTS).
61
+ * 4. cleanup: pooled sessions are released (core's `Session.end()`) on
62
+ * pi's `session_shutdown` lifecycle event.
62
63
  *
63
64
  * RUNTIME DEPENDENCY STORY (owner requirement — stated honestly): token
64
65
  * streams are named-DATA session streams, i.e. SCTP data channels over
@@ -118,8 +119,18 @@ declare function resolveSessionEnv(env: NodeJS.ProcessEnv): {
118
119
  * `@urun-sh/core`.
119
120
  */
120
121
  interface SessionFactory {
121
- (env: NodeJS.ProcessEnv, appSlug: string, fnName: string): Promise<UrunSessionLike> | UrunSessionLike;
122
+ (env: NodeJS.ProcessEnv, appSlug: string, fnName: string): Promise<OwnedSession> | OwnedSession;
122
123
  }
124
+ /**
125
+ * A session this lane OWNS: core's transport surface plus core's own terminal
126
+ * release, `Session.end()` (the same requirement the compat proxy asserts in
127
+ * `sessionOf`). A session without it could never be released — it would leak
128
+ * the backend session and its capacity lease until the platform's abandonment
129
+ * backstop reclaimed it — so the factory refuses to hand one back.
130
+ */
131
+ type OwnedSession = UrunSessionLike & {
132
+ end: () => Promise<unknown>;
133
+ };
123
134
  /** The structured diagnostic shape core's transports emit (typed locally). */
124
135
  interface CoreDiagnosticLike {
125
136
  level: string;
@@ -173,7 +184,7 @@ declare function piDiagnosticLogPath(home?: string): string;
173
184
  declare function makeSessionFactory(loadCore: () => Promise<CoreModuleLike> | CoreModuleLike): SessionFactory;
174
185
  /** One pooled backhaul: the session plus its Responses client (cli.ts shape). */
175
186
  interface PoolEntry {
176
- session: UrunSessionLike;
187
+ session: OwnedSession;
177
188
  responses: UrunResponses;
178
189
  }
179
190
  /**
@@ -254,4 +265,4 @@ declare function createUrunExtension(opts?: UrunExtensionOptions): (pi: Extensio
254
265
  /** The pi extension factory (default export — what pi's loader invokes). */
255
266
  declare const _default: (pi: ExtensionAPI) => Promise<void>;
256
267
 
257
- export { type CoreDiagnosticLike, type CoreModuleLike, type ResponsesInputItem, type SessionFactory, SessionPool, type StreamTiming, URUN_API, type UrunExtensionOptions, coalesceSameRole, createFileDiagnosticSink, createUrunExtension, _default as default, makeSessionFactory, makeStreamSimple, piDiagnosticLogPath, resolveSessionEnv, toResponsesInput };
268
+ export { type CoreDiagnosticLike, type CoreModuleLike, type OwnedSession, type ResponsesInputItem, type SessionFactory, SessionPool, type StreamTiming, URUN_API, type UrunExtensionOptions, coalesceSameRole, createFileDiagnosticSink, createUrunExtension, _default as default, makeSessionFactory, makeStreamSimple, piDiagnosticLogPath, resolveSessionEnv, toResponsesInput };
@@ -1,6 +1,6 @@
1
1
  import { ExtensionAPI } from '@earendil-works/pi-coding-agent';
2
2
  import { Api, Model, Context, SimpleStreamOptions, AssistantMessageEventStream } from '@earendil-works/pi-ai';
3
- import { a as UrunSessionLike, U as UrunResponses } from '../ResponsesClient-DF39QXq1.js';
3
+ import { a as UrunSessionLike, U as UrunResponses } from '../ResponsesClient-DrccxHTc.js';
4
4
 
5
5
  declare const URUN_API: Api;
6
6
 
@@ -18,9 +18,13 @@ declare function resolveSessionEnv(env: NodeJS.ProcessEnv): {
18
18
  };
19
19
 
20
20
  interface SessionFactory {
21
- (env: NodeJS.ProcessEnv, appSlug: string, fnName: string): Promise<UrunSessionLike> | UrunSessionLike;
21
+ (env: NodeJS.ProcessEnv, appSlug: string, fnName: string): Promise<OwnedSession> | OwnedSession;
22
22
  }
23
23
 
24
+ type OwnedSession = UrunSessionLike & {
25
+ end: () => Promise<unknown>;
26
+ };
27
+
24
28
  interface CoreDiagnosticLike {
25
29
  level: string;
26
30
  kind: string;
@@ -51,7 +55,7 @@ declare function piDiagnosticLogPath(home?: string): string;
51
55
  declare function makeSessionFactory(loadCore: () => Promise<CoreModuleLike> | CoreModuleLike): SessionFactory;
52
56
 
53
57
  interface PoolEntry {
54
- session: UrunSessionLike;
58
+ session: OwnedSession;
55
59
  responses: UrunResponses;
56
60
  }
57
61
 
@@ -105,4 +109,4 @@ declare function createUrunExtension(opts?: UrunExtensionOptions): (pi: Extensio
105
109
 
106
110
  declare const _default: (pi: ExtensionAPI) => Promise<void>;
107
111
 
108
- export { type CoreDiagnosticLike, type CoreModuleLike, type ResponsesInputItem, type SessionFactory, SessionPool, type StreamTiming, URUN_API, type UrunExtensionOptions, coalesceSameRole, createFileDiagnosticSink, createUrunExtension, _default as default, makeSessionFactory, makeStreamSimple, piDiagnosticLogPath, resolveSessionEnv, toResponsesInput };
112
+ export { type CoreDiagnosticLike, type CoreModuleLike, type OwnedSession, type ResponsesInputItem, type SessionFactory, SessionPool, type StreamTiming, URUN_API, type UrunExtensionOptions, coalesceSameRole, createFileDiagnosticSink, createUrunExtension, _default as default, makeSessionFactory, makeStreamSimple, piDiagnosticLogPath, resolveSessionEnv, toResponsesInput };
@@ -1,4 +1,4 @@
1
- import{c as B}from"../chunk-DYBS3NLC.js";import{a as D,c as H}from"../chunk-PS4BLX7J.js";import{createAssistantMessageEventStream as te}from"@earendil-works/pi-ai";import{mkdirSync as ne,openSync as oe,writeSync as re}from"fs";import se from"os";import{dirname as ie,join as ae}from"path";async function Y(t){let e=await H(t),n=e.filter(o=>o.function_name===t.fnName&&o.deployment_status==="active").map(o=>o.app_slug);if(n.length===0)throw new Error(`urun pi extension: the org has no active deployed app exposing "${t.fnName}" (GET ${t.apiUrl}/apps returned ${e.length} app(s), none servable) \u2014 deploy one with \`urun serve <model>\` first`);return n.sort()}var Q="urun-serve",le="serve",ce=131072,ue=16384,X=3,pe=42e4,de=6e4,fe=15e3;function ge(t){let e=(t.URUN_API_KEY??"").trim();if(!e)throw new Error("urun pi extension: URUN_API_KEY is required \u2014 model discovery lists the org's deployed serve apps via the org API (URUN_JWT alone cannot list apps)");return{apiKey:e,apiUrl:(t.URUN_API_URL??"").trim()||D,fnName:(t.URUN_FUNCTION??"").trim()||le}}function me(t){let e=(t.URUN_BASE_URL??"").trim(),n=(t.URUN_ORG_ID??"").trim();if(!e)throw new Error("urun pi extension: URUN_BASE_URL is required to open a session");if(/\/v1\/*$/.test(new URL(e).pathname))throw new Error(`urun pi extension: URUN_BASE_URL must be the session-gateway base (e.g. https://api.urun.sh), got ${e} \u2014 a trailing /v1 is the org API form (URUN_API_URL); session allocation 404s against it. Drop the /v1.`);if(!n)throw new Error("urun pi extension: URUN_ORG_ID is required to open a session");let o=(t.URUN_JWT??"").trim();if(o)return{baseUrl:e,orgId:n,auth:{lane:"jwt",jwt:o}};let i=(t.URUN_API_KEY??"").trim();if(!i)throw new Error("urun pi extension: URUN_JWT or URUN_API_KEY is required to open a session");let c=(t.URUN_GATEWAY_URL??"").trim()||void 0;return{baseUrl:e,orgId:n,auth:{lane:"api-key",apiKey:i,gatewayUrl:c}}}function ye(t){let e=null;return n=>{e===null&&(ne(ie(t),{recursive:!0}),e=oe(t,"a"));let o=n.detail?` ${JSON.stringify(n.detail)}`:"";re(e,`${new Date().toISOString()} [${n.level}] [urun] ${n.message}${o}
2
- `)}}function he(t=se.homedir()){return ae(t,".urun","logs","pi-extension.log")}function we(t){let e=ye(he());return async(n,o,i)=>{let{baseUrl:c,orgId:s,auth:d}=me(n),{App:w,createClientToken:a}=await t(),_=(d.lane==="jwt"?w(o,{baseUrl:c,orgId:s,jwt:d.jwt,diagnosticSink:e}):w(o,{baseUrl:c,orgId:s,diagnosticSink:e,getAccessToken:async()=>(await a(d.apiKey,{baseUrl:d.gatewayUrl,expiresIn:300,allowedFunctions:[`${o}/${i}`]})).token}))[i];if(typeof _!="function")throw new Error(`urun pi extension: app "${o}" has no function "${i}"`);let y=_(),b=y.connect;return typeof b=="function"&&await b.call(y),y}}var _e=we(async()=>{let{createRequire:t}=await import("module"),e=t(import.meta.url);if(typeof globalThis.RTCPeerConnection>"u")try{e.resolve("werift")}catch{throw new Error('urun pi extension: token streams require a WebRTC data channel, and this Node runtime has no RTCPeerConnection and no "werift" backend installed (@urun-sh/core\'s optional Node WebRTC backend \u2014 it was probably stripped by a --no-optional install). Install werift (`npm i werift`) and retry.')}return e("@urun-sh/core")});function xe(t){try{Promise.resolve(t.close?.()).catch(()=>{})}catch{}}var F=class{constructor(e,n,o){this.open=e;this.env=n;this.fnName=o}open;env;fnName;pool=new Map;acquire(e){let n=this.pool.get(e);if(!n){let o=Promise.resolve(this.open(this.env,e,this.fnName)).then(i=>({session:i,responses:new B(i)}));n=o,this.pool.set(e,o),o.catch(()=>{this.pool.get(e)===o&&this.pool.delete(e)})}return n}evict(e){let n=this.pool.get(e);n&&(this.pool.delete(e),n.then(o=>xe(o.session),()=>{}))}closeAll(){for(let e of[...this.pool.keys()])this.evict(e)}};function ve(t){let e=[];t.systemPrompt&&e.push({role:"system",content:t.systemPrompt});for(let n of t.messages){if(n.role==="toolResult"){e.push({type:"function_call_output",call_id:n.toolCallId,output:Te(n.content)});continue}if(n.role==="assistant"&&Array.isArray(n.content)){let i="",c=()=>{i&&(e.push({role:"assistant",content:i}),i="")};for(let s of n.content)if(s.type==="text")i+=String(s.text??"");else if(s.type==="toolCall")c(),e.push({type:"function_call",call_id:String(s.id??""),name:String(s.name??""),arguments:JSON.stringify(s.arguments??{})});else{if(s.type==="thinking")continue;throw new Error(`urun pi extension: unsupported assistant content part "${String(s.type)}"`)}c();continue}let o=n.role==="assistant"?"assistant":"user";e.push({role:o,content:Re(n.content)})}return ke(e)}function ke(t){let e=[];for(let n of t){let o=e[e.length-1];o&&"role"in o&&"role"in n&&o.role===n.role?o.content=[o.content,n.content].filter(i=>i.length>0).join(`
1
+ import{c as G}from"../chunk-HQVV5UN5.js";import{a as F,c as H}from"../chunk-5CEMLB6H.js";import{createAssistantMessageEventStream as oe}from"@earendil-works/pi-ai";import{mkdirSync as re,openSync as se,writeSync as ie}from"fs";import ae from"os";import{dirname as le,join as ce}from"path";async function Y(t){let e=await H(t),n=e.filter(o=>o.function_name===t.fnName&&o.deployment_status==="active").map(o=>o.app_slug);if(n.length===0)throw new Error(`urun pi extension: the org has no active deployed app exposing "${t.fnName}" (GET ${t.apiUrl}/apps returned ${e.length} app(s), none servable) \u2014 deploy one with \`urun serve <model>\` first`);return n.sort()}var V="urun-serve",ue="serve",pe=131072,de=16384,B=3,fe=42e4,ge=6e4,X=2,me=15e3;function ye(t){let e=(t.URUN_API_KEY??"").trim();if(!e)throw new Error("urun pi extension: URUN_API_KEY is required \u2014 model discovery lists the org's deployed serve apps via the org API (URUN_JWT alone cannot list apps)");return{apiKey:e,apiUrl:(t.URUN_API_URL??"").trim()||F,fnName:(t.URUN_FUNCTION??"").trim()||ue}}function he(t){let e=(t.URUN_BASE_URL??"").trim(),n=(t.URUN_ORG_ID??"").trim();if(!e)throw new Error("urun pi extension: URUN_BASE_URL is required to open a session");if(/\/v1\/*$/.test(new URL(e).pathname))throw new Error(`urun pi extension: URUN_BASE_URL must be the session-gateway base (e.g. https://api.urun.sh), got ${e} \u2014 a trailing /v1 is the org API form (URUN_API_URL); session allocation 404s against it. Drop the /v1.`);if(!n)throw new Error("urun pi extension: URUN_ORG_ID is required to open a session");let o=(t.URUN_JWT??"").trim();if(o)return{baseUrl:e,orgId:n,auth:{lane:"jwt",jwt:o}};let i=(t.URUN_API_KEY??"").trim();if(!i)throw new Error("urun pi extension: URUN_JWT or URUN_API_KEY is required to open a session");let u=(t.URUN_GATEWAY_URL??"").trim()||void 0;return{baseUrl:e,orgId:n,auth:{lane:"api-key",apiKey:i,gatewayUrl:u}}}function we(t){let e=null;return n=>{e===null&&(re(le(t),{recursive:!0}),e=se(t,"a"));let o=n.detail?` ${JSON.stringify(n.detail)}`:"";ie(e,`${new Date().toISOString()} [${n.level}] [urun] ${n.message}${o}
2
+ `)}}function _e(t=ae.homedir()){return ce(t,".urun","logs","pi-extension.log")}function xe(t){let e=we(_e());return async(n,o,i)=>{let{baseUrl:u,orgId:s,auth:d}=he(n),{App:x,createClientToken:a}=await t(),w=(d.lane==="jwt"?x(o,{baseUrl:u,orgId:s,jwt:d.jwt,diagnosticSink:e}):x(o,{baseUrl:u,orgId:s,diagnosticSink:e,getAccessToken:async()=>(await a(d.apiKey,{baseUrl:d.gatewayUrl,expiresIn:300,allowedFunctions:[`${o}/${i}`]})).token}))[i];if(typeof w!="function")throw new Error(`urun pi extension: app "${o}" has no function "${i}"`);let m=w();if(typeof m.end!="function")throw new Error(`urun pi extension: app "${o}" function "${i}" returned a session without end()`);let E=m.connect;return typeof E=="function"&&await E.call(m),m}}var ve=xe(async()=>{let{createRequire:t}=await import("module"),e=t(import.meta.url);if(typeof globalThis.RTCPeerConnection>"u")try{e.resolve("werift")}catch{throw new Error('urun pi extension: token streams require a WebRTC data channel, and this Node runtime has no RTCPeerConnection and no "werift" backend installed (@urun-sh/core\'s optional Node WebRTC backend \u2014 it was probably stripped by a --no-optional install). Install werift (`npm i werift`) and retry.')}return e("@urun-sh/core")});function ke(t){try{Promise.resolve(t.end()).catch(()=>{})}catch{}}var K=class{constructor(e,n,o){this.open=e;this.env=n;this.fnName=o}open;env;fnName;pool=new Map;acquire(e){let n=this.pool.get(e);if(!n){let o=Promise.resolve(this.open(this.env,e,this.fnName)).then(i=>({session:i,responses:new G(i)}));n=o,this.pool.set(e,o),o.catch(()=>{this.pool.get(e)===o&&this.pool.delete(e)})}return n}evict(e){let n=this.pool.get(e);n&&(this.pool.delete(e),n.then(o=>ke(o.session),()=>{}))}closeAll(){for(let e of[...this.pool.keys()])this.evict(e)}};function Re(t){let e=[];t.systemPrompt&&e.push({role:"system",content:t.systemPrompt});for(let n of t.messages){if(n.role==="toolResult"){e.push({type:"function_call_output",call_id:n.toolCallId,output:Ae(n.content)});continue}if(n.role==="assistant"&&Array.isArray(n.content)){let i="",u=()=>{i&&(e.push({role:"assistant",content:i}),i="")};for(let s of n.content)if(s.type==="text")i+=String(s.text??"");else if(s.type==="toolCall")u(),e.push({type:"function_call",call_id:String(s.id??""),name:String(s.name??""),arguments:JSON.stringify(s.arguments??{})});else{if(s.type==="thinking")continue;throw new Error(`urun pi extension: unsupported assistant content part "${String(s.type)}"`)}u();continue}let o=n.role==="assistant"?"assistant":"user";e.push({role:o,content:be(n.content)})}return Te(e)}function Te(t){let e=[];for(let n of t){let o=e[e.length-1];o&&"role"in o&&"role"in n&&o.role===n.role?o.content=[o.content,n.content].filter(i=>i.length>0).join(`
3
3
 
4
- `):e.push({...n})}return e}function Re(t){return typeof t=="string"?t:Array.isArray(t)?t.map(e=>e&&typeof e=="object"&&"text"in e?String(e.text):"").join(""):""}function Te(t){if(typeof t=="string")return t;if(!Array.isArray(t))return"";let e="";for(let n of t){let o=String(n.type??"");if(o!=="text")throw new Error(`urun pi extension: unsupported toolResult content part "${o}" \u2014 the serve lane carries text tool results only`);e+=String(n.text??"")}return e}function Ae(t){if(!(!Array.isArray(t)||t.length===0))return t.map(e=>({type:"function",name:e.name,description:e.description,parameters:e.parameters}))}function z(t,e){if(!e.trim())return{};try{return JSON.parse(e)}catch{throw new Error(`uRun serve error: tool call "${t}" arguments are not valid JSON: ${e}`)}}function be(t){let e=t?.output;return Array.isArray(e)?e.filter(n=>n.type==="function_call"):[]}function Ue(t){let e=t?.output;if(!Array.isArray(e))return"";let n="";for(let o of e)if(!(o.type!=="reasoning"||!Array.isArray(o.content)))for(let i of o.content)i.type==="reasoning_text"&&(n+=String(i.text??""));return n}var Ee=["<tool_call>","<function="];function Se(t,e){let n=Ee.find(o=>e.includes(o));if(n)return new Error(`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 Ie(t){let e=t instanceof Error?t.message:String(t),n=t?.code;return/\b529\b/.test(e)||/overloaded/i.test(e)||n===529||n==="529"}function Pe(t){return new Promise(e=>setTimeout(e,t))}function Ce(t,e,n,o){return new Promise((i,c)=>{let s=!1,d=r=>{s||(s=!0,clearTimeout(w),o?.removeEventListener("abort",a),r())},w=setTimeout(()=>d(()=>c(n())),e),a=()=>d(()=>c(new Error("aborted")));if(o?.aborted){a();return}o?.addEventListener("abort",a,{once:!0}),Promise.resolve(t).then(r=>d(()=>i(r)),r=>d(()=>c(r)))})}async function*Ne(t,e){let n=t[Symbol.asyncIterator](),o,i=new Promise((c,s)=>{o=()=>s(new Error("aborted")),e.addEventListener("abort",o,{once:!0})});try{for(;;){if(e.aborted)throw new Error("aborted");let c=await Promise.race([n.next(),i]);if(c.done)return;yield c.value}}finally{o&&e.removeEventListener("abort",o),n.return?.(void 0)}}function Le(t,e){let n=t?.sendMessage;if(typeof n=="function")try{n.call(t,{customType:"urun-status",content:e,display:!0},{triggerTurn:!1})}catch{}}function Me(t,e={},n){let o=e.connectDeadlineMs??pe,i=e.stallTimeoutMs??de,c=e.phaseHeartbeatMs??fe;return(s,d,w)=>{let a=te(),r={role:"assistant",content:[],api:s.api,provider:s.provider,model:s.id,usage:{input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},stopReason:"stop",timestamp:Date.now()},_=new AbortController,y=w?.signal,b=!1,S=()=>{b=!0,_.abort()};y&&(y.aborted?S():y.addEventListener("abort",S,{once:!0}));let N=!1,T,K=()=>{T&&clearTimeout(T),T=setTimeout(()=>{N=!0,_.abort()},i)},L=()=>{T&&clearTimeout(T),T=void 0},x=null,v=null,g=null,J="",I=!1,M=()=>{if(!v)return;let p=v;v=null,a.push({type:"thinking_end",contentIndex:r.content.indexOf(p),content:p.thinking,partial:r})},W=()=>{if(!x)return;let p=x;x=null,a.push({type:"text_end",contentIndex:r.content.indexOf(p),content:p.text,partial:r})},O=()=>{if(!g)return;let{call:p,args:m,contentIndex:k}=g;g=null,p.arguments=z(p.name,m),a.push({type:"toolcall_end",contentIndex:k,toolCall:p,partial:r})},V=p=>{let m={type:"toolCall",id:String(p.call_id??p.id??`call_${r.content.length}`),name:String(p.name??""),arguments:{}};r.content.push(m);let k=r.content.length-1;a.push({type:"toolcall_start",contentIndex:k,partial:r});let U=typeof p.arguments=="string"?p.arguments:"";U&&a.push({type:"toolcall_delta",contentIndex:k,delta:U,partial:r}),m.arguments=z(m.name,U),a.push({type:"toolcall_end",contentIndex:k,toolCall:m,partial:r})};return(async()=>{a.push({type:"start",partial:r});let p=!1,m,k=()=>{m&&clearInterval(m),m=void 0},U=Date.now();m=setInterval(()=>{let R=Math.round((Date.now()-U)/1e3);Le(n,`uRun: still opening the "${s.id}" session\u2026 (${R}s \u2014 serve apps scale to zero, first turn can cold-start ~6min)`)},c);try{let{responses:R}=await Ce(t.acquire(s.id),o,()=>new Error(`uRun session for "${s.id}" did not connect within ${Math.round(o/1e3)}s \u2014 likely cold-starting (scaled to zero) or queued behind capacity. Retry shortly.`),_.signal);k();let $=ve(d),P,C;for(let u=1;u<=X;u++)try{let h=await R.responses.create({model:s.id,input:$,stream:!0,tools:Ae(d.tools),max_output_tokens:s.maxTokens});K();for await(let E of Ne(h,_.signal)){K();let f=E;if(f.type==="response.output_text.delta"){let l=typeof f.delta=="string"?f.delta:"";l&&(I=!0,M(),O(),x||(x={type:"text",text:""},r.content.push(x),a.push({type:"text_start",contentIndex:r.content.length-1,partial:r})),x.text+=l,J+=l,a.push({type:"text_delta",contentIndex:r.content.indexOf(x),delta:l,partial:r}))}else if(f.type==="response.reasoning_text.delta"){let l=typeof f.delta=="string"?f.delta:"";l&&(I=!0,v||(v={type:"thinking",thinking:""},r.content.push(v),a.push({type:"thinking_start",contentIndex:r.content.length-1,partial:r})),v.thinking+=l,a.push({type:"thinking_delta",contentIndex:r.content.indexOf(v),delta:l,partial:r}))}else if(f.type==="response.function_call_arguments.delta"&&typeof f.tool_index=="number"){let l=f;if(I=!0,M(),W(),!g||g.toolIndex!==l.tool_index){O();let G={type:"toolCall",id:l.call_id??`call_${l.tool_index}`,name:l.name??"",arguments:{}};r.content.push(G),g={call:G,args:"",contentIndex:r.content.length-1,toolIndex:l.tool_index},a.push({type:"toolcall_start",contentIndex:g.contentIndex,partial:r})}l.call_id&&(g.call.id=l.call_id),l.name&&(g.call.name=l.name);let A=typeof l.delta=="string"?l.delta:"";A&&(g.args+=A,a.push({type:"toolcall_delta",contentIndex:g.contentIndex,delta:A,partial:r}))}else if(f.type==="response.completed"){P=f.response;break}else if(f.type==="error"){let l=f.error,A=new Error(`uRun serve error: ${l?.message??"unknown error"}`);throw A.code=l?.code??null,A}}C=void 0;break}catch(h){if(C=h,_.signal.aborted)throw h;if(u<X&&Ie(h)&&!I){await Pe(u*500);continue}throw h}if(C)throw C;if(L(),M(),W(),O(),!r.content.some(u=>u.type==="toolCall"))for(let u of be(P))V(u);if(!r.content.some(u=>u.type==="thinking")){let u=Ue(P);if(u){let h={type:"thinking",thinking:""};r.content.push(h);let E=r.content.length-1;a.push({type:"thinking_start",contentIndex:E,partial:r}),h.thinking=u,a.push({type:"thinking_delta",contentIndex:E,delta:u,partial:r}),a.push({type:"thinking_end",contentIndex:E,content:u,partial:r})}}let q=r.content.filter(u=>u.type==="toolCall").length;if((d.tools?.length??0)>0&&q===0){let u=Se(s.id,J);if(u)throw u}let j=q>0?"toolUse":P?.status==="incomplete"?"length":"stop";r.stopReason=j,a.push({type:"done",reason:j,message:r}),a.end(r)}catch(R){if(p=!0,L(),b||y?.aborted&&!N)r.stopReason="aborted",r.errorMessage="aborted by user",a.push({type:"error",reason:"aborted",error:r});else{let $=N?`uRun stream stalled \u2014 no output for ${Math.round(i/1e3)}s; the model may be hung. Retry, or Ctrl-C to abort.`:R instanceof Error?R.message:String(R);r.stopReason="error",r.errorMessage=$,a.push({type:"error",reason:"error",error:r})}a.end(r)}finally{L(),k(),y&&y.removeEventListener("abort",S),p&&t.evict(s.id)}})(),a}}function Oe(t){return{id:t,name:`uRun ${t}`,api:Q,reasoning:!0,input:["text"],cost:{input:0,output:0,cacheRead:0,cacheWrite:0},contextWindow:ce,maxTokens:ue}}function $e(t={}){return async e=>{let n=t.env??process.env,{apiKey:o,apiUrl:i,fnName:c}=ge(n),s=await Y({apiUrl:i,apiKey:o,fnName:c,fetchImpl:t.fetchImpl}),d=new F(t.openSession??_e,n,c);e.on("session_shutdown",()=>d.closeAll());let w={name:"uRun",api:Q,baseUrl:"urun://session",apiKey:"$URUN_API_KEY",models:s.map(Oe),streamSimple:Me(d,t.timing??{},e)};e.registerProvider("urun",w)}}var Ye=$e();export{F as SessionPool,Q as URUN_API,ke as coalesceSameRole,ye as createFileDiagnosticSink,$e as createUrunExtension,Ye as default,we as makeSessionFactory,Me as makeStreamSimple,he as piDiagnosticLogPath,me as resolveSessionEnv,ve as toResponsesInput};
4
+ `):e.push({...n})}return e}function be(t){return typeof t=="string"?t:Array.isArray(t)?t.map(e=>e&&typeof e=="object"&&"text"in e?String(e.text):"").join(""):""}function Ae(t){if(typeof t=="string")return t;if(!Array.isArray(t))return"";let e="";for(let n of t){let o=String(n.type??"");if(o!=="text")throw new Error(`urun pi extension: unsupported toolResult content part "${o}" \u2014 the serve lane carries text tool results only`);e+=String(n.text??"")}return e}function Ee(t){if(!(!Array.isArray(t)||t.length===0))return t.map(e=>({type:"function",name:e.name,description:e.description,parameters:e.parameters}))}function z(t,e){if(!e.trim())return{};try{return JSON.parse(e)}catch{throw new Error(`uRun serve error: tool call "${t}" arguments are not valid JSON: ${e}`)}}function Ue(t){let e=t?.output;return Array.isArray(e)?e.filter(n=>n.type==="function_call"):[]}function Se(t){let e=t?.output;if(!Array.isArray(e))return"";let n="";for(let o of e)if(!(o.type!=="reasoning"||!Array.isArray(o.content)))for(let i of o.content)i.type==="reasoning_text"&&(n+=String(i.text??""));return n}var Ie=["<tool_call>","<function="];function Pe(t,e){let n=Ie.find(o=>e.includes(o));if(n)return new Error(`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)`)}var L=class extends Error{};function Ce(t){let e=t instanceof Error?t.message:String(t),n=t?.code;return/\b529\b/.test(e)||/overloaded/i.test(e)||n===529||n==="529"}function Ne(t){return new Promise(e=>setTimeout(e,t))}function Me(t,e,n,o){return new Promise((i,u)=>{let s=!1,d=r=>{s||(s=!0,clearTimeout(x),o?.removeEventListener("abort",a),r())},x=setTimeout(()=>d(()=>u(n())),e),a=()=>d(()=>u(new Error("aborted")));if(o?.aborted){a();return}o?.addEventListener("abort",a,{once:!0}),Promise.resolve(t).then(r=>d(()=>i(r)),r=>d(()=>u(r)))})}async function*Oe(t,e){let n=t[Symbol.asyncIterator](),o,i=new Promise((u,s)=>{o=()=>s(new Error("aborted")),e.addEventListener("abort",o,{once:!0})});try{for(;;){if(e.aborted)throw new Error("aborted");let u=await Promise.race([n.next(),i]);if(u.done)return;yield u.value}}finally{o&&e.removeEventListener("abort",o),n.return?.(void 0)}}function Q(t,e){let n=t?.sendMessage;if(typeof n=="function")try{n.call(t,{customType:"urun-status",content:e,display:!0},{triggerTurn:!1})}catch{}}function Le(t,e={},n){let o=e.connectDeadlineMs??fe,i=e.stallTimeoutMs??ge,u=e.phaseHeartbeatMs??me;return(s,d,x)=>{let a=oe(),r={role:"assistant",content:[],api:s.api,provider:s.provider,model:s.id,usage:{input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},stopReason:"stop",timestamp:Date.now()},w=new AbortController,m=x?.signal,E=!1,M=()=>{E=!0,w.abort()};m&&(m.aborted?M():m.addEventListener("abort",M,{once:!0}));let P=!1,U,J=()=>{U&&clearTimeout(U),U=setTimeout(()=>{P=!0,w.abort()},i)},O=()=>{U&&clearTimeout(U),U=void 0},v=null,k=null,y=null,W="",C=!1,$=()=>{if(!k)return;let p=k;k=null,a.push({type:"thinking_end",contentIndex:r.content.indexOf(p),content:p.thinking,partial:r})},q=()=>{if(!v)return;let p=v;v=null,a.push({type:"text_end",contentIndex:r.content.indexOf(p),content:p.text,partial:r})},D=()=>{if(!y)return;let{call:p,args:h,contentIndex:R}=y;y=null,p.arguments=z(p.name,h),a.push({type:"toolcall_end",contentIndex:R,toolCall:p,partial:r})},Z=p=>{let h={type:"toolCall",id:String(p.call_id??p.id??`call_${r.content.length}`),name:String(p.name??""),arguments:{}};r.content.push(h);let R=r.content.length-1;a.push({type:"toolcall_start",contentIndex:R,partial:r});let N=typeof p.arguments=="string"?p.arguments:"";N&&a.push({type:"toolcall_delta",contentIndex:R,delta:N,partial:r}),h.arguments=z(h.name,N),a.push({type:"toolcall_end",contentIndex:R,toolCall:h,partial:r})};return(async()=>{a.push({type:"start",partial:r});let p=!1,h,R=()=>{h&&clearInterval(h),h=void 0},N=Date.now();h=setInterval(()=>{let _=Math.round((Date.now()-N)/1e3);Q(n,`uRun: still opening the "${s.id}" session\u2026 (${_}s \u2014 serve apps scale to zero, first turn can cold-start ~6min)`)},u);let ee=async _=>{let{responses:T}=await Me(t.acquire(s.id),o,()=>new Error(`uRun session for "${s.id}" did not connect within ${Math.round(o/1e3)}s \u2014 likely cold-starting (scaled to zero) or queued behind capacity. Retry shortly.`),w.signal);R();let S,b;for(let l=1;l<=B;l++)try{let g=await T.responses.create({model:s.id,input:_,stream:!0,tools:Ee(d.tools),max_output_tokens:s.maxTokens});J();for await(let A of Oe(g,w.signal)){J();let f=A;if(f.type==="response.output_text.delta"){let c=typeof f.delta=="string"?f.delta:"";c&&(C=!0,$(),D(),v||(v={type:"text",text:""},r.content.push(v),a.push({type:"text_start",contentIndex:r.content.length-1,partial:r})),v.text+=c,W+=c,a.push({type:"text_delta",contentIndex:r.content.indexOf(v),delta:c,partial:r}))}else if(f.type==="response.reasoning_text.delta"){let c=typeof f.delta=="string"?f.delta:"";c&&(C=!0,k||(k={type:"thinking",thinking:""},r.content.push(k),a.push({type:"thinking_start",contentIndex:r.content.length-1,partial:r})),k.thinking+=c,a.push({type:"thinking_delta",contentIndex:r.content.indexOf(k),delta:c,partial:r}))}else if(f.type==="response.function_call_arguments.delta"&&typeof f.tool_index=="number"){let c=f;if(C=!0,$(),q(),!y||y.toolIndex!==c.tool_index){D();let j={type:"toolCall",id:c.call_id??`call_${c.tool_index}`,name:c.name??"",arguments:{}};r.content.push(j),y={call:j,args:"",contentIndex:r.content.length-1,toolIndex:c.tool_index},a.push({type:"toolcall_start",contentIndex:y.contentIndex,partial:r})}c.call_id&&(y.call.id=c.call_id),c.name&&(y.call.name=c.name);let I=typeof c.delta=="string"?c.delta:"";I&&(y.args+=I,a.push({type:"toolcall_delta",contentIndex:y.contentIndex,delta:I,partial:r}))}else if(f.type==="response.completed"){S=f.response;break}else if(f.type==="error"){let c=f.error,I=new Error(`uRun serve error: ${c?.message??"unknown error"}`);throw I.code=c?.code??null,I}}if(!S)throw new L(`uRun backhaul for "${s.id}" closed before the turn completed \u2014 the serving session ended mid-turn (its pod was restarted, drained or deleted).`);b=void 0;break}catch(g){if(b=g,w.signal.aborted)throw g;if(l<B&&Ce(g)&&!C){await Ne(l*500);continue}throw g}if(b)throw b;return S};try{let _=Re(d),T;for(let l=1;l<=X;l++)try{T=await ee(_);break}catch(g){let A=P||g instanceof L;if(l>=X||!A||C||E)throw g;O(),t.evict(s.id),P=!1,w=new AbortController,Q(n,`uRun: the "${s.id}" session ended mid-turn \u2014 re-homing to a fresh assignment and replaying the turn\u2026`)}if(O(),$(),q(),D(),!r.content.some(l=>l.type==="toolCall"))for(let l of Ue(T))Z(l);if(!r.content.some(l=>l.type==="thinking")){let l=Se(T);if(l){let g={type:"thinking",thinking:""};r.content.push(g);let A=r.content.length-1;a.push({type:"thinking_start",contentIndex:A,partial:r}),g.thinking=l,a.push({type:"thinking_delta",contentIndex:A,delta:l,partial:r}),a.push({type:"thinking_end",contentIndex:A,content:l,partial:r})}}let S=r.content.filter(l=>l.type==="toolCall").length;if((d.tools?.length??0)>0&&S===0){let l=Pe(s.id,W);if(l)throw l}let b=S>0?"toolUse":T?.status==="incomplete"?"length":"stop";r.stopReason=b,a.push({type:"done",reason:b,message:r}),a.end(r)}catch(_){if(p=!0,O(),E||m?.aborted&&!P)r.stopReason="aborted",r.errorMessage="aborted by user",a.push({type:"error",reason:"aborted",error:r});else{let T=P?`uRun stream stalled \u2014 no output for ${Math.round(i/1e3)}s; the model may be hung. Retry, or Ctrl-C to abort.`:_ instanceof Error?_.message:String(_);r.stopReason="error",r.errorMessage=T,a.push({type:"error",reason:"error",error:r})}a.end(r)}finally{O(),R(),m&&m.removeEventListener("abort",M),p&&t.evict(s.id)}})(),a}}function $e(t){return{id:t,name:`uRun ${t}`,api:V,reasoning:!0,input:["text"],cost:{input:0,output:0,cacheRead:0,cacheWrite:0},contextWindow:pe,maxTokens:de}}function De(t={}){return async e=>{let n=t.env??process.env,{apiKey:o,apiUrl:i,fnName:u}=ye(n),s=await Y({apiUrl:i,apiKey:o,fnName:u,fetchImpl:t.fetchImpl}),d=new K(t.openSession??ve,n,u);e.on("session_shutdown",()=>d.closeAll());let x={name:"uRun",api:V,baseUrl:"urun://session",apiKey:"$URUN_API_KEY",models:s.map($e),streamSimple:Le(d,t.timing??{},e)};e.registerProvider("urun",x)}}var Xe=De();export{K as SessionPool,V as URUN_API,Te as coalesceSameRole,we as createFileDiagnosticSink,De as createUrunExtension,Xe as default,xe as makeSessionFactory,Le as makeStreamSimple,_e as piDiagnosticLogPath,he as resolveSessionEnv,Re as toResponsesInput};