@urun-sh/openai 0.5.3 → 0.5.4

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.
Files changed (39) hide show
  1. package/dist/chunk-4MSBS7M6.js +1 -0
  2. package/dist/{chunk-G3NMGP4N.js → chunk-GBBY3PCZ.js} +1 -1
  3. package/dist/chunk-K23AZPI4.js +1 -0
  4. package/dist/chunk-OI2OY32M.js +1 -0
  5. package/dist/chunk-RQBD4OAA.js +6 -0
  6. package/dist/{chunk-FVD4NMXJ.js → chunk-STFRT5OY.js} +1 -1
  7. package/dist/{chunk-M6ICU4F5.js → chunk-VNM4M4P3.js} +12 -12
  8. package/dist/gemini-live.cjs +2 -2
  9. package/dist/gemini-live.d.cts +6 -0
  10. package/dist/gemini-live.d.ts +6 -0
  11. package/dist/gemini-live.js +1 -1
  12. package/dist/hosted/bin.cjs +16 -16
  13. package/dist/hosted/bin.js +1 -1
  14. package/dist/hosted/index.cjs +16 -16
  15. package/dist/hosted/index.d.cts +94 -13
  16. package/dist/hosted/index.d.ts +44 -11
  17. package/dist/hosted/index.js +1 -1
  18. package/dist/index.cjs +1 -1
  19. package/dist/index.d.cts +2 -18
  20. package/dist/index.d.ts +2 -18
  21. package/dist/index.js +1 -1
  22. package/dist/models-NYMZrklp.d.cts +38 -0
  23. package/dist/models-NYMZrklp.d.ts +38 -0
  24. package/dist/pi-extension/index.cjs +6 -6
  25. package/dist/pi-extension/index.js +1 -1
  26. package/dist/pi-extension/standalone.cjs +49 -49
  27. package/dist/proxy/cli.cjs +31 -31
  28. package/dist/proxy/cli.js +1 -1
  29. package/dist/proxy/index.cjs +13 -13
  30. package/dist/proxy/index.d.cts +1 -1
  31. package/dist/proxy/index.d.ts +1 -1
  32. package/dist/proxy/index.js +1 -1
  33. package/dist/{server-l1himPxc.d.ts → server-DuH_5OD9.d.ts} +2 -0
  34. package/dist/{server-BfME37pQ.d.cts → server-wmUnMewW.d.cts} +6 -0
  35. package/package.json +3 -3
  36. package/dist/chunk-F2TEK34X.js +0 -1
  37. package/dist/chunk-ODHCPZHI.js +0 -6
  38. package/dist/chunk-UVAY7Q7Z.js +0 -1
  39. package/dist/chunk-XHIIEA6Z.js +0 -1
@@ -1,34 +1,34 @@
1
- "use strict";var St=Object.create;var de=Object.defineProperty;var Rt=Object.getOwnPropertyDescriptor;var At=Object.getOwnPropertyNames;var Et=Object.getPrototypeOf,Ot=Object.prototype.hasOwnProperty;var It=(e,n)=>{for(var t in n)de(e,t,{get:n[t],enumerable:!0})},Ke=(e,n,t,o)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of At(n))!Ot.call(e,r)&&r!==t&&de(e,r,{get:()=>n[r],enumerable:!(o=Rt(n,r))||o.enumerable});return e};var pe=(e,n,t)=>(t=e!=null?St(Et(e)):{},Ke(n||!e||!e.__esModule?de(t,"default",{value:e,enumerable:!0}):t,e)),Tt=e=>Ke(de({},"__esModule",{value:!0}),e);var Cn={};It(Cn,{BIND_HOST:()=>wt,ControlPlaneUnavailableError:()=>W,DEFAULT_PORT:()=>He,MAX_CACHED_KEYS:()=>De,MAX_TENANTS:()=>Fe,ORG_BINDING_TTL_MS:()=>Me,OrgResolver:()=>ee,ProxyAuthError:()=>F,READINESS_TIMEOUT_MS:()=>Je,READINESS_TTL_MS:()=>qe,SERVE_FUNCTION:()=>Se,TenantRegistry:()=>te,bearerFrom:()=>ve,createHostedProxy:()=>bt,resolveHostedConfig:()=>_t,tenantSubject:()=>je});module.exports=Tt(Cn);var xt=require("http");var Jt=require("http");var Gt=require("crypto"),qt=require("ws");function Ae(e){return e.toLowerCase().replace(/[^\p{L}\p{N}-]/gu,"-").replace(/^-+|-+$/g,"")}var U=class extends Error{},V=class extends Error{},Ee="urs1.";function Pt(e,n){return Ee+Buffer.from(JSON.stringify([e,n]),"utf8").toString("base64url")}function Ct(e){if(!e.startsWith(Ee))return null;try{let n=JSON.parse(Buffer.from(e.slice(Ee.length),"base64url").toString("utf8"));if(Array.isArray(n)&&typeof n[0]=="string"&&typeof n[1]=="string")return{app:n[0],key:n[1]}}catch{}return null}async function Ye(e){let n=e.fetchImpl??fetch,t=`${e.apiUrl.replace(/\/+$/,"")}/apps`,o=await n(t,{headers:{Authorization:`Bearer ${e.apiKey}`,Accept:"application/json"}});if(!o.ok)throw new Error(`org apps listing failed: GET ${t} \u2192 ${o.status}`);let r=await o.json();if(!Array.isArray(r.apps))throw new Error(`org apps listing returned no "apps" array (GET ${t})`);if(r.truncated===!0)throw new Error(`org apps listing was truncated (GET ${t} returned ${r.apps.length} of more) \u2014 model discovery would silently omit deployed apps`);return r.apps}var Ut=6e4,fe=class{constructor(n){this.opts=n}opts;pool=new Map;appsCache=null;seed(n,t){this.pool.set(n,Promise.resolve(t))}async deployedApps(){if(!this.opts.listApps)return[];let n=this.opts.appsTtlMs??Ut;if(this.appsCache&&Date.now()-this.appsCache.at<n)return this.appsCache.apps;let t=await this.opts.listApps();return this.appsCache={at:Date.now(),apps:t},t}servable(n){return n.filter(t=>t.function_name===this.opts.fnName&&t.deployment_status==="active").map(t=>t.app_slug)}async availableIds(){let n=this.opts.defaultApp,t=new Set(n===null?[]:[n]);if(this.opts.listApps)for(let r of this.servable(await this.deployedApps()))t.add(r);for(let r of this.pool.keys())t.add(r);let o=[...t].filter(r=>r!==n).sort();return n===null?o:[n,...o]}async noDefaultApp(n){let t=await this.availableIds(),o=t.length>0?t.join(", "):"(none deployed)";throw new U(n===""?`no "model" was given and this endpoint has no default model \u2014 name one of your org's deployed "${this.opts.fnName}" apps; available models: ${o}`:`model "${n}" does not name a deployed "${this.opts.fnName}" app in your org, and this endpoint has no default model to fall back to; available models: ${o}`)}async resolveApp(n){let t=(n??"").trim(),o=this.opts.defaultApp;if(!t||t==="urun")return o===null?this.noDefaultApp(t):o;let r=Ae(t);if(r===o)return o;if(this.pool.has(r))return r;if(this.opts.listApps){let i=await this.deployedApps(),s=this.servable(i);if(s.includes(r))return r;let a=s.filter(c=>c.startsWith(`${r}-`));if(a.length===1)return a[0];if(a.length>1)throw new U(`model "${t}" is ambiguous across deployed apps ${a.join(", ")} \u2014 name the exact app slug (or catalog id:variant)`);let u=i.find(c=>c.app_slug===r||c.app_slug.startsWith(`${r}-`));if(u)throw new U(`model "${t}" maps to app "${u.app_slug}", which is not an active "${this.opts.fnName}" app \u2014 deploy it with \`urun serve ${t}\`; available models: ${(await this.availableIds()).join(", ")}`)}if(this.opts.listCatalog){let s=(await this.opts.listCatalog()).find(a=>t===a.model_id||t===`${a.model_id}:${a.variant}`||r===Ae(a.model_id)||r===Ae(`${a.model_id}-${a.variant}`));if(s)throw new U(`model "${t}" is in the uRun catalog but not deployed \u2014 deploy it with \`urun serve ${s.model_id}\`; available models: ${(await this.availableIds()).join(", ")}`)}return o===null?this.noDefaultApp(t):o}async sessionFor(n){let t=await this.resolveApp(n),o=this.pool.get(t);return o||(o=Promise.resolve(this.opts.openSession(t)),this.pool.set(t,o),o.catch(()=>this.pool.delete(t))),{app:t,entry:await o}}keyOf(n){let t=this.opts.sessionKey;if(!t)throw new Error("ModelRouter: sessionKey is not configured \u2014 the session-identity seam (handleFor/sessionForHandle) is unavailable on this router");let o=t(n);if(typeof o!="string"||o.length===0)throw new Error("ModelRouter: sessionKey returned an empty identity for a pooled session");return o}async handleFor(n){let{app:t,entry:o}=await this.sessionFor(n);return{app:t,handle:Pt(t,this.keyOf(o))}}async sessionForHandle(n){let t=Ct(n);if(!t)throw new V(`malformed session handle ${JSON.stringify(n)} \u2014 not issued by this proxy`);let{app:o,key:r}=t,i=this.pool.get(o),s=i?await i.then(a=>a,()=>null):null;if(s===null)throw new V(`the session behind this handle (app "${o}") is gone \u2014 closed, evicted after its pod died, or the proxy restarted; it cannot be reattached. Reconnect without a handle to start a new session.`);if(this.keyOf(s)!==r)throw new V(`the session behind this handle (app "${o}") was replaced \u2014 the original backhaul died and a new session serves this app now; the handle's session cannot be reattached. Reconnect without a handle to start a new session.`);return{app:o,entry:s}}async evict(n,t){let o=this.pool.get(n);!o||await o.then(i=>i,()=>null)!==t||this.pool.get(n)!==o||(this.pool.delete(n),await this.opts.closeSession(t).catch(()=>{}))}async modelList(){return{object:"list",data:(await this.availableIds()).map(t=>({id:t,object:"model",created:0,owned_by:"urun"}))}}async closeAll(){let n=[...this.pool.values()];this.pool.clear();let t=[];if(await Promise.all(n.map(async o=>{try{await this.opts.closeSession(await o)}catch(r){t.push(String(r instanceof Error?r.message:r))}})),t.length>0)throw new Error(`failed to close ${t.length} pooled session(s): ${t.join("; ")}`)}};var Oe=class{constructor(n,t){this.backend=n;this.opts=t}backend;opts;source=null;sink=null;outHandlers=new Set;async startOutbound(){return this.source=this.backend.createSource(),this.source.track}appendInputAudio(n){if(!this.source)throw new Error("startOutbound() not called");let t=Buffer.from(n,"base64"),o=Math.floor(t.byteLength/2),r=new Int16Array(o);for(let i=0;i<o;i++)r[i]=t.readInt16LE(i*2);this.source.onData(r)}async startInbound(n){if(n==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(n),this.sink.onframe=t=>{let o=Buffer.from(t.samples.buffer,t.samples.byteOffset,t.samples.byteLength).toString("base64");for(let r of this.outHandlers)r(o)}}onOutputAudio(n){return this.outHandlers.add(n),()=>this.outHandlers.delete(n)}};async function Qe(e,n,t=1e4){let o=new Oe(n,{sampleRate:24e3}),r=await o.startOutbound();await e.stream("rt-audio-in").attach(r);let i=await Nt(e,t);return await o.startInbound(i),o}function Nt(e,n){let t=e.stream("rt-audio-out");return t.track!=null?Promise.resolve(t.track):new Promise((o,r)=>{let i,s=setTimeout(()=>{i?.(),r(new Error(`enableSessionAudio: no downstream audio track within ${n}ms (runtime produced no voice OUT / SFU audio consumer never attached)`))},n),a=u=>{u!=null&&(clearTimeout(s),i?.(),o(u))};i=t.on?.("track",a),t.track!=null&&a(t.track)})}var ze="rt-video-in",Xe=256e3;function Ze(e){let n=e.stream(ze),t=n.emit;if(typeof t!="function")throw new Error(`enableSessionVideo: session.stream('${ze}') has no emit() \u2014 the named-DATA stream produce seam (@urun-sh/core SessionStream.emit, contract \xA75) is required for the video frame lane`);return{sendInputFrame:async o=>{if(o.byteLength===0)throw new Error("enableSessionVideo: refusing to send an empty video frame");if(o.byteLength>Xe)throw new Error(`enableSessionVideo: frame is ${o.byteLength} bytes \u2014 over the ${Xe}-byte data-channel budget (the SFU's 262144-byte SCTP ceiling drops oversize messages SILENTLY; send smaller/lower-quality frames)`);await t.call(n,o)}}}var $t=24e3,se=480,Lt=111;async function Mt(){let e=await import("opusscript"),n=e.default??e;return new n($t,1,2048)}async function et(){let e=await import("werift"),n=await Mt();return{createSource:()=>{let t=new e.MediaStreamTrack({kind:"audio"}),o=Math.random()*4294967295>>>0,r=Math.random()*65535&65535,i=Math.random()*4294967295>>>0,s=new Int16Array(0);return{track:t,onData:a=>{let u=new Int16Array(s.length+a.length);u.set(s,0),u.set(a,s.length);let c=0;for(;u.length-c>=se;){let p=u.subarray(c,c+se);c+=se;let f=Buffer.from(p.buffer,p.byteOffset,p.byteLength),m=n.encode(f,se);r=r+1&65535,i=i+se>>>0;let w=new e.RtpHeader({version:2,payloadType:Lt,sequenceNumber:r,timestamp:i,ssrc:o,marker:!1}),y=new e.RtpPacket(w,m);t.writeRtp(y)}s=u.slice(c)}}},createSink:t=>{let o={onframe:null};return t.onReceiveRtp.subscribe(i=>{let s;try{s=n.decode(i.payload)}catch{return}let a=new Int16Array(s.length/2);for(let u=0;u<a.length;u++)a[u]=s.readInt16LE(u*2);o.onframe?.({samples:a})}),o}}}var me=require("@urun-sh/core"),Ie="rt-video-out";var Dt="h264";function Vt(e,n){if(!Number.isInteger(e.seq)||e.seq<0)throw new Error(`${n}: header seq must be a non-negative integer (got ${e.seq})`);if(!Number.isInteger(e.ptsUs))throw new Error(`${n}: header ptsUs must be an integer microsecond timestamp (got ${e.ptsUs})`);if(typeof e.codec!="string"||e.codec.length===0)throw new Error(`${n}: header codec must be a non-empty string`);if(typeof e.key!="boolean")throw new Error(`${n}: header key must be a boolean`)}function Bt(e){if(e.byteLength<2)throw new Error(`decodeVideoOutRecord: truncated record (${e.byteLength} byte(s), no header length)`);let n=e[0]|e[1]<<8;if(e.byteLength<2+n)throw new Error(`decodeVideoOutRecord: truncated record (header says ${n} bytes, ${e.byteLength-2} present)`);let t;try{t=JSON.parse(new TextDecoder().decode(e.subarray(2,2+n)))}catch(s){throw new Error(`decodeVideoOutRecord: header is not valid JSON (${String(s)})`)}let o=t;if(o===null||typeof o!="object"||o.v!==1)throw new Error(`decodeVideoOutRecord: header is not spec v1 (v=${JSON.stringify(o?.v)}) \u2014 a newer producer must be met with a newer consumer, never silently misread`);let r=o;Vt(r,"decodeVideoOutRecord");let i=e.subarray(2+n);if(i.byteLength===0)throw new Error("decodeVideoOutRecord: empty access unit \u2014 a record with no AU bytes is a producer bug");return{header:r,au:i.slice()}}function tt(e){let n=e.stream(Ie);if(typeof n.messages!="function")throw new Error(`openSessionVideoOutLane: session.stream('${Ie}') has no messages() \u2014 the named-DATA stream consume seam (@urun-sh/core SessionStream.messages, contract \xA75) is required for the video OUT lane`);let t=new Set,o=new Set,r=new Set,i=u=>{for(let c of o)c(u)},s=!1,a=async()=>{for await(let u of n.messages()){if(!(u instanceof Uint8Array)){i(new Error(`openSessionVideoOutLane: "${Ie}" delivered a non-BINARY \xA75 payload (${typeof u}) \u2014 spec v1 records ride BINARY envelopes only`));continue}let c;try{c=Bt(u)}catch(p){i(p instanceof Error?p:new Error(String(p)));continue}for(let p of t)p(c)}for(let u of r)u()};return{codec:Dt,onOutputFrame:u=>(t.add(u),s||(s=!0,a().catch(c=>i(c instanceof Error?c:new Error(String(c))))),()=>t.delete(u)),onLaneError:u=>(o.add(u),()=>o.delete(u)),onEnd:u=>(r.add(u),()=>r.delete(u))}}var Ft=24e3,jn=`audio/pcm;rate=${Ft}`,jt=Buffer.alloc(960).toString("base64");var Ce=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>=Wt?"(other)":n;return this.models[o]??={requests:0,tokens_out:0}}model(n){this.modelEntry(n).requests+=1}track(n,t){let o=this,r=performance.now(),i=null,s=0;return(async function*(){for await(let u of n)u.type==="response.output_text.delta"&&typeof u.delta=="string"&&(i===null&&(i=performance.now(),o.ttftMs.push(i-r),o.ttftMs.length>512&&o.ttftMs.shift()),s+=1,o.tokensOut+=1,o.charsOut+=u.delta.length,t!==void 0&&(o.modelEntry(t).tokens_out+=1)),yield u;let a=(performance.now()-(i??r))/1e3;s>0&&a>0&&(o.tokRates.push(s/a),o.tokRates.length>512&&o.tokRates.shift())})()}static p50(n){if(!n.length)return null;let t=[...n].sort((o,r)=>o-r);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 Ne(e){e.writeHead(200,{"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive"})}function H(e,n,t){e.writeHead(n,{"content-type":"application/json"}),e.end(JSON.stringify(t))}function q(e,n,t,o="invalid_request_error"){H(e,n,{error:{message:t,type:o}})}function B(e,n,t,o){H(e,n,{type:"error",error:{type:t,message:o}})}function $e(e,n,t){if(n==="anthropic"){H(e,404,{type:"error",error:{type:"not_found_error",message:t.message}});return}H(e,404,{error:{message:t.message,type:"invalid_request_error",code:"model_not_found"}})}var Wt=256,Kt=128;function Le(e){return typeof e.model!="string"||!e.model.trim()?"(default)":e.model.trim().slice(0,Kt)}var nt=64*1024*1024,ge=class extends Error{};async function Yt(e){let n=[],t=0;for await(let r of e){if(t+=r.length,t>nt)throw new ge(`request body exceeds ${nt} bytes`);n.push(r)}let o=Buffer.concat(n).toString("utf8");return o?JSON.parse(o):{}}function X(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 zt=256;function Xt(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 Ue=class{conversations=new Map;thread(n,t){let o=Xt(t);if(n==null)return o;let r=this.conversations.get(String(n));if(!r)throw new Error(`unknown previous_response_id ${String(n)} (proxy restarts drop stored responses)`);return[...r,...o]}remember(n,t,o){this.conversations.set(n,[...t,{role:"assistant",content:o}]);for(let r of this.conversations.keys()){if(this.conversations.size<=zt)break;this.conversations.delete(r)}}};function ie(e){let n=e?.output;return Array.isArray(n)?n.filter(t=>t.type==="function_call"):[]}function K(e){return e.find(n=>n.type==="response.completed")?.response??null}function he(e){let n=e?.usage;if(!n||typeof n!="object")return null;let t=s=>typeof s=="number"&&Number.isFinite(s)&&s>=0?s:0,o=t(n.input_tokens),r=t(n.output_tokens);if(o===0&&r===0)return null;let i=t(n.total_tokens)||o+r;return{input_tokens:o,output_tokens:r,total_tokens:i}}function ot(e){let n=he(e);return n?{prompt_tokens:n.input_tokens,completion_tokens:n.output_tokens,total_tokens:n.total_tokens}:{prompt_tokens:0,completion_tokens:0,total_tokens:0}}function st(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 r of o.content)r.type==="reasoning_text"&&(t+=String(r.text??""));return t}function ae(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 Y=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}))}},Qt=["<tool_call>","<function="];function Zt(e){return Qt.find(n=>e.includes(n))}function Q(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 Z(e,n,t){if(!(!e||n>0))return Zt(t)}function en(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 ye=class extends Error{};function tn(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 r=o.image_url??{};return{type:"input_image",image_url:r.url,detail:r.detail}}throw new ye(`unsupported chat content part type "${String(o.type)}" \u2014 the proxy translates text and image_url parts`)}):n}function nn(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 r=o.function??{};n.push({type:"function_call",call_id:o.id,name:r.name,arguments:r.arguments})}continue}n.push({...t,content:tn(t.role,t.content)})}return n}function Te(e){return ie(e).map((n,t)=>({index:t,id:n.call_id??n.id??`call_${t}`,type:"function",function:{name:n.name??"",arguments:n.arguments??"{}"}}))}function rt(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 on(e,n,t,o,r){let i=e.stream===!0,s;try{s=t.thread(e.previous_response_id,e.input)}catch(l){q(o,400,String(l instanceof Error?l.message:l));return}e.previous_response_id!=null&&(r.naiveInBytes+=Buffer.byteLength(JSON.stringify(s))-Buffer.byteLength(JSON.stringify(e.input)));let a=`resp_${Math.random().toString(36).slice(2,14)}`,u=e.store!==!1,c=Le(e);r.model(c);let p=Array.isArray(e.tools)&&e.tools.length>0,f;try{f=await n.createResponse({model:e.model,input:s,stream:i,tools:e.tools,tool_choice:e.tool_choice,temperature:e.temperature,max_output_tokens:e.max_output_tokens,...e.reasoning_effort!==void 0?{reasoning_effort:e.reasoning_effort}:{},...e.chat_template_kwargs!==void 0?{chat_template_kwargs:e.chat_template_kwargs}:{}})}catch(l){if(l instanceof U){$e(o,"openai",l);return}throw l}let m=[];if(i){Ne(o);let l=g=>{o.write(`event: ${String(g.type??"message")}
1
+ "use strict";var Pt=Object.create;var pe=Object.defineProperty;var Ut=Object.getOwnPropertyDescriptor;var Nt=Object.getOwnPropertyNames;var $t=Object.getPrototypeOf,Lt=Object.prototype.hasOwnProperty;var Mt=(t,n)=>{for(var e in n)pe(t,e,{get:n[e],enumerable:!0})},ze=(t,n,e,o)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of Nt(n))!Lt.call(t,r)&&r!==e&&pe(t,r,{get:()=>n[r],enumerable:!(o=Ut(n,r))||o.enumerable});return t};var fe=(t,n,e)=>(e=t!=null?Pt($t(t)):{},ze(n||!t||!t.__esModule?pe(e,"default",{value:t,enumerable:!0}):e,t)),Dt=t=>ze(pe({},"__esModule",{value:!0}),t);var Bn={};Mt(Bn,{BIND_HOST:()=>At,ControlPlaneUnavailableError:()=>W,DEFAULT_PORT:()=>Fe,MAX_CACHED_KEYS:()=>Ve,MAX_TENANTS:()=>je,ORG_BINDING_TTL_MS:()=>De,OrgResolver:()=>te,ProxyAuthError:()=>F,READINESS_TIMEOUT_MS:()=>We,READINESS_TTL_MS:()=>Je,SERVE_FUNCTION:()=>Re,TenantRegistry:()=>ne,bearerFrom:()=>ke,createHostedProxy:()=>Ct,resolveHostedConfig:()=>Et,tenantSubject:()=>Ge});module.exports=Dt(Bn);var Tt=require("http");var tn=require("http");var Zt=require("crypto"),en=require("ws");function K(t){return t.toLowerCase().replace(/[^\p{L}\p{N}-]/gu,"-").replace(/^-+|-+$/g,"")}var Vt={chat:!0,code:!0,agent:!0,vl:!0},Ye={int4:"int4",int8:"int8",fp4:"fp4",mxfp4:"mxfp4",nvfp4:"nvfp4",fp6:"fp6",fp8:"fp8",mxfp8:"mxfp8",fp16:"fp16",bf16:"bf16",fp32:"fp32"};function Ht(t){let n=t.toLowerCase();return Object.hasOwn(Ye,n)?Ye[n]:null}function Ee(t){let n=t.engine_args?.context_length;return typeof n=="number"&&Number.isFinite(n)&&n>0?n:null}function Qe(t,n){let e=n.filter(i=>K(`${i.model_id}-${i.variant}`)===t);if(e.length===1)return e[0];if(e.length>1)return Xe(e);let o=n.filter(i=>K(i.model_id)===t),r=new Set(o.map(i=>i.variant));return o.length>0&&r.size===1?Xe(o):null}function Xe(t){let n=t[0],e=s=>t.every(a=>(a[s]??void 0)===(n[s]??void 0))?n[s]:void 0,o=t.map(Ee),r=o[0],i=r!=null&&o.every(s=>s===r)?r:null;return{model_id:n.model_id,variant:n.variant,gpu_spec:e("gpu_spec"),engine:e("engine"),task:e("task"),description:e("description"),size_gb:e("size_gb"),hf_repo:e("hf_repo"),engine_args:i!==null?{context_length:i}:{},updated_at:e("updated_at")}}function Ze(t){let n=t.updated_at?Date.parse(t.updated_at):NaN;return Number.isFinite(n)?Math.floor(n/1e3):0}function et(t,n){let e=Qe(t,n);if(!e)return{id:t,object:"model",created:0,owned_by:"urun"};let o=Ee(e);return{id:t,object:"model",created:Ze(e),owned_by:"urun",name:`${e.model_id}:${e.variant}`,...e.description?{description:e.description}:{},...e.task?{task:e.task}:{},...e.engine?{engine:e.engine}:{},...e.gpu_spec?{gpu_spec:e.gpu_spec}:{},...o!==null?{context_length:o}:{}}}function tt(t,n){let e=[];for(let o of t){let r=Qe(o,n);if(!r||!r.task||Vt[r.task]!==!0)continue;let i=Ee(r),s={temperature:{type:"range",min:0,max:2},top_p:{type:"range",min:0,max:1},stop:{type:"array",max_items:4}};i!==null&&(s.max_tokens={type:"integer",min:1,max:i,unit:"token"}),e.push({schema_version:"2.4",id:o,name:`${r.model_id}:${r.variant}`,created:Ze(r),quantization:Ht(r.variant),description:r.description??"",hugging_face_id:r.hf_repo?r.hf_repo.split("@")[0]??r.hf_repo:"",input_modalities:[{type:"text",...i!==null?{supported_inputs:{max_context_length:{value:i,unit:"token"}}}:{}},...r.task==="vl"?[{type:"image"}]:[]],output_modalities:[{type:"text",streaming:!0,supported_parameters:s}]})}return{data:e}}var U=class extends Error{},H=class extends Error{},Oe="urs1.";function Bt(t,n){return Oe+Buffer.from(JSON.stringify([t,n]),"utf8").toString("base64url")}function Ft(t){if(!t.startsWith(Oe))return null;try{let n=JSON.parse(Buffer.from(t.slice(Oe.length),"base64url").toString("utf8"));if(Array.isArray(n)&&typeof n[0]=="string"&&typeof n[1]=="string")return{app:n[0],key:n[1]}}catch{}return null}async function ot(t){let n=t.fetchImpl??fetch,e=`${t.apiUrl.replace(/\/+$/,"")}/apps`,o=await n(e,{headers:{Authorization:`Bearer ${t.apiKey}`,Accept:"application/json"}});if(!o.ok)throw new Error(`org apps listing failed: GET ${e} \u2192 ${o.status}`);let r=await o.json();if(!Array.isArray(r.apps))throw new Error(`org apps listing returned no "apps" array (GET ${e})`);if(r.truncated===!0)throw new Error(`org apps listing was truncated (GET ${e} returned ${r.apps.length} of more) \u2014 model discovery would silently omit deployed apps`);return r.apps}var nt=6e4,me=class{constructor(n){this.opts=n}opts;pool=new Map;appsCache=null;rowsCache=null;seed(n,e){this.pool.set(n,Promise.resolve(e))}async deployedApps(){if(!this.opts.listApps)return[];let n=this.opts.appsTtlMs??nt;if(this.appsCache&&Date.now()-this.appsCache.at<n)return this.appsCache.apps;let e=await this.opts.listApps();return this.appsCache={at:Date.now(),apps:e},e}async catalogRows(){if(!this.opts.listCatalog)return[];let n=this.opts.appsTtlMs??nt;if(this.rowsCache&&Date.now()-this.rowsCache.at<n)return this.rowsCache.rows;let e=await this.opts.listCatalog();return this.rowsCache={at:Date.now(),rows:e},e}servable(n){return n.filter(e=>e.function_name===this.opts.fnName&&e.deployment_status==="active").map(e=>e.app_slug)}async availableIds(){let n=this.opts.defaultApp,e=new Set(n===null?[]:[n]);if(this.opts.listApps)for(let r of this.servable(await this.deployedApps()))e.add(r);for(let r of this.pool.keys())e.add(r);let o=[...e].filter(r=>r!==n).sort();return n===null?o:[n,...o]}async noDefaultApp(n){let e=await this.availableIds(),o=e.length>0?e.join(", "):"(none deployed)";throw new U(n===""?`no "model" was given and this endpoint has no default model \u2014 name one of your org's deployed "${this.opts.fnName}" apps; available models: ${o}`:`model "${n}" does not name a deployed "${this.opts.fnName}" app in your org, and this endpoint has no default model to fall back to; available models: ${o}`)}async resolveApp(n){let e=(n??"").trim(),o=this.opts.defaultApp;if(!e||e==="urun")return o===null?this.noDefaultApp(e):o;let r=K(e);if(r===o)return o;if(this.pool.has(r))return r;if(this.opts.listApps){let i=await this.deployedApps(),s=this.servable(i);if(s.includes(r))return r;let a=s.filter(c=>c.startsWith(`${r}-`));if(a.length===1)return a[0];if(a.length>1)throw new U(`model "${e}" is ambiguous across deployed apps ${a.join(", ")} \u2014 name the exact app slug (or catalog id:variant)`);let u=i.find(c=>c.app_slug===r||c.app_slug.startsWith(`${r}-`));if(u)throw new U(`model "${e}" maps to app "${u.app_slug}", which is not an active "${this.opts.fnName}" app \u2014 deploy it with \`urun serve ${e}\`; available models: ${(await this.availableIds()).join(", ")}`)}if(this.opts.listCatalog){let s=(await this.opts.listCatalog()).find(a=>e===a.model_id||e===`${a.model_id}:${a.variant}`||r===K(a.model_id)||r===K(`${a.model_id}-${a.variant}`));if(s)throw new U(`model "${e}" is in the uRun catalog but not deployed \u2014 deploy it with \`urun serve ${s.model_id}\`; available models: ${(await this.availableIds()).join(", ")}`)}return o===null?this.noDefaultApp(e):o}async sessionFor(n){let e=await this.resolveApp(n),o=this.pool.get(e);return o||(o=Promise.resolve(this.opts.openSession(e)),this.pool.set(e,o),o.catch(()=>this.pool.delete(e))),{app:e,entry:await o}}keyOf(n){let e=this.opts.sessionKey;if(!e)throw new Error("ModelRouter: sessionKey is not configured \u2014 the session-identity seam (handleFor/sessionForHandle) is unavailable on this router");let o=e(n);if(typeof o!="string"||o.length===0)throw new Error("ModelRouter: sessionKey returned an empty identity for a pooled session");return o}async handleFor(n){let{app:e,entry:o}=await this.sessionFor(n);return{app:e,handle:Bt(e,this.keyOf(o))}}async sessionForHandle(n){let e=Ft(n);if(!e)throw new H(`malformed session handle ${JSON.stringify(n)} \u2014 not issued by this proxy`);let{app:o,key:r}=e,i=this.pool.get(o),s=i?await i.then(a=>a,()=>null):null;if(s===null)throw new H(`the session behind this handle (app "${o}") is gone \u2014 closed, evicted after its pod died, or the proxy restarted; it cannot be reattached. Reconnect without a handle to start a new session.`);if(this.keyOf(s)!==r)throw new H(`the session behind this handle (app "${o}") was replaced \u2014 the original backhaul died and a new session serves this app now; the handle's session cannot be reattached. Reconnect without a handle to start a new session.`);return{app:o,entry:s}}async evict(n,e){let o=this.pool.get(n);!o||await o.then(i=>i,()=>null)!==e||this.pool.get(n)!==o||(this.pool.delete(n),await this.opts.closeSession(e).catch(()=>{}))}async modelList(){let n=await this.availableIds(),e=await this.catalogRows().catch(()=>[]);return{object:"list",data:n.map(o=>et(o,e))}}async openRouterModels(){let n=await this.availableIds(),e=await this.catalogRows();return tt(n,e)}async closeAll(){let n=[...this.pool.values()];this.pool.clear();let e=[];if(await Promise.all(n.map(async o=>{try{await this.opts.closeSession(await o)}catch(r){e.push(String(r instanceof Error?r.message:r))}})),e.length>0)throw new Error(`failed to close ${e.length} pooled session(s): ${e.join("; ")}`)}};var Ie=class{constructor(n,e){this.backend=n;this.opts=e}backend;opts;source=null;sink=null;outHandlers=new Set;async startOutbound(){return this.source=this.backend.createSource(),this.source.track}appendInputAudio(n){if(!this.source)throw new Error("startOutbound() not called");let e=Buffer.from(n,"base64"),o=Math.floor(e.byteLength/2),r=new Int16Array(o);for(let i=0;i<o;i++)r[i]=e.readInt16LE(i*2);this.source.onData(r)}async startInbound(n){if(n==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(n),this.sink.onframe=e=>{let o=Buffer.from(e.samples.buffer,e.samples.byteOffset,e.samples.byteLength).toString("base64");for(let r of this.outHandlers)r(o)}}onOutputAudio(n){return this.outHandlers.add(n),()=>this.outHandlers.delete(n)}};async function it(t,n,e=1e4){let o=new Ie(n,{sampleRate:24e3}),r=await o.startOutbound();await t.stream("rt-audio-in").attach(r);let i=await jt(t,e);return await o.startInbound(i),o}function jt(t,n){let e=t.stream("rt-audio-out");return e.track!=null?Promise.resolve(e.track):new Promise((o,r)=>{let i,s=setTimeout(()=>{i?.(),r(new Error(`enableSessionAudio: no downstream audio track within ${n}ms (runtime produced no voice OUT / SFU audio consumer never attached)`))},n),a=u=>{u!=null&&(clearTimeout(s),i?.(),o(u))};i=e.on?.("track",a),e.track!=null&&a(e.track)})}var rt="rt-video-in",st=256e3;function at(t){let n=t.stream(rt),e=n.emit;if(typeof e!="function")throw new Error(`enableSessionVideo: session.stream('${rt}') has no emit() \u2014 the named-DATA stream produce seam (@urun-sh/core SessionStream.emit, contract \xA75) is required for the video frame lane`);return{sendInputFrame:async o=>{if(o.byteLength===0)throw new Error("enableSessionVideo: refusing to send an empty video frame");if(o.byteLength>st)throw new Error(`enableSessionVideo: frame is ${o.byteLength} bytes \u2014 over the ${st}-byte data-channel budget (the SFU's 262144-byte SCTP ceiling drops oversize messages SILENTLY; send smaller/lower-quality frames)`);await e.call(n,o)}}}var Gt=24e3,ie=480,qt=111;async function Jt(){let t=await import("opusscript"),n=t.default??t;return new n(Gt,1,2048)}async function ut(){let t=await import("werift"),n=await Jt();return{createSource:()=>{let e=new t.MediaStreamTrack({kind:"audio"}),o=Math.random()*4294967295>>>0,r=Math.random()*65535&65535,i=Math.random()*4294967295>>>0,s=new Int16Array(0);return{track:e,onData:a=>{let u=new Int16Array(s.length+a.length);u.set(s,0),u.set(a,s.length);let c=0;for(;u.length-c>=ie;){let p=u.subarray(c,c+ie);c+=ie;let f=Buffer.from(p.buffer,p.byteOffset,p.byteLength),m=n.encode(f,ie);r=r+1&65535,i=i+ie>>>0;let w=new t.RtpHeader({version:2,payloadType:qt,sequenceNumber:r,timestamp:i,ssrc:o,marker:!1}),h=new t.RtpPacket(w,m);e.writeRtp(h)}s=u.slice(c)}}},createSink:e=>{let o={onframe:null};return e.onReceiveRtp.subscribe(i=>{let s;try{s=n.decode(i.payload)}catch{return}let a=new Int16Array(s.length/2);for(let u=0;u<a.length;u++)a[u]=s.readInt16LE(u*2);o.onframe?.({samples:a})}),o}}}var ge=require("@urun-sh/core"),Te="rt-video-out";var Wt="h264";function Kt(t,n){if(!Number.isInteger(t.seq)||t.seq<0)throw new Error(`${n}: header seq must be a non-negative integer (got ${t.seq})`);if(!Number.isInteger(t.ptsUs))throw new Error(`${n}: header ptsUs must be an integer microsecond timestamp (got ${t.ptsUs})`);if(typeof t.codec!="string"||t.codec.length===0)throw new Error(`${n}: header codec must be a non-empty string`);if(typeof t.key!="boolean")throw new Error(`${n}: header key must be a boolean`)}function zt(t){if(t.byteLength<2)throw new Error(`decodeVideoOutRecord: truncated record (${t.byteLength} byte(s), no header length)`);let n=t[0]|t[1]<<8;if(t.byteLength<2+n)throw new Error(`decodeVideoOutRecord: truncated record (header says ${n} bytes, ${t.byteLength-2} present)`);let e;try{e=JSON.parse(new TextDecoder().decode(t.subarray(2,2+n)))}catch(s){throw new Error(`decodeVideoOutRecord: header is not valid JSON (${String(s)})`)}let o=e;if(o===null||typeof o!="object"||o.v!==1)throw new Error(`decodeVideoOutRecord: header is not spec v1 (v=${JSON.stringify(o?.v)}) \u2014 a newer producer must be met with a newer consumer, never silently misread`);let r=o;Kt(r,"decodeVideoOutRecord");let i=t.subarray(2+n);if(i.byteLength===0)throw new Error("decodeVideoOutRecord: empty access unit \u2014 a record with no AU bytes is a producer bug");return{header:r,au:i.slice()}}function ct(t){let n=t.stream(Te);if(typeof n.messages!="function")throw new Error(`openSessionVideoOutLane: session.stream('${Te}') has no messages() \u2014 the named-DATA stream consume seam (@urun-sh/core SessionStream.messages, contract \xA75) is required for the video OUT lane`);let e=new Set,o=new Set,r=new Set,i=u=>{for(let c of o)c(u)},s=!1,a=async()=>{for await(let u of n.messages()){if(!(u instanceof Uint8Array)){i(new Error(`openSessionVideoOutLane: "${Te}" delivered a non-BINARY \xA75 payload (${typeof u}) \u2014 spec v1 records ride BINARY envelopes only`));continue}let c;try{c=zt(u)}catch(p){i(p instanceof Error?p:new Error(String(p)));continue}for(let p of e)p(c)}for(let u of r)u()};return{codec:Wt,onOutputFrame:u=>(e.add(u),s||(s=!0,a().catch(c=>i(c instanceof Error?c:new Error(String(c))))),()=>e.delete(u)),onLaneError:u=>(o.add(u),()=>o.delete(u)),onEnd:u=>(r.add(u),()=>r.delete(u))}}var Xt=24e3,so=`audio/pcm;rate=${Xt}`,Qt=Buffer.alloc(960).toString("base64");var Ue=class t{startedAt=Date.now();requests={};models={};ttftMs=[];tokRates=[];tokensOut=0;charsOut=0;localInBytes=0;naiveInBytes=0;request(n,e,o){this.requests[n]=(this.requests[n]??0)+1,this.localInBytes+=e,this.naiveInBytes+=o}modelEntry(n){let e=this.models[n];if(e)return e;let o=Object.keys(this.models).length>=nn?"(other)":n;return this.models[o]??={requests:0,tokens_out:0}}model(n){this.modelEntry(n).requests+=1}track(n,e){let o=this,r=performance.now(),i=null,s=0;return(async function*(){for await(let u of n)u.type==="response.output_text.delta"&&typeof u.delta=="string"&&(i===null&&(i=performance.now(),o.ttftMs.push(i-r),o.ttftMs.length>512&&o.ttftMs.shift()),s+=1,o.tokensOut+=1,o.charsOut+=u.delta.length,e!==void 0&&(o.modelEntry(e).tokens_out+=1)),yield u;let a=(performance.now()-(i??r))/1e3;s>0&&a>0&&(o.tokRates.push(s/a),o.tokRates.length>512&&o.tokRates.shift())})()}static p50(n){if(!n.length)return null;let e=[...n].sort((o,r)=>o-r);return e[Math.floor(e.length/2)]}snapshot(){let n=Object.values(this.requests).reduce((e,o)=>e+o,0);return{uptime_s:Math.round((Date.now()-this.startedAt)/1e3),requests:this.requests,models:this.models,tokens_out:this.tokensOut,chars_out:this.charsOut,ttft_ms:{p50:t.p50(this.ttftMs),last:this.ttftMs.at(-1)??null},tok_per_s:{p50:t.p50(this.tokRates),last:this.tokRates.at(-1)??null},traffic:{local_request_bytes:this.localInBytes,naive_baseline:{request_bytes:this.naiveInBytes,connections:n},persistent_connections:1,history_bytes_saved:Math.max(0,this.naiveInBytes-this.localInBytes),history_bytes_saved_pct:this.naiveInBytes>0?Math.round((1-this.localInBytes/this.naiveInBytes)*1e3)/10:null}}}};function $e(t){t.writeHead(200,{"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive"})}function M(t,n,e){t.writeHead(n,{"content-type":"application/json"}),t.end(JSON.stringify(e))}function q(t,n,e,o="invalid_request_error"){M(t,n,{error:{message:e,type:o}})}function B(t,n,e,o){M(t,n,{type:"error",error:{type:e,message:o}})}function Le(t,n,e){if(n==="anthropic"){M(t,404,{type:"error",error:{type:"not_found_error",message:e.message}});return}M(t,404,{error:{message:e.message,type:"invalid_request_error",code:"model_not_found"}})}var nn=256,on=128;function Me(t){return typeof t.model!="string"||!t.model.trim()?"(default)":t.model.trim().slice(0,on)}var lt=64*1024*1024,he=class extends Error{};async function rn(t){let n=[],e=0;for await(let r of t){if(e+=r.length,e>lt)throw new he(`request body exceeds ${lt} bytes`);n.push(r)}let o=Buffer.concat(n).toString("utf8");return o?JSON.parse(o):{}}function Q(t,n,e,o){return{id:t,object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:n,choices:[{index:0,delta:e,finish_reason:o}]}}var sn=256;function an(t){if(typeof t=="string")return[{role:"user",content:t}];if(Array.isArray(t))return t;throw new Error("responses input must be a string or an array of messages/items")}var Ne=class{conversations=new Map;thread(n,e){let o=an(e);if(n==null)return o;let r=this.conversations.get(String(n));if(!r)throw new Error(`unknown previous_response_id ${String(n)} (proxy restarts drop stored responses)`);return[...r,...o]}remember(n,e,o){this.conversations.set(n,[...e,{role:"assistant",content:o}]);for(let r of this.conversations.keys()){if(this.conversations.size<=sn)break;this.conversations.delete(r)}}};function ae(t){let n=t?.output;return Array.isArray(n)?n.filter(e=>e.type==="function_call"):[]}function z(t){return t.find(n=>n.type==="response.completed")?.response??null}function ye(t){let n=t?.usage;if(!n||typeof n!="object")return null;let e=s=>typeof s=="number"&&Number.isFinite(s)&&s>=0?s:0,o=e(n.input_tokens),r=e(n.output_tokens);if(o===0&&r===0)return null;let i=e(n.total_tokens)||o+r;return{input_tokens:o,output_tokens:r,total_tokens:i}}function dt(t){let n=ye(t);return n?{prompt_tokens:n.input_tokens,completion_tokens:n.output_tokens,total_tokens:n.total_tokens}:{prompt_tokens:0,completion_tokens:0,total_tokens:0}}function ft(t){let n=t?.output;if(!Array.isArray(n))return"";let e="";for(let o of n)if(!(o.type!=="reasoning"||!Array.isArray(o.content)))for(let r of o.content)r.type==="reasoning_text"&&(e+=String(r.text??""));return e}function ue(t){return t.type!=="response.function_call_arguments.delta"||typeof t.tool_index!="number"?null:{tool_index:t.tool_index,call_id:typeof t.call_id=="string"?t.call_id:void 0,name:typeof t.name=="string"?t.name:void 0,delta:typeof t.delta=="string"?t.delta:""}}var Y=class{calls=new Map;add(n){let e=this.calls.get(n.tool_index),o=!e;return e||(e={args:""},this.calls.set(n.tool_index,e)),n.call_id&&(e.id=n.call_id),n.name&&(e.name=n.name),e.args+=n.delta,{call:e,isNew:o}}get size(){return this.calls.size}items(){return[...this.calls.entries()].map(([n,e])=>({type:"function_call",call_id:e.id??`call_${n}`,name:e.name??"",arguments:e.args}))}},un=["<tool_call>","<function="];function cn(t){return un.find(n=>t.includes(n))}function Z(t,n){return`serving row emitted a prose tool call (literal ${JSON.stringify(n)} in the assistant text) for a request that carried tools, and no structured tool_calls arrived \u2014 the tool-call parser is not configured on the model row "${t}" (see catalog parser_defaults)`}function ee(t,n,e){if(!(!t||n>0))return cn(e)}function ln(t){if(Array.isArray(t))return t.map(n=>{let e=n.function;return!e||typeof e!="object"?n:{type:"function",name:e.name,description:e.description,parameters:e.parameters,strict:e.strict}})}var we=class extends Error{};function dn(t,n){return Array.isArray(n)?n.map(e=>{let o=e;if(o.type==="text")return{type:t==="assistant"?"output_text":"input_text",text:o.text};if(o.type==="image_url"){let r=o.image_url??{};return{type:"input_image",image_url:r.url,detail:r.detail}}throw new we(`unsupported chat content part type "${String(o.type)}" \u2014 the proxy translates text and image_url parts`)}):n}function pn(t){let n=[];for(let e of t){if(e.role==="tool"){n.push({type:"function_call_output",call_id:e.tool_call_id,output:typeof e.content=="string"?e.content:JSON.stringify(e.content??"")});continue}if(e.role==="assistant"&&Array.isArray(e.tool_calls)){typeof e.content=="string"&&e.content&&n.push({role:"assistant",content:e.content});for(let o of e.tool_calls){let r=o.function??{};n.push({type:"function_call",call_id:o.id,name:r.name,arguments:r.arguments})}continue}n.push({...e,content:dn(e.role,e.content)})}return n}function Ce(t){return ae(t).map((n,e)=>({index:e,id:n.call_id??n.id??`call_${e}`,type:"function",function:{name:n.name??"",arguments:n.arguments??"{}"}}))}function pt(t,n){let e=n?.output_text;return typeof e=="string"?e:t.filter(o=>o.type==="response.output_text.delta"&&typeof o.delta=="string").map(o=>o.delta).join("")}async function fn(t,n,e,o,r){let i=t.stream===!0,s;try{s=e.thread(t.previous_response_id,t.input)}catch(l){q(o,400,String(l instanceof Error?l.message:l));return}t.previous_response_id!=null&&(r.naiveInBytes+=Buffer.byteLength(JSON.stringify(s))-Buffer.byteLength(JSON.stringify(t.input)));let a=`resp_${Math.random().toString(36).slice(2,14)}`,u=t.store!==!1,c=Me(t);r.model(c);let p=Array.isArray(t.tools)&&t.tools.length>0,f;try{f=await n.createResponse({model:t.model,input:s,stream:i,tools:t.tools,tool_choice:t.tool_choice,temperature:t.temperature,top_p:t.top_p,stop:t.stop,max_output_tokens:t.max_output_tokens,...t.reasoning_effort!==void 0?{reasoning_effort:t.reasoning_effort}:{},...t.chat_template_kwargs!==void 0?{chat_template_kwargs:t.chat_template_kwargs}:{}})}catch(l){if(l instanceof U){Le(o,"openai",l);return}throw l}let m=[];if(i){$e(o);let l=g=>{o.write(`event: ${String(g.type??"message")}
2
2
  data: ${JSON.stringify(g)}
3
3
 
4
- `)},A=g=>g.response&&typeof g.response=="object"?{...g,response:{...g.response,id:a}}:g,E=`item_${a.slice(5)}`,N=`rs_${a.slice(5)}`,P=!1,$=!1,d=0,k=()=>{P||(P=!0,l({type:"response.created",response:{id:a,object:"response",status:"in_progress"}}))},M=!1,T=0,L="",D=()=>{M&&(M=!1,l({type:"response.reasoning_text.done",item_id:N,output_index:T,content_index:0,text:L}),l({type:"response.output_item.done",output_index:T,item:{id:N,type:"reasoning",summary:[],content:[{type:"reasoning_text",text:L}],status:"completed"}}))},C=!1,v=0,R="",j=g=>{C&&(C=!1,l({type:"response.output_text.done",item_id:E,output_index:v,content_index:0,text:R}),l({type:"response.content_part.done",item_id:E,output_index:v,content_index:0,part:{type:"output_text",text:R}}),l({type:"response.output_item.done",output_index:v,item:{id:E,type:"message",role:"assistant",status:g,content:[{type:"output_text",text:R}]}}))},G=new Y,x=null,z=-1,ne=g=>{if(!x)return;let S=x;x=null,l({type:"response.function_call_arguments.done",item_id:S.fcId,output_index:S.outputIndex,arguments:S.args}),l({type:"response.output_item.done",output_index:S.outputIndex,item:{id:S.fcId,type:"function_call",call_id:S.callId??S.fcId,name:S.name??"",arguments:S.args,status:g}})},oe=!1;for await(let g of r.track(f,c)){m.push(g);let S=String(g.type??"");if(S==="response.created"||S==="response.in_progress"){P=!0,l(A(g));continue}if(S==="response.output_item.added"){$=!0,l(A(g));continue}if(S==="response.reasoning_text.delta"&&!$){k(),M||(M=!0,T=d++,l({type:"response.output_item.added",output_index:T,item:{id:N,type:"reasoning",summary:[],content:[],status:"in_progress"}})),L+=String(g.delta??""),l({type:"response.reasoning_text.delta",item_id:N,output_index:T,content_index:0,delta:g.delta});continue}if(S==="response.output_text.delta"&&!$){k(),D(),C||(C=!0,v=d++,l({type:"response.output_item.added",output_index:v,item:{id:E,type:"message",role:"assistant",status:"in_progress",content:[]}}),l({type:"response.content_part.added",item_id:E,output_index:v,content_index:0,part:{type:"output_text",text:""}})),R+=String(g.delta??""),l({type:S,item_id:E,output_index:v,content_index:0,delta:g.delta});continue}let O=$?null:ae(g);if(O){if(k(),D(),j("completed"),G.add(O),O.tool_index!==z){ne("completed"),z=O.tool_index;let h=d++;x={fcId:`fc_${a.slice(5)}_${O.tool_index}`,outputIndex:h,callId:O.call_id,name:O.name,args:""},l({type:"response.output_item.added",output_index:h,item:{id:x.fcId,type:"function_call",call_id:x.callId??x.fcId,name:x.name??"",arguments:"",status:"in_progress"}})}x&&(O.call_id&&(x.callId=O.call_id),O.name&&(x.name=O.name),x.args+=O.delta,l({type:"response.function_call_arguments.delta",item_id:x.fcId,output_index:x.outputIndex,delta:O.delta}));continue}if(S==="response.completed"&&!$){let h=ie(g.response),I=Z(p,G.size+h.length,R);if(I){oe=!0,l({type:"error",error:{type:"urun_error",code:"tool_call_parser_missing",message:Q(c,I)}});break}D(),j("completed"),ne("completed"),G.size===0&&h.forEach(J=>{let re=d++,le=J.id??J.call_id??`fc_${re}`,Re=J.arguments??"",We={id:le,type:"function_call",call_id:J.call_id??le,name:J.name??""};l({type:"response.output_item.added",output_index:re,item:{...We,arguments:"",status:"in_progress"}}),l({type:"response.function_call_arguments.delta",item_id:le,output_index:re,delta:Re}),l({type:"response.function_call_arguments.done",item_id:le,output_index:re,arguments:Re}),l({type:"response.output_item.done",output_index:re,item:{...We,arguments:Re,status:"completed"}})}),l(A(g));continue}l(A(g))}D(),j("incomplete"),ne("incomplete"),u&&!oe&&t.remember(a,s,rt(m,K(m))),o.write(`data: [DONE]
4
+ `)},R=g=>g.response&&typeof g.response=="object"?{...g,response:{...g.response,id:a}}:g,E=`item_${a.slice(5)}`,N=`rs_${a.slice(5)}`,C=!1,$=!1,d=0,x=()=>{C||(C=!0,l({type:"response.created",response:{id:a,object:"response",status:"in_progress"}}))},D=!1,T=0,L="",V=()=>{D&&(D=!1,l({type:"response.reasoning_text.done",item_id:N,output_index:T,content_index:0,text:L}),l({type:"response.output_item.done",output_index:T,item:{id:N,type:"reasoning",summary:[],content:[{type:"reasoning_text",text:L}],status:"completed"}}))},P=!1,v=0,A="",j=g=>{P&&(P=!1,l({type:"response.output_text.done",item_id:E,output_index:v,content_index:0,text:A}),l({type:"response.content_part.done",item_id:E,output_index:v,content_index:0,part:{type:"output_text",text:A}}),l({type:"response.output_item.done",output_index:v,item:{id:E,type:"message",role:"assistant",status:g,content:[{type:"output_text",text:A}]}}))},G=new Y,b=null,X=-1,oe=g=>{if(!b)return;let S=b;b=null,l({type:"response.function_call_arguments.done",item_id:S.fcId,output_index:S.outputIndex,arguments:S.args}),l({type:"response.output_item.done",output_index:S.outputIndex,item:{id:S.fcId,type:"function_call",call_id:S.callId??S.fcId,name:S.name??"",arguments:S.args,status:g}})},re=!1;for await(let g of r.track(f,c)){m.push(g);let S=String(g.type??"");if(S==="response.created"||S==="response.in_progress"){C=!0,l(R(g));continue}if(S==="response.output_item.added"){$=!0,l(R(g));continue}if(S==="response.reasoning_text.delta"&&!$){x(),D||(D=!0,T=d++,l({type:"response.output_item.added",output_index:T,item:{id:N,type:"reasoning",summary:[],content:[],status:"in_progress"}})),L+=String(g.delta??""),l({type:"response.reasoning_text.delta",item_id:N,output_index:T,content_index:0,delta:g.delta});continue}if(S==="response.output_text.delta"&&!$){x(),V(),P||(P=!0,v=d++,l({type:"response.output_item.added",output_index:v,item:{id:E,type:"message",role:"assistant",status:"in_progress",content:[]}}),l({type:"response.content_part.added",item_id:E,output_index:v,content_index:0,part:{type:"output_text",text:""}})),A+=String(g.delta??""),l({type:S,item_id:E,output_index:v,content_index:0,delta:g.delta});continue}let O=$?null:ue(g);if(O){if(x(),V(),j("completed"),G.add(O),O.tool_index!==X){oe("completed"),X=O.tool_index;let y=d++;b={fcId:`fc_${a.slice(5)}_${O.tool_index}`,outputIndex:y,callId:O.call_id,name:O.name,args:""},l({type:"response.output_item.added",output_index:y,item:{id:b.fcId,type:"function_call",call_id:b.callId??b.fcId,name:b.name??"",arguments:"",status:"in_progress"}})}b&&(O.call_id&&(b.callId=O.call_id),O.name&&(b.name=O.name),b.args+=O.delta,l({type:"response.function_call_arguments.delta",item_id:b.fcId,output_index:b.outputIndex,delta:O.delta}));continue}if(S==="response.completed"&&!$){let y=ae(g.response),I=ee(p,G.size+y.length,A);if(I){re=!0,l({type:"error",error:{type:"urun_error",code:"tool_call_parser_missing",message:Z(c,I)}});break}V(),j("completed"),oe("completed"),G.size===0&&y.forEach(J=>{let se=d++,de=J.id??J.call_id??`fc_${se}`,Ae=J.arguments??"",Ke={id:de,type:"function_call",call_id:J.call_id??de,name:J.name??""};l({type:"response.output_item.added",output_index:se,item:{...Ke,arguments:"",status:"in_progress"}}),l({type:"response.function_call_arguments.delta",item_id:de,output_index:se,delta:Ae}),l({type:"response.function_call_arguments.done",item_id:de,output_index:se,arguments:Ae}),l({type:"response.output_item.done",output_index:se,item:{...Ke,arguments:Ae,status:"completed"}})}),l(R(g));continue}l(R(g))}V(),j("incomplete"),oe("incomplete"),u&&!re&&e.remember(a,s,pt(m,z(m))),o.write(`data: [DONE]
5
5
 
6
- `),o.end();return}let w=null;for await(let l of r.track(f,c)){if(m.push(l),l.type==="error"){q(o,502,JSON.stringify(l),"upstream_error");return}l.type==="response.completed"&&(w=l.response)}if(w==null){q(o,502,"upstream produced no response.completed event","upstream_error");return}let y=rt(m,w),_=Z(p,ie(w).length,y);if(_){q(o,502,Q(c,_),"upstream_error");return}u&&t.remember(a,s,y),H(o,200,{...w,id:a})}async function rn(e,n,t,o){let r=e.messages;if(!Array.isArray(r)){q(t,400,"chat/completions requires a messages array");return}let i=String(e.model??"urun"),s=`chatcmpl-${Math.random().toString(36).slice(2,14)}`,a;try{a=nn(r)}catch(d){if(d instanceof ye){q(t,400,d.message);return}throw d}let u=Le(e);o.model(u);let c=Array.isArray(e.tools)&&e.tools.length>0,p;try{p=await n.createResponse({model:e.model,input:a,stream:!0,tools:en(e.tools),tool_choice:e.tool_choice,temperature:e.temperature,max_output_tokens:e.max_completion_tokens??e.max_tokens,...e.reasoning_effort!==void 0?{reasoning_effort:e.reasoning_effort}:{},...e.chat_template_kwargs!==void 0?{chat_template_kwargs:e.chat_template_kwargs}:{}})}catch(d){if(d instanceof U){$e(t,"openai",d);return}throw d}if(e.stream===!0){Ne(t);let d=[],k=new Y,M="";t.write(`data: ${JSON.stringify(X(s,i,{role:"assistant"},null))}
6
+ `),o.end();return}let w=null;for await(let l of r.track(f,c)){if(m.push(l),l.type==="error"){q(o,502,JSON.stringify(l),"upstream_error");return}l.type==="response.completed"&&(w=l.response)}if(w==null){q(o,502,"upstream produced no response.completed event","upstream_error");return}let h=pt(m,w),_=ee(p,ae(w).length,h);if(_){q(o,502,Z(c,_),"upstream_error");return}u&&e.remember(a,s,h),M(o,200,{...w,id:a})}async function mn(t,n,e,o){let r=t.messages;if(!Array.isArray(r)){q(e,400,"chat/completions requires a messages array");return}let i=String(t.model??"urun"),s=`chatcmpl-${Math.random().toString(36).slice(2,14)}`,a;try{a=pn(r)}catch(d){if(d instanceof we){q(e,400,d.message);return}throw d}let u=Me(t);o.model(u);let c=Array.isArray(t.tools)&&t.tools.length>0,p;try{p=await n.createResponse({model:t.model,input:a,stream:!0,tools:ln(t.tools),tool_choice:t.tool_choice,temperature:t.temperature,top_p:t.top_p,stop:t.stop,max_output_tokens:t.max_completion_tokens??t.max_tokens,...t.reasoning_effort!==void 0?{reasoning_effort:t.reasoning_effort}:{},...t.chat_template_kwargs!==void 0?{chat_template_kwargs:t.chat_template_kwargs}:{}})}catch(d){if(d instanceof U){Le(e,"openai",d);return}throw d}if(t.stream===!0){$e(e);let d=[],x=new Y,D="";e.write(`data: ${JSON.stringify(Q(s,i,{role:"assistant"},null))}
7
7
 
8
- `);for await(let v of o.track(p,u)){d.push(v);let R=ae(v);if(v.type==="response.output_text.delta"&&typeof v.delta=="string")M+=v.delta,t.write(`data: ${JSON.stringify(X(s,i,{content:v.delta},null))}
8
+ `);for await(let v of o.track(p,u)){d.push(v);let A=ue(v);if(v.type==="response.output_text.delta"&&typeof v.delta=="string")D+=v.delta,e.write(`data: ${JSON.stringify(Q(s,i,{content:v.delta},null))}
9
9
 
10
- `);else if(v.type==="response.reasoning_text.delta"&&typeof v.delta=="string")t.write(`data: ${JSON.stringify(X(s,i,{reasoning_content:v.delta},null))}
10
+ `);else if(v.type==="response.reasoning_text.delta"&&typeof v.delta=="string")e.write(`data: ${JSON.stringify(Q(s,i,{reasoning_content:v.delta},null))}
11
11
 
12
- `);else if(R){let{call:j,isNew:G}=k.add(R),x=G?{index:R.tool_index,id:j.id??`call_${R.tool_index}`,type:"function",function:{name:j.name??"",arguments:R.delta}}:{index:R.tool_index,function:{arguments:R.delta}};t.write(`data: ${JSON.stringify(X(s,i,{tool_calls:[x]},null))}
12
+ `);else if(A){let{call:j,isNew:G}=x.add(A),b=G?{index:A.tool_index,id:j.id??`call_${A.tool_index}`,type:"function",function:{name:j.name??"",arguments:A.delta}}:{index:A.tool_index,function:{arguments:A.delta}};e.write(`data: ${JSON.stringify(Q(s,i,{tool_calls:[b]},null))}
13
13
 
14
- `)}else if(v.type==="error"){t.write(`data: ${JSON.stringify({error:v})}
14
+ `)}else if(v.type==="error"){e.write(`data: ${JSON.stringify({error:v})}
15
15
 
16
- `),t.end();return}}let T=Te(K(d)),L=Z(c,k.size+T.length,M);if(L){t.write(`data: ${JSON.stringify({error:{type:"urun_error",code:"tool_call_parser_missing",message:Q(u,L)}})}
16
+ `),e.end();return}}let T=Ce(z(d)),L=ee(c,x.size+T.length,D);if(L){e.write(`data: ${JSON.stringify({error:{type:"urun_error",code:"tool_call_parser_missing",message:Z(u,L)}})}
17
17
 
18
- `),t.end();return}k.size===0&&T.length>0&&t.write(`data: ${JSON.stringify(X(s,i,{tool_calls:T},null))}
18
+ `),e.end();return}x.size===0&&T.length>0&&e.write(`data: ${JSON.stringify(Q(s,i,{tool_calls:T},null))}
19
19
 
20
- `);let D=k.size>0||T.length>0;t.write(`data: ${JSON.stringify(X(s,i,{},D?"tool_calls":"stop"))}
20
+ `);let V=x.size>0||T.length>0;e.write(`data: ${JSON.stringify(Q(s,i,{},V?"tool_calls":"stop"))}
21
21
 
22
- `),he(K(d))&&t.write(`data: ${JSON.stringify({id:s,object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:i,choices:[],usage:ot(K(d))})}
22
+ `),ye(z(d))&&e.write(`data: ${JSON.stringify({id:s,object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:i,choices:[],usage:dt(z(d))})}
23
23
 
24
- `),t.write(`data: [DONE]
24
+ `),e.write(`data: [DONE]
25
25
 
26
- `),t.end();return}let f="",m="",w=[],y=new Y;for await(let d of o.track(p,u)){w.push(d),d.type==="response.output_text.delta"&&typeof d.delta=="string"&&(f+=d.delta),d.type==="response.reasoning_text.delta"&&typeof d.delta=="string"&&(m+=d.delta);let k=ae(d);if(k&&y.add(k),d.type==="error"){q(t,502,JSON.stringify(d),"upstream_error");return}}let _=K(w),l=Te(_),A=l.length>0?l:Te({output:y.items()}),E=Z(c,A.length,f);if(E){q(t,502,Q(u,E),"upstream_error");return}let N=A.map(({index:d,...k})=>k),P={role:"assistant",content:f||null},$=m||st(_);$&&(P.reasoning_content=$),N.length>0&&(P.tool_calls=N),H(t,200,{id:s,object:"chat.completion",created:Math.floor(Date.now()/1e3),model:i,choices:[{index:0,message:P,finish_reason:N.length>0?"tool_calls":"stop"}],usage:ot(_)})}function sn(e){return typeof e=="string"?e:Array.isArray(e)?e.filter(n=>n.type==="text").map(n=>String(n.text??"")).join(""):""}var ue=class extends Error{};function we(e){return new ue(`unsupported anthropic content block type "${e}" \u2014 the proxy translates text, tool_use and tool_result blocks`)}function an(e){if(Array.isArray(e))return e.map(n=>{let t=n;return{type:"function",name:t.name,description:t.description,parameters:t.input_schema}})}function un(e){if(e==null)return;let n=e.type;if(n==="auto")return"auto";if(n==="none")return"none";if(n==="any")return"required";if(n==="tool")return{type:"function",name:e.name};throw new ue(`unsupported anthropic tool_choice type ${JSON.stringify(String(n))} \u2014 the proxy maps auto, none, any and tool`)}function cn(e){if(typeof e=="string")return e;if(e==null)return"";if(!Array.isArray(e))throw we(typeof e);let n="";for(let t of e){let o=String(t.type??"");if(o!=="text")throw we(`tool_result > ${o}`);n+=String(t.text??"")}return n}function ln(e){let{role:n,content:t}=e;if(typeof t=="string")return[{role:n,content:t}];if(t==null)return[];if(!Array.isArray(t))throw we(typeof t);let o=[],r="",i=()=>{r&&(o.push({role:n,content:r}),r="")};for(let s of t){let a=String(s.type??"");if(a==="text")r+=String(s.text??"");else if(a==="tool_use")i(),o.push({type:"function_call",call_id:s.id,name:s.name,arguments:JSON.stringify(s.input??{})});else if(a==="tool_result")i(),o.push({type:"function_call_output",call_id:s.tool_use_id,output:cn(s.content)});else{if(a==="thinking"||a==="redacted_thinking")continue;throw we(a)}}return i(),o}function Pe(e){return ie(e).map((n,t)=>{let o;try{o=JSON.parse(n.arguments||"{}")}catch{throw new Error(`upstream function_call "${n.name??""}" arguments are not valid JSON`)}return{type:"tool_use",id:n.call_id??n.id??`toolu_${t}`,name:n.name??"",input:o}})}async function dn(e,n,t,o){let r=e.messages;if(!Array.isArray(r)){B(t,400,"invalid_request_error","messages requires a messages array");return}if(typeof e.max_tokens!="number"||!Number.isInteger(e.max_tokens)||e.max_tokens<1){B(t,400,"invalid_request_error","max_tokens is required and must be a positive integer");return}if(e.top_k!==void 0){B(t,400,"invalid_request_error","top_k is not supported: the uRun serve lane exposes temperature/top_p/stop_sequences only");return}if(e.stop_sequences!==void 0&&(!Array.isArray(e.stop_sequences)||e.stop_sequences.some(d=>typeof d!="string"))){B(t,400,"invalid_request_error","stop_sequences must be an array of strings");return}let i=String(e.model??"urun"),s=`msg_${Math.random().toString(36).slice(2,14)}`,a=[],u;try{e.system&&a.push({role:"system",content:sn(e.system)});for(let d of r)a.push(...ln(d));u=un(e.tool_choice)}catch(d){if(d instanceof ue){B(t,400,"invalid_request_error",d.message);return}throw d}let c=Le(e);o.model(c);let p=Array.isArray(e.tools)&&e.tools.length>0,f;try{f=await n.createResponse({model:e.model,input:a,stream:!0,tools:an(e.tools),tool_choice:u,temperature:e.temperature,max_output_tokens:e.max_tokens,top_p:e.top_p,stop:e.stop_sequences})}catch(d){if(d instanceof U){$e(t,"anthropic",d);return}throw d}let m=(d,k)=>{t.destroyed||t.write(`event: ${d}
27
- data: ${JSON.stringify({type:d,...k})}
26
+ `),e.end();return}let f="",m="",w=[],h=new Y;for await(let d of o.track(p,u)){w.push(d),d.type==="response.output_text.delta"&&typeof d.delta=="string"&&(f+=d.delta),d.type==="response.reasoning_text.delta"&&typeof d.delta=="string"&&(m+=d.delta);let x=ue(d);if(x&&h.add(x),d.type==="error"){q(e,502,JSON.stringify(d),"upstream_error");return}}let _=z(w),l=Ce(_),R=l.length>0?l:Ce({output:h.items()}),E=ee(c,R.length,f);if(E){q(e,502,Z(u,E),"upstream_error");return}let N=R.map(({index:d,...x})=>x),C={role:"assistant",content:f||null},$=m||ft(_);$&&(C.reasoning_content=$),N.length>0&&(C.tool_calls=N),M(e,200,{id:s,object:"chat.completion",created:Math.floor(Date.now()/1e3),model:i,choices:[{index:0,message:C,finish_reason:N.length>0?"tool_calls":"stop"}],usage:dt(_)})}function gn(t){return typeof t=="string"?t:Array.isArray(t)?t.filter(n=>n.type==="text").map(n=>String(n.text??"")).join(""):""}var ce=class extends Error{};function _e(t){return new ce(`unsupported anthropic content block type "${t}" \u2014 the proxy translates text, tool_use and tool_result blocks`)}function hn(t){if(Array.isArray(t))return t.map(n=>{let e=n;return{type:"function",name:e.name,description:e.description,parameters:e.input_schema}})}function yn(t){if(t==null)return;let n=t.type;if(n==="auto")return"auto";if(n==="none")return"none";if(n==="any")return"required";if(n==="tool")return{type:"function",name:t.name};throw new ce(`unsupported anthropic tool_choice type ${JSON.stringify(String(n))} \u2014 the proxy maps auto, none, any and tool`)}function wn(t){if(typeof t=="string")return t;if(t==null)return"";if(!Array.isArray(t))throw _e(typeof t);let n="";for(let e of t){let o=String(e.type??"");if(o!=="text")throw _e(`tool_result > ${o}`);n+=String(e.text??"")}return n}function _n(t){let{role:n,content:e}=t;if(typeof e=="string")return[{role:n,content:e}];if(e==null)return[];if(!Array.isArray(e))throw _e(typeof e);let o=[],r="",i=()=>{r&&(o.push({role:n,content:r}),r="")};for(let s of e){let a=String(s.type??"");if(a==="text")r+=String(s.text??"");else if(a==="tool_use")i(),o.push({type:"function_call",call_id:s.id,name:s.name,arguments:JSON.stringify(s.input??{})});else if(a==="tool_result")i(),o.push({type:"function_call_output",call_id:s.tool_use_id,output:wn(s.content)});else{if(a==="thinking"||a==="redacted_thinking")continue;throw _e(a)}}return i(),o}function Pe(t){return ae(t).map((n,e)=>{let o;try{o=JSON.parse(n.arguments||"{}")}catch{throw new Error(`upstream function_call "${n.name??""}" arguments are not valid JSON`)}return{type:"tool_use",id:n.call_id??n.id??`toolu_${e}`,name:n.name??"",input:o}})}async function vn(t,n,e,o){let r=t.messages;if(!Array.isArray(r)){B(e,400,"invalid_request_error","messages requires a messages array");return}if(typeof t.max_tokens!="number"||!Number.isInteger(t.max_tokens)||t.max_tokens<1){B(e,400,"invalid_request_error","max_tokens is required and must be a positive integer");return}if(t.top_k!==void 0){B(e,400,"invalid_request_error","top_k is not supported: the uRun serve lane exposes temperature/top_p/stop_sequences only");return}if(t.stop_sequences!==void 0&&(!Array.isArray(t.stop_sequences)||t.stop_sequences.some(d=>typeof d!="string"))){B(e,400,"invalid_request_error","stop_sequences must be an array of strings");return}let i=String(t.model??"urun"),s=`msg_${Math.random().toString(36).slice(2,14)}`,a=[],u;try{t.system&&a.push({role:"system",content:gn(t.system)});for(let d of r)a.push(..._n(d));u=yn(t.tool_choice)}catch(d){if(d instanceof ce){B(e,400,"invalid_request_error",d.message);return}throw d}let c=Me(t);o.model(c);let p=Array.isArray(t.tools)&&t.tools.length>0,f;try{f=await n.createResponse({model:t.model,input:a,stream:!0,tools:hn(t.tools),tool_choice:u,temperature:t.temperature,max_output_tokens:t.max_tokens,top_p:t.top_p,stop:t.stop_sequences})}catch(d){if(d instanceof U){Le(e,"anthropic",d);return}throw d}let m=(d,x)=>{e.destroyed||e.write(`event: ${d}
27
+ data: ${JSON.stringify({type:d,...x})}
28
28
 
29
- `)};if(e.stream===!0){let d=o.track(f,c);Ne(t),m("message_start",{message:{id:s,type:"message",role:"assistant",content:[],model:i,stop_reason:null,usage:{input_tokens:0,output_tokens:0}}});let k=0,M="",T=0,L="none",D=()=>L,C=-1,v=-1,R=new Y,j=[],G=()=>{L!=="none"&&(L="none",m("content_block_stop",{index:C}))},x=(h,I)=>{G(),L=h,C=T++,m("content_block_start",{index:C,content_block:I})};for await(let h of d){if(t.destroyed)break;j.push(h);let I=ae(h);if(h.type==="response.reasoning_text.delta"&&typeof h.delta=="string")D()!=="thinking"&&x("thinking",{type:"thinking",thinking:""}),m("content_block_delta",{index:C,delta:{type:"thinking_delta",thinking:h.delta}});else if(h.type==="response.output_text.delta"&&typeof h.delta=="string")D()!=="text"&&x("text",{type:"text",text:""}),k+=1,M+=h.delta,m("content_block_delta",{index:C,delta:{type:"text_delta",text:h.delta}});else if(I){let{call:J}=R.add(I);(D()!=="tool"||I.tool_index!==v)&&(v=I.tool_index,x("tool",{type:"tool_use",id:J.id??`call_${I.tool_index}`,name:J.name??"",input:{}})),I.delta&&m("content_block_delta",{index:C,delta:{type:"input_json_delta",partial_json:I.delta}})}else if(h.type==="error"){m("error",{error:{type:"api_error",message:JSON.stringify(h)}}),t.end();return}}if(t.destroyed)return;let z=K(j),ne=ie(z),oe=Z(p,R.size+ne.length,M);if(oe){m("error",{error:{type:"api_error",message:Q(c,oe)}}),t.end();return}G();let g=[];if(R.size===0)try{g=Pe(z)}catch(h){m("error",{error:{type:"api_error",message:String(h instanceof Error?h.message:h)}}),t.end();return}T===0&&g.length===0&&(x("text",{type:"text",text:""}),G()),g.forEach(h=>{let I=T++;m("content_block_start",{index:I,content_block:{...h,input:{}}}),m("content_block_delta",{index:I,delta:{type:"input_json_delta",partial_json:JSON.stringify(h.input??{})}}),m("content_block_stop",{index:I})});let S=R.size>0||g.length>0,O=he(z);m("message_delta",{delta:{stop_reason:S?"tool_use":"end_turn"},usage:O?{input_tokens:O.input_tokens,output_tokens:O.output_tokens}:{output_tokens:k}}),m("message_stop",{}),t.end();return}let w="",y="",_=[],l=new Y;for await(let d of o.track(f,c)){_.push(d),d.type==="response.output_text.delta"&&typeof d.delta=="string"&&(w+=d.delta),d.type==="response.reasoning_text.delta"&&typeof d.delta=="string"&&(y+=d.delta);let k=ae(d);if(k&&l.add(k),d.type==="error"){B(t,502,"api_error",JSON.stringify(d));return}if(t.destroyed)break}if(t.destroyed)return;let A=K(_),E;try{E=Pe(A),E.length===0&&l.size>0&&(E=Pe({output:l.items()}))}catch(d){B(t,502,"api_error",String(d instanceof Error?d.message:d));return}let N=Z(p,E.length,w);if(N){B(t,502,"api_error",Q(c,N));return}let P=[],$=y||st(A);$&&P.push({type:"thinking",thinking:$}),(w||E.length===0)&&P.push({type:"text",text:w}),P.push(...E),H(t,200,{id:s,type:"message",role:"assistant",content:P,model:i,stop_reason:E.length>0?"tool_use":"end_turn",usage:he(A)??{input_tokens:0,output_tokens:0}})}function it(e){let{clients:n,apiKey:t,identity:o,statusOf:r}=e,i=typeof n=="function"?n:()=>n,s=new WeakMap,a=c=>{let p=s.get(c);return p||(p=new Ue,s.set(c,p)),p},u=new Ce;return(c,p)=>{let f=new URL(c.url??"/","http://localhost"),m=f.pathname==="/v1/messages"||f.pathname.startsWith("/v1/messages/"),w=(y,_,l,A)=>m?B(p,y,A,_):q(p,y,_,l);(async()=>{if(c.method==="GET"&&f.pathname==="/healthz"){H(p,200,{ok:!0});return}if(c.method==="GET"&&f.pathname==="/stats"){H(p,200,o?{identity:o,...u.snapshot()}:u.snapshot());return}if(t&&(c.headers.authorization??"")!==`Bearer ${t}`){w(401,"invalid local proxy api key","authentication_error","authentication_error");return}let y=await i(c);if(c.method==="GET"&&f.pathname==="/v1/models"){H(p,200,await y.listModels());return}if(c.method!=="POST"){w(404,`no route for ${c.method} ${f.pathname}`,"invalid_request_error","not_found_error");return}let _;try{_=await Yt(c)}catch(A){if(A instanceof ge){w(413,A.message,"request_too_large","request_too_large");return}w(400,"request body is not valid JSON","invalid_request_error","invalid_request_error");return}let l=Buffer.byteLength(JSON.stringify(_));if(f.pathname==="/v1/responses"){u.request("responses",l,l),await on(_,y,a(y),p,u);return}if(f.pathname==="/v1/chat/completions"){u.request("chat_completions",l,l),await rn(_,y,p,u);return}if(f.pathname==="/v1/messages"){u.request("messages",l,l),await dn(_,y,p,u);return}if(f.pathname==="/v1/messages/count_tokens"){u.request("count_tokens",l,l),B(p,404,"not_found_error","count_tokens is not implemented by the uRun proxy: the serve transport exposes no token-count lane, and the proxy will not fabricate counts");return}w(404,`no route for POST ${f.pathname}`,"invalid_request_error","not_found_error")})().catch(y=>{let _=String(y instanceof Error?y.message:y);if(!p.headersSent){let l=r?.(y)??null;if(l){w(l.status,_,l.openaiType,l.anthropicType);return}w(500,_,"proxy_error","api_error");return}p.destroyed||(m?p.write(`event: error
29
+ `)};if(t.stream===!0){let d=o.track(f,c);$e(e),m("message_start",{message:{id:s,type:"message",role:"assistant",content:[],model:i,stop_reason:null,usage:{input_tokens:0,output_tokens:0}}});let x=0,D="",T=0,L="none",V=()=>L,P=-1,v=-1,A=new Y,j=[],G=()=>{L!=="none"&&(L="none",m("content_block_stop",{index:P}))},b=(y,I)=>{G(),L=y,P=T++,m("content_block_start",{index:P,content_block:I})};for await(let y of d){if(e.destroyed)break;j.push(y);let I=ue(y);if(y.type==="response.reasoning_text.delta"&&typeof y.delta=="string")V()!=="thinking"&&b("thinking",{type:"thinking",thinking:""}),m("content_block_delta",{index:P,delta:{type:"thinking_delta",thinking:y.delta}});else if(y.type==="response.output_text.delta"&&typeof y.delta=="string")V()!=="text"&&b("text",{type:"text",text:""}),x+=1,D+=y.delta,m("content_block_delta",{index:P,delta:{type:"text_delta",text:y.delta}});else if(I){let{call:J}=A.add(I);(V()!=="tool"||I.tool_index!==v)&&(v=I.tool_index,b("tool",{type:"tool_use",id:J.id??`call_${I.tool_index}`,name:J.name??"",input:{}})),I.delta&&m("content_block_delta",{index:P,delta:{type:"input_json_delta",partial_json:I.delta}})}else if(y.type==="error"){m("error",{error:{type:"api_error",message:JSON.stringify(y)}}),e.end();return}}if(e.destroyed)return;let X=z(j),oe=ae(X),re=ee(p,A.size+oe.length,D);if(re){m("error",{error:{type:"api_error",message:Z(c,re)}}),e.end();return}G();let g=[];if(A.size===0)try{g=Pe(X)}catch(y){m("error",{error:{type:"api_error",message:String(y instanceof Error?y.message:y)}}),e.end();return}T===0&&g.length===0&&(b("text",{type:"text",text:""}),G()),g.forEach(y=>{let I=T++;m("content_block_start",{index:I,content_block:{...y,input:{}}}),m("content_block_delta",{index:I,delta:{type:"input_json_delta",partial_json:JSON.stringify(y.input??{})}}),m("content_block_stop",{index:I})});let S=A.size>0||g.length>0,O=ye(X);m("message_delta",{delta:{stop_reason:S?"tool_use":"end_turn"},usage:O?{input_tokens:O.input_tokens,output_tokens:O.output_tokens}:{output_tokens:x}}),m("message_stop",{}),e.end();return}let w="",h="",_=[],l=new Y;for await(let d of o.track(f,c)){_.push(d),d.type==="response.output_text.delta"&&typeof d.delta=="string"&&(w+=d.delta),d.type==="response.reasoning_text.delta"&&typeof d.delta=="string"&&(h+=d.delta);let x=ue(d);if(x&&l.add(x),d.type==="error"){B(e,502,"api_error",JSON.stringify(d));return}if(e.destroyed)break}if(e.destroyed)return;let R=z(_),E;try{E=Pe(R),E.length===0&&l.size>0&&(E=Pe({output:l.items()}))}catch(d){B(e,502,"api_error",String(d instanceof Error?d.message:d));return}let N=ee(p,E.length,w);if(N){B(e,502,"api_error",Z(c,N));return}let C=[],$=h||ft(R);$&&C.push({type:"thinking",thinking:$}),(w||E.length===0)&&C.push({type:"text",text:w}),C.push(...E),M(e,200,{id:s,type:"message",role:"assistant",content:C,model:i,stop_reason:E.length>0?"tool_use":"end_turn",usage:ye(R)??{input_tokens:0,output_tokens:0}})}function mt(t){let{clients:n,apiKey:e,identity:o,statusOf:r}=t,i=typeof n=="function"?n:()=>n,s=new WeakMap,a=c=>{let p=s.get(c);return p||(p=new Ne,s.set(c,p)),p},u=new Ue;return(c,p)=>{let f=new URL(c.url??"/","http://localhost"),m=f.pathname==="/v1/messages"||f.pathname.startsWith("/v1/messages/"),w=(h,_,l,R)=>m?B(p,h,R,_):q(p,h,_,l);(async()=>{if(c.method==="GET"&&f.pathname==="/healthz"){M(p,200,{ok:!0});return}if(c.method==="GET"&&f.pathname==="/stats"){M(p,200,o?{identity:o,...u.snapshot()}:u.snapshot());return}if(e&&(c.headers.authorization??"")!==`Bearer ${e}`){w(401,"invalid local proxy api key","authentication_error","authentication_error");return}let h=await i(c);if(c.method==="GET"&&f.pathname==="/v1/models"){if(f.searchParams.get("format")==="openrouter"){if(!h.openRouterModels){w(501,"format=openrouter needs a router-backed client (openRouterModels)","not_implemented","not_implemented_error");return}M(p,200,await h.openRouterModels());return}M(p,200,await h.listModels());return}if(c.method!=="POST"){w(404,`no route for ${c.method} ${f.pathname}`,"invalid_request_error","not_found_error");return}let _;try{_=await rn(c)}catch(R){if(R instanceof he){w(413,R.message,"request_too_large","request_too_large");return}w(400,"request body is not valid JSON","invalid_request_error","invalid_request_error");return}let l=Buffer.byteLength(JSON.stringify(_));if(f.pathname==="/v1/responses"){u.request("responses",l,l),await fn(_,h,a(h),p,u);return}if(f.pathname==="/v1/chat/completions"){u.request("chat_completions",l,l),await mn(_,h,p,u);return}if(f.pathname==="/v1/messages"){u.request("messages",l,l),await vn(_,h,p,u);return}if(f.pathname==="/v1/messages/count_tokens"){u.request("count_tokens",l,l),B(p,404,"not_found_error","count_tokens is not implemented by the uRun proxy: the serve transport exposes no token-count lane, and the proxy will not fabricate counts");return}w(404,`no route for POST ${f.pathname}`,"invalid_request_error","not_found_error")})().catch(h=>{let _=String(h instanceof Error?h.message:h);if(!p.headersSent){let l=r?.(h)??null;if(l){w(l.status,_,l.openaiType,l.anthropicType);return}w(500,_,"proxy_error","api_error");return}p.destroyed||(m?p.write(`event: error
30
30
  data: ${JSON.stringify({type:"error",error:{type:"api_error",message:_}})}
31
31
 
32
32
  `):p.write(`data: ${JSON.stringify({error:{message:_,type:"upstream_error"}})}
33
33
 
34
- `)),p.end()})}}var _e=require("@urun-sh/core"),F=class extends Error{constructor(t,o=401){super(t);this.status=o;this.name="ProxyAuthError"}status},W=class extends Error{constructor(n){super(n),this.name="ControlPlaneUnavailableError"}};function ve(e){let n=(e??"").trim();if(n==="")throw new F("missing Authorization header \u2014 send your uRun org API key as `Authorization: Bearer <key>`");let t=/^Bearer[ \t]+(\S.*)$/i.exec(n);if(!t)throw new F("malformed Authorization header \u2014 expected `Authorization: Bearer <urun org api key>`");return t[1].trim()}var pn=60,Me=6e4,De=4096;function fn(e){return e===401||e===403}var ee=class{constructor(n){this.opts=n;this.mint=n.mint??_e.createClientToken,this.now=n.now??Date.now}opts;cache=new Map;mint;now;async resolve(n){if(n==="")throw new F("empty Authorization bearer token");let t=this.cache.get(n);if(t&&this.now()-t.at<Me)return{apiKey:n,orgId:t.orgId};let o;try{o=(await this.mint(n,{baseUrl:this.opts.gatewayUrl,expiresIn:pn})).orgId}catch(r){throw r instanceof _e.ClientTokenError&&fn(r.status)?(this.cache.delete(n),new F("the uRun org API key was rejected by the control plane \u2014 check the key and that it is not revoked")):new W(`could not verify the API key against the uRun control plane at ${this.opts.gatewayUrl}: ${r instanceof Error?r.message:String(r)}`)}if(!o)throw new W("the control plane verified the API key but returned no org_id \u2014 refusing to route a request with no tenancy (control-plane contract violation)");if(this.cache.size>=De){let r=this.cache.keys().next();r.done||this.cache.delete(r.value)}return this.cache.set(n,{orgId:o,at:this.now()}),{apiKey:n,orgId:o}}clear(){this.cache.clear()}};var vt=require("crypto");var ce=require("@urun-sh/core");async function at(e){let t=await(e.fetchImpl??fetch)(`${e.catalogUrl}/model_catalog?select=model_id,variant`,{headers:{apikey:e.anonKey,Authorization:`Bearer ${e.anonKey}`}});if(!t.ok)throw new Error(`model_catalog fetch failed: ${t.status}`);return await t.json()}function ut(e,n,t,o){let r=e.response??{},i={request_id:t,consumer_id:o,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 ct(e,n,t){let o={request_id:n,consumer_id:t,stream:!!e.stream,kind:"responses",input:e.input};return e.model&&(o.model=e.model),e.tools!==void 0&&(o.tools=e.tools),e.tool_choice!==void 0&&(o.tool_choice=e.tool_choice),typeof e.temperature=="number"&&(o.temperature=e.temperature),typeof e.max_output_tokens=="number"&&(o.max_output_tokens=e.max_output_tokens),typeof e.reasoning_effort=="string"&&(o.reasoning_effort=e.reasoning_effort),e.chat_template_kwargs!==void 0&&(o.chat_template_kwargs=e.chat_template_kwargs),o}function lt(e){if(e instanceof Error)return{type:"error",error:{type:"urun_error",code:e.name||null,message:e.message}};if(e&&typeof e=="object"&&e.t==="error"){let n=e,t=n.body??{};return{type:"error",error:{type:"urun_error",code:n.code??null,message:t.message??"unknown error"}}}return{type:"error",error:{type:"urun_error",code:null,message:String(e)}}}var mn="llm-resp";async function*Ve(e,n){let t=`${mn}:${n}`,o=`resp_${n}`;yield{type:"response.created",response:{id:o,status:"in_progress"}};let r=new Map;for await(let i of e.stream(t).messages()){let s=i;if(s.t==="delta"){if(typeof s.delta=="string"&&(yield{type:"response.output_text.delta",item_id:o,delta:s.delta}),typeof s.reasoning=="string"&&(yield{type:"response.reasoning_text.delta",item_id:o,delta:s.reasoning}),Array.isArray(s.tool_calls))for(let a of s.tool_calls){let u=typeof a.index=="number"?a.index:0,c=r.get(u)??{};a.id&&(c.id=a.id),a.function?.name&&(c.name=a.function.name),r.set(u,c),yield{type:"response.function_call_arguments.delta",item_id:`fc_${n}_${u}`,tool_index:u,call_id:c.id,name:c.name,delta:a.function?.arguments??""}}}else if(s.t==="response"){yield{type:"response.completed",response:{id:o,status:"completed",...s.body}};return}else if(s.t==="error"){yield lt(s);return}}}var gn="llm",ke=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(gn).set({requests:{[n.request_id]:{payload:n,consumer_id:n.consumer_id,stream:n.stream}}})}sendResponses(n,t){let o=ct(n,t,this.consumerId);return this.write(o),Ve(this.session,t)}sendResponseCreate(n,t,o){let r=ut(n,t,o,this.consumerId);return this.write(r),Ve(this.session,o)}};var dt=0;function hn(){return dt+=1,`req_${Date.now().toString(36)}_${dt.toString(36)}`}var xe=class{transport;constructor(n){this.transport=new ke(n)}responses={create:async n=>{let t=hn(),o=this.transport.sendResponses(n,t);return Object.assign((async function*(){yield*o})(),{requestId:t})}}};function yn(e){let n=e?.type;return n==="response.created"||n==="response.in_progress"}function wn(e){let n=e?.type;return n==="response.completed"||n==="error"}function pt(e){return async function(t){return(async function*(){for(let r=1;r<=2;r++){let{app:i,entry:s}=await e.sessionFor(t.model),a=!1,u=!1;try{let c=await e.createStream(s,t);for await(let p of c){if(wn(p)&&(a=!0),yn(p)){if(r>1)continue}else u=!0;yield p}}catch(c){if(r<2&&!u){await e.evict(i,s);continue}throw c}if(a)return;if(r<2&&!u){await e.evict(i,s);continue}return}})()}}var _n=3,vn="llm",kn=new Set(["paused","error"]);function ft(e,n){let t=e.doc(vn),o=typeof t.onConnectionState=="function",r=typeof e.onPhase=="function";if(!o&&!r)throw new Error(`session for app "${n}" exposes neither a doc connection-state surface nor onPhase \u2014 session-gone detection requires @urun-sh/core Session (SessionDocument.onConnectionState / Session.onPhase); pooling a session with no native lifecycle signal would silently swallow requests dispatched after the platform closes it`);let i=null,s=new Set,a=[],u=c=>{if(!i){i=c;for(let p of[...s])p(c);s.clear()}};return o&&a.push(t.onConnectionState(c=>{c.consecutiveFailures<_n||u(new V(`the pooled session for app "${n}" is gone: its doc backhaul failed ${c.consecutiveFailures} consecutive times (last close ${c.lastCloseCode===null?"by provider liveness reap":`code ${c.lastCloseCode}`}${c.lastCloseReason?`, reason ${JSON.stringify(c.lastCloseReason)}`:""}) \u2014 the platform closed the session (idle timeout or a serve-side crash). The entry is evicted; retry to get a fresh session.`))})),r&&a.push(e.onPhase(c=>{kn.has(c.name)&&u(new V(`the pooled session for app "${n}" lost its compute binding (phase "${c.name}"). The entry is evicted; retry to get a fresh session. The named session itself is not over \u2014 it stays attachable by name.`))})),{gone:()=>i,onGone(c){return i?(c(i),()=>{}):(s.add(c),()=>s.delete(c))},dispose(){s.clear();for(let c of a.splice(0))c()}}}async function*Be(e,n){let t=n.gone();if(t)throw t;let o=e[Symbol.asyncIterator](),r,i=new Promise((s,a)=>{r=n.onGone(u=>a(u))});i.catch(()=>{});try{for(;;){let s=await Promise.race([o.next(),i]);if(s.done)return;yield s.value}}finally{r?.(),o.return?.(void 0)}}function mt(e,n,t){let o=e[t];if(typeof o!="function")throw new Error(`app "${n}" has no function "${t}" (set URUN_FUNCTION)`);let r=o();if(typeof r.end!="function")throw new Error(`app "${n}" function "${t}" returned a session without end()`);return r}function xn(e,n){let{baseUrl:t,orgId:o,fnName:r,auth:i,subject:s}=e,a=f=>({session:f,responses:new xe(f),gone:ft(f,n)});if(i.lane==="jwt"){let f=(0,ce.App)(n,{baseUrl:t,orgId:o,jwt:i.jwt});return a(mt(f,n,r))}let{apiKey:u,gatewayUrl:c}=i,p=(0,ce.App)(n,{baseUrl:t,orgId:o,getAccessToken:async()=>(await(0,ce.createClientToken)(u,{baseUrl:c,expiresIn:300,allowedFunctions:[`${n}/${r}`],...s===void 0?{}:{subject:s}})).token});return a(mt(p,n,r))}function bn(e){let n=e.session.id;if(typeof n!="string"||n.length===0)throw new Error("pooled session exposes no stable session id \u2014 the session-identity seam requires @urun-sh/core Session (session.id)");return n}var Sn=new Set(["error","paused"]);function gt(e){let{auth:n,catalog:t}=e,o=null,r=s=>{let a=xn(e,s);return a.gone.onGone(()=>{o?.evict(s,a)}),a},i=new fe({defaultApp:e.defaultApp,fnName:e.fnName,openSession:r,closeSession:async s=>{s.gone.dispose(),await s.session.end()},listApps:n.lane==="api-key"?()=>Ye({apiUrl:e.apiUrl,apiKey:n.apiKey}):null,listCatalog:t?()=>at(t):null,sessionKey:bn});return o=i,e.defaultApp!==null&&i.seed(e.defaultApp,r(e.defaultApp)),i}function ht(e,n=et){let t=new WeakMap,o=new WeakMap,r=new WeakMap;return{createResponse:pt({sessionFor:i=>e.sessionFor(i),evict:(i,s)=>e.evict(i,s),createStream:async(i,s)=>Be(await i.responses.responses.create(s),i.gone)}),listModels:()=>e.modelList(),openAudio:async i=>{let{entry:s}=await e.sessionFor(i),a=t.get(s);return a||(a=(async()=>Qe(s.session,await n()))(),t.set(s,a),a.catch(()=>t.delete(s))),a},openVideo:async i=>{let{entry:s}=await e.sessionFor(i),a=o.get(s);return a||(a=Ze(s.session),o.set(s,a)),a},openVideoOut:async i=>{let{entry:s}=await e.sessionFor(i),a=r.get(s);return a||(a=tt(s.session),r.set(s,a)),a},sessionHandle:async i=>(await e.handleFor(i)).handle,createResponseOn:async(i,s)=>{let{entry:a}=await e.sessionForHandle(i);return Be(await a.responses.responses.create(s),a.gone)},onSessionEnd:async(i,s)=>{let{entry:a}=await e.sessionForHandle(i),u=a.session;if(typeof u.onPhase!="function")throw new Error("pooled session exposes no onPhase \u2014 session-end (goAway) wiring requires @urun-sh/core Session");let c=!1;return u.onPhase(p=>{if(c||!Sn.has(p.name))return;c=!0;let f=u.endsAt??null;s({timeLeftMs:f?Math.max(0,f.getTime()-Date.now()):null,reason:p.reason??`session ${p.name}`})})}}}var Rn=pe(require("os"),1),An=pe(require("path"),1),En=require("url"),On=require("util");function yt(e,n="URUN_BASE_URL"){if(/\/v1\/*$/.test(new URL(e).pathname))throw new Error(`${n} must be the session-gateway base (e.g. https://api.urun.sh), got ${e} \u2014 a trailing /v1 is the org control-plane API form (that belongs in URUN_API_URL); session allocation 404s against it. Drop the /v1.`);return e}function be(e,n="URUN_GATEWAY_URL"){let t=new URL(e),o=t.hostname==="localhost"||t.hostname==="127.0.0.1"||t.hostname==="[::1]";if(t.protocol!=="https:"&&!o)throw new Error(`${n} must be https (got ${e}) \u2014 the org API key rides the request's Authorization header`);return e}var He=8080,Se="serve",wt="0.0.0.0";function In(e,n,t){let o=(e[n]??"").trim();if(!o)throw new Error(`${n} is not set \u2014 ${t}`);return o}function _t(e=process.env){let n=(e.PORT??"").trim(),t=n===""?He:Number(n);if(!Number.isInteger(t)||t<0||t>65535)throw new Error(`PORT must be an integer in 0..65535, got ${JSON.stringify(n)}`);let o=yt(be(In(e,"URUN_BASE_URL","the hosted proxy needs the uRun session-gateway base it opens sessions and verifies API keys against (e.g. https://api.urun.sh)"),"URUN_BASE_URL")),r=(e.URUN_API_URL??"").trim(),i=r?be(r,"URUN_API_URL"):`${o.replace(/\/+$/,"")}/v1`,s=(e.URUN_CATALOG_URL??"").trim(),a=(e.URUN_CATALOG_ANON_KEY??"").trim();if(!!s!=!!a)throw new Error("URUN_CATALOG_URL and URUN_CATALOG_ANON_KEY must be set together (or both left unset) \u2014 exactly one of them is set, which would silently disable the model-catalog oracle");let u=s?{catalogUrl:be(s,"URUN_CATALOG_URL"),anonKey:a}:null;return{port:t,baseUrl:o,apiUrl:i,catalog:u}}var Fe=512;function je(e){return`urun-inference-proxy-${(0,vt.createHash)("sha256").update(e).digest("hex").slice(0,32)}`}var te=class{constructor(n){this.opts=n}opts;tenants=new Map;build(n){if(this.opts.build)return this.opts.build(n);let t=gt({baseUrl:this.opts.baseUrl,orgId:n.orgId,defaultApp:null,fnName:Se,apiUrl:this.opts.apiUrl,auth:{lane:"api-key",apiKey:n.apiKey,gatewayUrl:this.opts.baseUrl},catalog:this.opts.catalog,subject:je(n.apiKey)});return{router:t,clients:ht(t)}}clientsFor(n){let t=this.tenants.get(n.apiKey);if(t)return this.tenants.delete(n.apiKey),this.tenants.set(n.apiKey,t),t.clients;for(;this.tenants.size>=Fe;){let r=this.tenants.entries().next();if(r.done)break;let[i,s]=r.value;this.tenants.delete(i),s.router.closeAll().catch(()=>{})}let o=this.build(n);return this.tenants.set(n.apiKey,o),o.clients}get size(){return this.tenants.size}async closeAll(){let n=[...this.tenants.values()].map(o=>o.router);this.tenants.clear();let t=[];if(await Promise.all(n.map(async o=>{try{await o.closeAll()}catch(r){t.push(String(r instanceof Error?r.message:r))}})),t.length>0)throw new Error(`failed to close ${t.length} tenant backhaul(s): ${t.join("; ")}`)}};var qe=5e3,Je=3e3,Tn="/api/client-tokens";function Ge(e,n,t){e.writeHead(n,{"content-type":"application/json"}),e.end(JSON.stringify(t))}function kt(e,n,t,o){Ge(e,n,{error:{message:t,type:o}})}async function Pn(e,n=fetch){let t=`${e.replace(/\/+$/,"")}${Tn}`;try{let o=await n(t,{method:"POST",headers:{"content-type":"application/json"},body:"{}",signal:AbortSignal.timeout(Je)});return o.status===404?{ready:!1,detail:`${t} answered 404 \u2014 this is not a uRun control plane`}:o.status>=500?{ready:!1,detail:`${t} answered HTTP ${o.status}`}:{ready:!0,detail:`${t} answered HTTP ${o.status}`}}catch(o){return{ready:!1,detail:`${t} unreachable: ${o instanceof Error?o.message:String(o)}`}}}function bt(e){let n=e.resolver??new ee({gatewayUrl:e.baseUrl}),t=e.registry??new te({baseUrl:e.baseUrl,apiUrl:e.apiUrl,catalog:e.catalog}),o=e.probeControlPlane??(()=>Pn(e.baseUrl)),r=async u=>n.resolve(ve(u.headers.authorization)),i=it({clients:async u=>t.clientsFor(await r(u)),statusOf:u=>u instanceof F?{status:u.status,openaiType:"authentication_error",anthropicType:"authentication_error"}:u instanceof W?{status:502,openaiType:"upstream_error",anthropicType:"api_error"}:null}),s=null;return{server:(0,xt.createServer)((u,c)=>{let p=new URL(u.url??"/","http://localhost");(async()=>{if(u.method==="GET"&&p.pathname==="/healthz"){Ge(c,200,{ok:!0});return}if(u.method==="GET"&&p.pathname==="/readyz"){let f=Date.now();if(!s||f-s.at>=qe){let m=await o();s={at:f,...m}}Ge(c,s.ready?200:503,{ok:s.ready,control_plane:s.detail});return}if(p.pathname!=="/v1"&&!p.pathname.startsWith("/v1/")){kt(c,404,`no route for ${u.method} ${p.pathname} \u2014 this endpoint serves the OpenAI-compatible /v1 surface plus /healthz and /readyz`,"invalid_request_error");return}i(u,c)})().catch(f=>{if(!c.headersSent){kt(c,500,String(f instanceof Error?f.message:f),"proxy_error");return}c.end()})}),closeAll:()=>t.closeAll()}}0&&(module.exports={BIND_HOST,ControlPlaneUnavailableError,DEFAULT_PORT,MAX_CACHED_KEYS,MAX_TENANTS,ORG_BINDING_TTL_MS,OrgResolver,ProxyAuthError,READINESS_TIMEOUT_MS,READINESS_TTL_MS,SERVE_FUNCTION,TenantRegistry,bearerFrom,createHostedProxy,resolveHostedConfig,tenantSubject});
34
+ `)),p.end()})}}var ve=require("@urun-sh/core"),F=class extends Error{constructor(e,o=401){super(e);this.status=o;this.name="ProxyAuthError"}status},W=class extends Error{constructor(n){super(n),this.name="ControlPlaneUnavailableError"}};function ke(t){let n=(t??"").trim();if(n==="")throw new F("missing Authorization header \u2014 send your uRun org API key as `Authorization: Bearer <key>`");let e=/^Bearer[ \t]+(\S.*)$/i.exec(n);if(!e)throw new F("malformed Authorization header \u2014 expected `Authorization: Bearer <urun org api key>`");return e[1].trim()}var kn=60,De=6e4,Ve=4096;function xn(t){return t===401||t===403}var te=class{constructor(n){this.opts=n;this.mint=n.mint??ve.createClientToken,this.now=n.now??Date.now}opts;cache=new Map;mint;now;async resolve(n){if(n==="")throw new F("empty Authorization bearer token");let e=this.cache.get(n);if(e&&this.now()-e.at<De)return{apiKey:n,orgId:e.orgId};let o;try{o=(await this.mint(n,{baseUrl:this.opts.gatewayUrl,expiresIn:kn})).orgId}catch(r){throw r instanceof ve.ClientTokenError&&xn(r.status)?(this.cache.delete(n),new F("the uRun org API key was rejected by the control plane \u2014 check the key and that it is not revoked")):new W(`could not verify the API key against the uRun control plane at ${this.opts.gatewayUrl}: ${r instanceof Error?r.message:String(r)}`)}if(!o)throw new W("the control plane verified the API key but returned no org_id \u2014 refusing to route a request with no tenancy (control-plane contract violation)");if(this.cache.size>=Ve){let r=this.cache.keys().next();r.done||this.cache.delete(r.value)}return this.cache.set(n,{orgId:o,at:this.now()}),{apiKey:n,orgId:o}}clear(){this.cache.clear()}};var Ot=require("crypto");var le=require("@urun-sh/core");async function gt(t){let e=await(t.fetchImpl??fetch)(`${t.catalogUrl}/model_catalog?select=model_id,variant,gpu_spec,engine,task,description,size_gb,hf_repo,engine_args,updated_at`,{headers:{apikey:t.anonKey,Authorization:`Bearer ${t.anonKey}`}});if(!e.ok)throw new Error(`model_catalog fetch failed: ${e.status}`);return await e.json()}function ht(t,n,e,o){let r=t.response??{},i={request_id:e,consumer_id:o,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 yt(t,n,e){let o={request_id:n,consumer_id:e,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),typeof t.top_p=="number"&&(o.top_p=t.top_p),Array.isArray(t.stop)&&t.stop.length>0&&(o.stop=t.stop),typeof t.reasoning_effort=="string"&&(o.reasoning_effort=t.reasoning_effort),t.chat_template_kwargs!==void 0&&(o.chat_template_kwargs=t.chat_template_kwargs),o}function wt(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 n=t,e=n.body??{};return{type:"error",error:{type:"urun_error",code:n.code??null,message:e.message??"unknown error"}}}return{type:"error",error:{type:"urun_error",code:null,message:String(t)}}}var bn="llm-resp";async function*He(t,n){let e=`${bn}:${n}`,o=`resp_${n}`;yield{type:"response.created",response:{id:o,status:"in_progress"}};let r=new Map;for await(let i of t.stream(e).messages()){let s=i;if(s.t==="delta"){if(typeof s.delta=="string"&&(yield{type:"response.output_text.delta",item_id:o,delta:s.delta}),typeof s.reasoning=="string"&&(yield{type:"response.reasoning_text.delta",item_id:o,delta:s.reasoning}),Array.isArray(s.tool_calls))for(let a of s.tool_calls){let u=typeof a.index=="number"?a.index:0,c=r.get(u)??{};a.id&&(c.id=a.id),a.function?.name&&(c.name=a.function.name),r.set(u,c),yield{type:"response.function_call_arguments.delta",item_id:`fc_${n}_${u}`,tool_index:u,call_id:c.id,name:c.name,delta:a.function?.arguments??""}}}else if(s.t==="response"){yield{type:"response.completed",response:{id:o,status:"completed",...s.body}};return}else if(s.t==="error"){yield wt(s);return}}}var Sn="llm",xe=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(Sn).set({requests:{[n.request_id]:{payload:n,consumer_id:n.consumer_id,stream:n.stream}}})}sendResponses(n,e){let o=yt(n,e,this.consumerId);return this.write(o),He(this.session,e)}sendResponseCreate(n,e,o){let r=ht(n,e,o,this.consumerId);return this.write(r),He(this.session,o)}};var _t=0;function Rn(){return _t+=1,`req_${Date.now().toString(36)}_${_t.toString(36)}`}var be=class{transport;constructor(n){this.transport=new xe(n)}responses={create:async n=>{let e=Rn(),o=this.transport.sendResponses(n,e);return Object.assign((async function*(){yield*o})(),{requestId:e})}}};function An(t){let n=t?.type;return n==="response.created"||n==="response.in_progress"}function En(t){let n=t?.type;return n==="response.completed"||n==="error"}function vt(t){return async function(e){return(async function*(){for(let r=1;r<=2;r++){let{app:i,entry:s}=await t.sessionFor(e.model),a=!1,u=!1;try{let c=await t.createStream(s,e);for await(let p of c){if(En(p)&&(a=!0),An(p)){if(r>1)continue}else u=!0;yield p}}catch(c){if(r<2&&!u){await t.evict(i,s);continue}throw c}if(a)return;if(r<2&&!u){await t.evict(i,s);continue}return}})()}}var On=3,In="llm",Tn=new Set(["paused","error"]);function kt(t,n){let e=t.doc(In),o=typeof e.onConnectionState=="function",r=typeof t.onPhase=="function";if(!o&&!r)throw new Error(`session for app "${n}" exposes neither a doc connection-state surface nor onPhase \u2014 session-gone detection requires @urun-sh/core Session (SessionDocument.onConnectionState / Session.onPhase); pooling a session with no native lifecycle signal would silently swallow requests dispatched after the platform closes it`);let i=null,s=new Set,a=[],u=c=>{if(!i){i=c;for(let p of[...s])p(c);s.clear()}};return o&&a.push(e.onConnectionState(c=>{c.consecutiveFailures<On||u(new H(`the pooled session for app "${n}" is gone: its doc backhaul failed ${c.consecutiveFailures} consecutive times (last close ${c.lastCloseCode===null?"by provider liveness reap":`code ${c.lastCloseCode}`}${c.lastCloseReason?`, reason ${JSON.stringify(c.lastCloseReason)}`:""}) \u2014 the platform closed the session (idle timeout or a serve-side crash). The entry is evicted; retry to get a fresh session.`))})),r&&a.push(t.onPhase(c=>{Tn.has(c.name)&&u(new H(`the pooled session for app "${n}" lost its compute binding (phase "${c.name}"). The entry is evicted; retry to get a fresh session. The named session itself is not over \u2014 it stays attachable by name.`))})),{gone:()=>i,onGone(c){return i?(c(i),()=>{}):(s.add(c),()=>s.delete(c))},dispose(){s.clear();for(let c of a.splice(0))c()}}}async function*Be(t,n){let e=n.gone();if(e)throw e;let o=t[Symbol.asyncIterator](),r,i=new Promise((s,a)=>{r=n.onGone(u=>a(u))});i.catch(()=>{});try{for(;;){let s=await Promise.race([o.next(),i]);if(s.done)return;yield s.value}}finally{r?.(),o.return?.(void 0)}}function xt(t,n,e){let o=t[e];if(typeof o!="function")throw new Error(`app "${n}" has no function "${e}" (set URUN_FUNCTION)`);let r=o();if(typeof r.end!="function")throw new Error(`app "${n}" function "${e}" returned a session without end()`);return r}function Cn(t,n){let{baseUrl:e,orgId:o,fnName:r,auth:i,subject:s}=t,a=f=>({session:f,responses:new be(f),gone:kt(f,n)});if(i.lane==="jwt"){let f=(0,le.App)(n,{baseUrl:e,orgId:o,jwt:i.jwt});return a(xt(f,n,r))}let{apiKey:u,gatewayUrl:c}=i,p=(0,le.App)(n,{baseUrl:e,orgId:o,getAccessToken:async()=>(await(0,le.createClientToken)(u,{baseUrl:c,expiresIn:300,allowedFunctions:[`${n}/${r}`],...s===void 0?{}:{subject:s}})).token});return a(xt(p,n,r))}function Pn(t){let n=t.session.id;if(typeof n!="string"||n.length===0)throw new Error("pooled session exposes no stable session id \u2014 the session-identity seam requires @urun-sh/core Session (session.id)");return n}var Un=new Set(["error","paused"]);function bt(t){let{auth:n,catalog:e}=t,o=null,r=s=>{let a=Cn(t,s);return a.gone.onGone(()=>{o?.evict(s,a)}),a},i=new me({defaultApp:t.defaultApp,fnName:t.fnName,openSession:r,closeSession:async s=>{s.gone.dispose(),await s.session.end()},listApps:n.lane==="api-key"?()=>ot({apiUrl:t.apiUrl,apiKey:n.apiKey}):null,listCatalog:e?()=>gt(e):null,sessionKey:Pn});return o=i,t.defaultApp!==null&&i.seed(t.defaultApp,r(t.defaultApp)),i}function St(t,n=ut){let e=new WeakMap,o=new WeakMap,r=new WeakMap;return{createResponse:vt({sessionFor:i=>t.sessionFor(i),evict:(i,s)=>t.evict(i,s),createStream:async(i,s)=>Be(await i.responses.responses.create(s),i.gone)}),listModels:()=>t.modelList(),openRouterModels:()=>t.openRouterModels(),openAudio:async i=>{let{entry:s}=await t.sessionFor(i),a=e.get(s);return a||(a=(async()=>it(s.session,await n()))(),e.set(s,a),a.catch(()=>e.delete(s))),a},openVideo:async i=>{let{entry:s}=await t.sessionFor(i),a=o.get(s);return a||(a=at(s.session),o.set(s,a)),a},openVideoOut:async i=>{let{entry:s}=await t.sessionFor(i),a=r.get(s);return a||(a=ct(s.session),r.set(s,a)),a},sessionHandle:async i=>(await t.handleFor(i)).handle,createResponseOn:async(i,s)=>{let{entry:a}=await t.sessionForHandle(i);return Be(await a.responses.responses.create(s),a.gone)},onSessionEnd:async(i,s)=>{let{entry:a}=await t.sessionForHandle(i),u=a.session;if(typeof u.onPhase!="function")throw new Error("pooled session exposes no onPhase \u2014 session-end (goAway) wiring requires @urun-sh/core Session");let c=!1;return u.onPhase(p=>{if(c||!Un.has(p.name))return;c=!0;let f=u.endsAt??null;s({timeLeftMs:f?Math.max(0,f.getTime()-Date.now()):null,reason:p.reason??`session ${p.name}`})})}}}var Nn=fe(require("os"),1),$n=fe(require("path"),1),Ln=require("url"),Mn=require("util");function Rt(t,n="URUN_BASE_URL"){if(/\/v1\/*$/.test(new URL(t).pathname))throw new Error(`${n} must be the session-gateway base (e.g. https://api.urun.sh), got ${t} \u2014 a trailing /v1 is the org control-plane API form (that belongs in URUN_API_URL); session allocation 404s against it. Drop the /v1.`);return t}function Se(t,n="URUN_GATEWAY_URL"){let e=new URL(t),o=e.hostname==="localhost"||e.hostname==="127.0.0.1"||e.hostname==="[::1]";if(e.protocol!=="https:"&&!o)throw new Error(`${n} must be https (got ${t}) \u2014 the org API key rides the request's Authorization header`);return t}var Fe=8080,Re="serve",At="0.0.0.0";function Dn(t,n,e){let o=(t[n]??"").trim();if(!o)throw new Error(`${n} is not set \u2014 ${e}`);return o}function Et(t=process.env){let n=(t.PORT??"").trim(),e=n===""?Fe:Number(n);if(!Number.isInteger(e)||e<0||e>65535)throw new Error(`PORT must be an integer in 0..65535, got ${JSON.stringify(n)}`);let o=Rt(Se(Dn(t,"URUN_BASE_URL","the hosted proxy needs the uRun session-gateway base it opens sessions and verifies API keys against (e.g. https://api.urun.sh)"),"URUN_BASE_URL")),r=(t.URUN_API_URL??"").trim(),i=r?Se(r,"URUN_API_URL"):`${o.replace(/\/+$/,"")}/v1`,s=(t.URUN_CATALOG_URL??"").trim(),a=(t.URUN_CATALOG_ANON_KEY??"").trim();if(!!s!=!!a)throw new Error("URUN_CATALOG_URL and URUN_CATALOG_ANON_KEY must be set together (or both left unset) \u2014 exactly one of them is set, which would silently disable the model-catalog oracle");let u=s?{catalogUrl:Se(s,"URUN_CATALOG_URL"),anonKey:a}:null;return{port:e,baseUrl:o,apiUrl:i,catalog:u}}var je=512;function Ge(t){return`urun-inference-proxy-${(0,Ot.createHash)("sha256").update(t).digest("hex").slice(0,32)}`}var ne=class{constructor(n){this.opts=n}opts;tenants=new Map;build(n){if(this.opts.build)return this.opts.build(n);let e=bt({baseUrl:this.opts.baseUrl,orgId:n.orgId,defaultApp:null,fnName:Re,apiUrl:this.opts.apiUrl,auth:{lane:"api-key",apiKey:n.apiKey,gatewayUrl:this.opts.baseUrl},catalog:this.opts.catalog,subject:Ge(n.apiKey)});return{router:e,clients:St(e)}}clientsFor(n){let e=this.tenants.get(n.apiKey);if(e)return this.tenants.delete(n.apiKey),this.tenants.set(n.apiKey,e),e.clients;for(;this.tenants.size>=je;){let r=this.tenants.entries().next();if(r.done)break;let[i,s]=r.value;this.tenants.delete(i),s.router.closeAll().catch(()=>{})}let o=this.build(n);return this.tenants.set(n.apiKey,o),o.clients}get size(){return this.tenants.size}async closeAll(){let n=[...this.tenants.values()].map(o=>o.router);this.tenants.clear();let e=[];if(await Promise.all(n.map(async o=>{try{await o.closeAll()}catch(r){e.push(String(r instanceof Error?r.message:r))}})),e.length>0)throw new Error(`failed to close ${e.length} tenant backhaul(s): ${e.join("; ")}`)}};var Je=5e3,We=3e3,Vn="/api/client-tokens";function qe(t,n,e){t.writeHead(n,{"content-type":"application/json"}),t.end(JSON.stringify(e))}function It(t,n,e,o){qe(t,n,{error:{message:e,type:o}})}async function Hn(t,n=fetch){let e=`${t.replace(/\/+$/,"")}${Vn}`;try{let o=await n(e,{method:"POST",headers:{"content-type":"application/json"},body:"{}",signal:AbortSignal.timeout(We)});return o.status===404?{ready:!1,detail:`${e} answered 404 \u2014 this is not a uRun control plane`}:o.status>=500?{ready:!1,detail:`${e} answered HTTP ${o.status}`}:{ready:!0,detail:`${e} answered HTTP ${o.status}`}}catch(o){return{ready:!1,detail:`${e} unreachable: ${o instanceof Error?o.message:String(o)}`}}}function Ct(t){let n=t.resolver??new te({gatewayUrl:t.baseUrl}),e=t.registry??new ne({baseUrl:t.baseUrl,apiUrl:t.apiUrl,catalog:t.catalog}),o=t.probeControlPlane??(()=>Hn(t.baseUrl)),r=async u=>n.resolve(ke(u.headers.authorization)),i=mt({clients:async u=>e.clientsFor(await r(u)),statusOf:u=>u instanceof F?{status:u.status,openaiType:"authentication_error",anthropicType:"authentication_error"}:u instanceof W?{status:502,openaiType:"upstream_error",anthropicType:"api_error"}:null}),s=null;return{server:(0,Tt.createServer)((u,c)=>{let p=new URL(u.url??"/","http://localhost");(async()=>{if(u.method==="GET"&&p.pathname==="/healthz"){qe(c,200,{ok:!0});return}if(u.method==="GET"&&p.pathname==="/readyz"){let f=Date.now();if(!s||f-s.at>=Je){let m=await o();s={at:f,...m}}qe(c,s.ready?200:503,{ok:s.ready,control_plane:s.detail});return}if(p.pathname!=="/v1"&&!p.pathname.startsWith("/v1/")){It(c,404,`no route for ${u.method} ${p.pathname} \u2014 this endpoint serves the OpenAI-compatible /v1 surface plus /healthz and /readyz`,"invalid_request_error");return}i(u,c)})().catch(f=>{if(!c.headersSent){It(c,500,String(f instanceof Error?f.message:f),"proxy_error");return}c.end()})}),closeAll:()=>e.closeAll()}}0&&(module.exports={BIND_HOST,ControlPlaneUnavailableError,DEFAULT_PORT,MAX_CACHED_KEYS,MAX_TENANTS,ORG_BINDING_TTL_MS,OrgResolver,ProxyAuthError,READINESS_TIMEOUT_MS,READINESS_TTL_MS,SERVE_FUNCTION,TenantRegistry,bearerFrom,createHostedProxy,resolveHostedConfig,tenantSubject});
@@ -2,9 +2,53 @@ import { Server } from 'node:http';
2
2
  import { createClientToken } from '@urun-sh/core';
3
3
  import { U as UrunResponses } from '../ResponsesClient-Dft3bg3b.cjs';
4
4
  import { b as UrunSessionLike } from '../types-lsVTbNcH.cjs';
5
- import { P as ProxyClients } from '../server-BfME37pQ.cjs';
5
+ import { C as CatalogRow } from '../models-NYMZrklp.cjs';
6
+ import { P as ProxyClients } from '../server-wmUnMewW.cjs';
6
7
  import '../video-out-D20UuJ8G.cjs';
7
8
 
9
+ /**
10
+ * THE OPENROUTER PROVIDER DOCUMENT — `GET /v1/models?format=openrouter`.
11
+ *
12
+ * OpenRouter's provider monitor polls this document (schema 2.4, per
13
+ * openrouter.ai/docs/guides/community/for-providers) to list a provider's
14
+ * models on the marketplace. The `id` field is the EXACT model identifier
15
+ * OpenRouter sends back as `model` on chat completions — which here is the
16
+ * app slug, the same id the OpenAI surface lists. One id space, two views.
17
+ *
18
+ * MODALITY GATING: only rows whose catalog `task` names a chat-completions
19
+ * shape (chat | code | agent | vl) are declared. A voice/video/image app
20
+ * behind a chat surface would stream garbage into OpenRouter's baseline
21
+ * tests; models the catalog cannot vouch for are OMITTED, never guessed.
22
+ * With no catalog oracle configured the document is `{"data": []}` — honest
23
+ * emptiness, not invented capability (the chart turns the oracle on).
24
+ *
25
+ * PRICING is deliberately omitted entirely: the schema's rule is "a modality
26
+ * with no pricing array is simply unpriced", OpenRouter configures pricing
27
+ * during provider onboarding, and the per-model price surface is
28
+ * urun-infra U3 (model_prices) — when that lands, this module grows a
29
+ * `prices` input and emits the input/output pricing arrays.
30
+ *
31
+ * The full closed-value-domain schema ships as OpenAPI 3.1 at
32
+ * openrouter.ai/docs/assets/provider-monitor-schema-v2.openapi.json.
33
+ */
34
+
35
+ type OpenRouterProviderDoc = {
36
+ data: OpenRouterProviderModel[];
37
+ };
38
+ interface OpenRouterProviderModel {
39
+ schema_version: '2.4';
40
+ /** The EXACT id OpenRouter sends back as `model` — the app slug. */
41
+ id: string;
42
+ name: string;
43
+ created: number;
44
+ /** Valid enum: int4|int8|fp4|mxfp4|nvfp4|fp6|fp8|mxfp8|fp16|bf16|fp32|null. */
45
+ quantization: string | null;
46
+ description: string;
47
+ hugging_face_id: string;
48
+ input_modalities: Array<Record<string, unknown>>;
49
+ output_modalities: Array<Record<string, unknown>>;
50
+ }
51
+
8
52
  /**
9
53
  * Per-model → per-app routing for the compat proxy (owner directive
10
54
  * 2026-08-07): swapping the model in a coding harness routes the request to
@@ -51,6 +95,7 @@ import '../video-out-D20UuJ8G.cjs';
51
95
  * model, here is the list. Rules 2–5 are byte-for-byte the local behavior —
52
96
  * one router, one resolution order, two configurations.
53
97
  */
98
+
54
99
  /** One org app row from `GET {orgApi}/apps` (urun-cli `ApiClient.list_apps`). */
55
100
  interface DeployedApp {
56
101
  app_slug: string;
@@ -66,15 +111,34 @@ interface DeployedApp {
66
111
  */
67
112
  declare class SessionGoneError extends Error {
68
113
  }
69
- /** OpenAI-shaped model list (same shape as models.ts listModels). */
114
+ /**
115
+ * OpenAI-shaped model list (same shape as models.ts listModels). When the
116
+ * catalog oracle is configured, each entry ALSO carries the catalog
117
+ * enrichment fields (additive JSON — OpenAI clients ignore unknown fields;
118
+ * the OpenRouter + Vercel AI Gateway provider listings need them). Entries
119
+ * whose slug matches no catalog row stay at the bare four fields.
120
+ */
121
+ interface RouterModelEntry {
122
+ id: string;
123
+ object: 'model';
124
+ created: number;
125
+ owned_by: string;
126
+ /** Display name — the canonical `<model_id>:<variant>` catalog ref. */
127
+ name?: string;
128
+ /** User-facing description from the catalog (console Endpoints copy). */
129
+ description?: string;
130
+ /** Catalog modality (chat | code | agent | vl | audio | image | ...). */
131
+ task?: string;
132
+ /** Serving engine (vllm | sglang | llamacpp | ...). */
133
+ engine?: string;
134
+ /** The catalog lane this app deploys, e.g. 'rtx6000:1'. */
135
+ gpu_spec?: string;
136
+ /** Context window in tokens (chat rows carry it in engine_args). */
137
+ context_length?: number;
138
+ }
70
139
  interface RouterModelList {
71
140
  object: 'list';
72
- data: Array<{
73
- id: string;
74
- object: 'model';
75
- created: number;
76
- owned_by: string;
77
- }>;
141
+ data: RouterModelEntry[];
78
142
  }
79
143
  interface ModelRouterOptions<S> {
80
144
  /**
@@ -100,12 +164,11 @@ interface ModelRouterOptions<S> {
100
164
  listApps: (() => Promise<DeployedApp[]>) | null;
101
165
  /**
102
166
  * Catalog rows (models.ts fetchCatalogRows) as the uRun-namespace oracle
103
- * for rule 5, or null when catalog access is not configured.
167
+ * for rule 5 AND the /v1/models enrichment + OpenRouter provider-doc
168
+ * source, or null when catalog access is not configured. Optional fields
169
+ * beyond model_id/variant are tolerated (thin rows still typecheck).
104
170
  */
105
- listCatalog: (() => Promise<Array<{
106
- model_id: string;
107
- variant: string;
108
- }>>) | null;
171
+ listCatalog: (() => Promise<CatalogRow[]>) | null;
109
172
  /** Deployed-apps cache TTL (the list changes on deploys, not per request). */
110
173
  appsTtlMs?: number;
111
174
  /**
@@ -128,10 +191,17 @@ declare class ModelRouter<S> {
128
191
  private readonly opts;
129
192
  private readonly pool;
130
193
  private appsCache;
194
+ private rowsCache;
131
195
  constructor(opts: ModelRouterOptions<S>);
132
196
  /** Seed an already-open session (the CLI's eagerly-opened startup app). */
133
197
  seed(appSlug: string, entry: S): void;
134
198
  private deployedApps;
199
+ /**
200
+ * Catalog rows with the same TTL discipline as {@link deployedApps} (the
201
+ * catalog changes on reseed migrations, not per request). Null when no
202
+ * oracle is configured — callers degrade to the bare four-field entries.
203
+ */
204
+ private catalogRows;
135
205
  /** Apps this proxy may serve: active AND exposing the serve function. */
136
206
  private servable;
137
207
  private availableIds;
@@ -194,6 +264,17 @@ declare class ModelRouter<S> {
194
264
  * the PR, not papered over here.
195
265
  */
196
266
  modelList(): Promise<RouterModelList>;
267
+ /**
268
+ * The OpenRouter PROVIDER document (`GET /v1/models?format=openrouter`):
269
+ * schema 2.4 per openrouter.ai/docs/guides/community/for-providers. Only
270
+ * chat-completions-shaped models are declared (task chat | code | agent |
271
+ * vl — a voice or video app behind a chat surface would stream garbage);
272
+ * models the catalog cannot vouch for are OMITTED, never guessed. Pricing
273
+ * is deliberately omitted entirely (schema rule: "A modality with no
274
+ * pricing array is simply unpriced" — OpenRouter configures pricing during
275
+ * provider onboarding; the per-model price surface is urun-infra U3).
276
+ */
277
+ openRouterModels(): Promise<OpenRouterProviderDoc>;
197
278
  /** Close every pooled session (Session.end() underneath) — proxy shutdown. */
198
279
  closeAll(): Promise<void>;
199
280
  }
@@ -2,9 +2,27 @@ import { Server } from 'node:http';
2
2
  import { createClientToken } from '@urun-sh/core';
3
3
  import { U as UrunResponses } from '../ResponsesClient-BYx3YLGo.js';
4
4
  import { b as UrunSessionLike } from '../types-lsVTbNcH.js';
5
- import { P as ProxyClients } from '../server-l1himPxc.js';
5
+ import { C as CatalogRow } from '../models-NYMZrklp.js';
6
+ import { P as ProxyClients } from '../server-DuH_5OD9.js';
6
7
  import '../video-out-CWesbk12.js';
7
8
 
9
+ type OpenRouterProviderDoc = {
10
+ data: OpenRouterProviderModel[];
11
+ };
12
+ interface OpenRouterProviderModel {
13
+ schema_version: '2.4';
14
+
15
+ id: string;
16
+ name: string;
17
+ created: number;
18
+
19
+ quantization: string | null;
20
+ description: string;
21
+ hugging_face_id: string;
22
+ input_modalities: Array<Record<string, unknown>>;
23
+ output_modalities: Array<Record<string, unknown>>;
24
+ }
25
+
8
26
  interface DeployedApp {
9
27
  app_slug: string;
10
28
  function_name?: string | null;
@@ -15,14 +33,27 @@ interface DeployedApp {
15
33
  declare class SessionGoneError extends Error {
16
34
  }
17
35
 
36
+ interface RouterModelEntry {
37
+ id: string;
38
+ object: 'model';
39
+ created: number;
40
+ owned_by: string;
41
+
42
+ name?: string;
43
+
44
+ description?: string;
45
+
46
+ task?: string;
47
+
48
+ engine?: string;
49
+
50
+ gpu_spec?: string;
51
+
52
+ context_length?: number;
53
+ }
18
54
  interface RouterModelList {
19
55
  object: 'list';
20
- data: Array<{
21
- id: string;
22
- object: 'model';
23
- created: number;
24
- owned_by: string;
25
- }>;
56
+ data: RouterModelEntry[];
26
57
  }
27
58
  interface ModelRouterOptions<S> {
28
59
 
@@ -36,10 +67,7 @@ interface ModelRouterOptions<S> {
36
67
 
37
68
  listApps: (() => Promise<DeployedApp[]>) | null;
38
69
 
39
- listCatalog: (() => Promise<Array<{
40
- model_id: string;
41
- variant: string;
42
- }>>) | null;
70
+ listCatalog: (() => Promise<CatalogRow[]>) | null;
43
71
 
44
72
  appsTtlMs?: number;
45
73
 
@@ -50,11 +78,14 @@ declare class ModelRouter<S> {
50
78
  private readonly opts;
51
79
  private readonly pool;
52
80
  private appsCache;
81
+ private rowsCache;
53
82
  constructor(opts: ModelRouterOptions<S>);
54
83
 
55
84
  seed(appSlug: string, entry: S): void;
56
85
  private deployedApps;
57
86
 
87
+ private catalogRows;
88
+
58
89
  private servable;
59
90
  private availableIds;
60
91
 
@@ -82,6 +113,8 @@ declare class ModelRouter<S> {
82
113
 
83
114
  modelList(): Promise<RouterModelList>;
84
115
 
116
+ openRouterModels(): Promise<OpenRouterProviderDoc>;
117
+
85
118
  closeAll(): Promise<void>;
86
119
  }
87
120
 
@@ -1 +1 @@
1
- import{a as e,b as o,c as t,d as n,e as p,f as s,g as T,h as E,i as _,j as a,k as S,l as f,m as x,n as i,o as y,p as O}from"../chunk-FVD4NMXJ.js";import"../chunk-ODHCPZHI.js";import"../chunk-F2TEK34X.js";import"../chunk-M6ICU4F5.js";import"../chunk-G3NMGP4N.js";import"../chunk-XHIIEA6Z.js";import"../chunk-5NXM4IO3.js";import"../chunk-CWJRDBDC.js";import"../chunk-UVAY7Q7Z.js";import{c as r}from"../chunk-YSFSRI3D.js";r();export{_ as BIND_HOST,o as ControlPlaneUnavailableError,T as DEFAULT_PORT,p as MAX_CACHED_KEYS,S as MAX_TENANTS,n as ORG_BINDING_TTL_MS,s as OrgResolver,e as ProxyAuthError,y as READINESS_TIMEOUT_MS,i as READINESS_TTL_MS,E as SERVE_FUNCTION,x as TenantRegistry,t as bearerFrom,O as createHostedProxy,a as resolveHostedConfig,f as tenantSubject};
1
+ import{a as e,b as o,c as t,d as n,e as p,f as s,g as T,h as E,i as _,j as a,k as S,l as f,m as x,n as i,o as y,p as O}from"../chunk-STFRT5OY.js";import"../chunk-RQBD4OAA.js";import"../chunk-K23AZPI4.js";import"../chunk-VNM4M4P3.js";import"../chunk-GBBY3PCZ.js";import"../chunk-4MSBS7M6.js";import"../chunk-5NXM4IO3.js";import"../chunk-CWJRDBDC.js";import"../chunk-OI2OY32M.js";import{c as r}from"../chunk-YSFSRI3D.js";r();export{_ as BIND_HOST,o as ControlPlaneUnavailableError,T as DEFAULT_PORT,p as MAX_CACHED_KEYS,S as MAX_TENANTS,n as ORG_BINDING_TTL_MS,s as OrgResolver,e as ProxyAuthError,y as READINESS_TIMEOUT_MS,i as READINESS_TTL_MS,E as SERVE_FUNCTION,x as TenantRegistry,t as bearerFrom,O as createHostedProxy,a as resolveHostedConfig,f as tenantSubject};