@urun-sh/openai 0.6.20 → 0.6.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,8 @@
1
1
  import { Server } from 'node:http';
2
2
  import * as _prometheus_io_client from '@prometheus-io/client';
3
3
  import { Registry } from '@prometheus-io/client';
4
- import { c as LedgerOutcome, I as InferenceRecord, S as SessionGoneError, P as ProxyClients, M as ModelRouter, i as UsageRowReporter, b as InferenceUsageRecord, e as LedgerWrite, d as LedgerRecorded, L as LedgerFailure } from '../responses-turn-Cb1qQBA7.cjs';
5
- import { createClientToken } from '@urun-sh/core';
4
+ import { c as LedgerOutcome, I as InferenceRecord, S as SessionGoneError, j as billingIdentityOf, P as ProxyClients, M as ModelRouter, i as UsageRowReporter, b as InferenceUsageRecord, e as LedgerWrite, d as LedgerRecorded, L as LedgerFailure } from '../responses-turn-C0PBaF29.cjs';
5
+ import { createClientToken, SessionPhaseName } from '@urun-sh/core';
6
6
  import { U as UrunResponses } from '../ResponsesClient-_OZERUjH.cjs';
7
7
  import { b as UrunSessionLike } from '../types-CHPtJx6d.cjs';
8
8
  import '../models-DUdx_Y6X.cjs';
@@ -235,6 +235,20 @@ declare class OrgResolver {
235
235
  clear(): void;
236
236
  }
237
237
 
238
+ /** Live gauges for the proxy's /metrics surface. */
239
+ interface DecisionPoolStats {
240
+ /** Slots that exist (any state) — submitted session requests. */
241
+ requested: number;
242
+ attached: number;
243
+ /** Slots submitted whose session has not attached (or re-attached) yet. */
244
+ queued: number;
245
+ paused: number;
246
+ /** Decisions currently riding the pool. */
247
+ inFlight: number;
248
+ /** GOAWAY sent: admissions closed, in-flight finishing, slots ending. */
249
+ draining: boolean;
250
+ }
251
+
238
252
  /**
239
253
  * SESSION GONE for the proxy serve lane — level-triggered, keyed off the
240
254
  * transport's OWN close/rejection signals (live defect, prod-usw2 2026-08-12).
@@ -368,6 +382,21 @@ type OwnedSession = UrunSessionLike & {
368
382
  timeout?: number;
369
383
  signal?: AbortSignal;
370
384
  }) => Promise<void>;
385
+ /**
386
+ * The session's current phase snapshot (core `Session.phase`): the server's
387
+ * wake hint (`phase.runtime.wake.expectedWakePath`) rides it and picks the
388
+ * explicit `whenLive` bound ({@link whenLiveTimeoutOf}). Optional — a
389
+ * session double without it reads as not waking (the fast 45s fence,
390
+ * unchanged from the pre-fix behavior).
391
+ */
392
+ phase?: {
393
+ name?: SessionPhaseName;
394
+ runtime?: {
395
+ wake?: {
396
+ expectedWakePath?: string;
397
+ };
398
+ };
399
+ };
371
400
  /**
372
401
  * Core's NATIVE admission-ticket cancel (`Session.cancel`): hands back the
373
402
  * claim a still-QUEUED call waits on — once the call HAS a session, the
@@ -387,6 +416,53 @@ type PoolEntry = {
387
416
  responses: UrunResponses;
388
417
  gone: SessionGoneWatch;
389
418
  };
419
+ /**
420
+ * The replica's DECISION POOL wiring (serving-plan.md Phase 2) — built from
421
+ * the SAME BackhaulConfig the router uses, so slot sessions open through the
422
+ * ONE `openSessionFor` path with a per-slot `concurrency_key` (STABLE per
423
+ * slot: a replica restart re-adopts its own slot sessions instead of minting
424
+ * garbage, and N slots are N genuinely concurrent sessions — no singleton 403
425
+ * `session_name_not_yours`). The pool's ATTACHED sessions ARE readiness: the
426
+ * decision lane never consults presence or capacity to pick one.
427
+ */
428
+ interface DecisionPools {
429
+ /** Submit `min` session requests for the default target (called at boot). */
430
+ boot(): Promise<void>;
431
+ /** The rehome seam's sessionFor: least-loaded attached slot lease.
432
+ *
433
+ * THE NO-WAIT CONTRACT (owner ruling 2026-10-03): never awaits a slot
434
+ * open — throws {@link DecisionCapacityError} when no attached slot is
435
+ * ready, after submitting the out-of-band add. */
436
+ sessionFor(model: string | undefined): Promise<{
437
+ app: string;
438
+ entry: PoolEntry;
439
+ identity: ReturnType<typeof billingIdentityOf>;
440
+ }>;
441
+ /** The out-of-band warm: submit `min` slot opens for `model`'s target,
442
+ * never on a request's critical path and never awaited by a request. */
443
+ warmFor(model: string): Promise<void>;
444
+ /** THE READINESS PING: a real round trip against one attached slot
445
+ * (core `Session.whenLive`, short deadline) — false when none answers. */
446
+ pingReady(timeoutMs: number): Promise<boolean>;
447
+ /** Release the lease a decision stream rode (stream end — success or not). */
448
+ end(entry: PoolEntry): void;
449
+ /** A pool entry's runtime detached: PAUSED + re-submit (re-adopt). */
450
+ evict(entry: PoolEntry): void;
451
+ /** Idle scale-down, above min. Owner-driven cadence (the 5s reap tick). */
452
+ reap(): void;
453
+ stats(): Array<{
454
+ poolKey: string;
455
+ } & DecisionPoolStats>;
456
+ /**
457
+ * THE GOAWAY DRAIN (spec docs/design/session-stream-semantics.md §3):
458
+ * rollout/SIGTERM path — stop admitting (typed 503 `draining`), let
459
+ * in-flight decisions finish (bounded by `timeoutMs`), then explicitly end
460
+ * every slot's session. Call BEFORE `server.close()` so no resident is
461
+ * killed mid-stream and no caller sees a bare 429/000.
462
+ */
463
+ drain(timeoutMs?: number): Promise<void>;
464
+ close(): Promise<void>;
465
+ }
390
466
 
391
467
  /**
392
468
  * PER-CALLER BACKHAULS — the multi-tenant half of the hosted endpoint.
@@ -459,10 +535,12 @@ interface TenantRegistryOptions {
459
535
  apiUrl: string;
460
536
  /** The model-catalog oracle for routing rule 5, or null. */
461
537
  catalog: CatalogConfig | null;
462
- /** Injected in tests; production builds real uRun backhauls. */
538
+ /** Injected in tests; production builds real uRun backhauls. A stub may
539
+ * also carry its own `decision` pool (tests drive the readiness ping). */
463
540
  build?: (caller: CallerIdentity) => {
464
541
  router: ModelRouter<PoolEntry>;
465
542
  clients: ProxyClients;
543
+ decision?: DecisionPools;
466
544
  };
467
545
  }
468
546
  /**
@@ -496,10 +574,34 @@ declare class TenantRegistry {
496
574
  */
497
575
  private label;
498
576
  private build;
577
+ /**
578
+ * THE POOL'S OWNER-DRIVEN IDLE SCALE-DOWN. The pool owns no timers
579
+ * (decision-pool.ts) — someone must call `reap()` on a cadence. One
580
+ * unref'd interval per registry, started only when a tenant actually built
581
+ * a decision pool, reaps every live tenant's pool on the same 5s cadence
582
+ * the local CLI proxy uses.
583
+ */
584
+ private ensureDecisionReaper;
585
+ private decisionReaper;
499
586
  /** The backhaul for THIS caller, opened on first use and reused after. */
500
587
  clientsFor(caller: CallerIdentity): ProxyClients;
501
588
  /** Live tenant count — the readiness/ops view, and the tests' assertion. */
502
589
  get size(): number;
590
+ /**
591
+ * THE READINESS SEAM: the live decision pools this replica could serve a
592
+ * decision from, for the hosted `/readyz` composition (a REAL session ping
593
+ * against one attached slot — owner ruling 2026-10-03). Empty when no
594
+ * tenant has built a pool (the honest "nothing to ping yet").
595
+ */
596
+ decisionPools(): IterableIterator<DecisionPools>;
597
+ /**
598
+ * THE OUT-OF-BAND WARM SEAM (owner ruling 2026-10-03: adding is never on
599
+ * the request path). Builds the tenant for `caller` (the SHARED org
600
+ * credential at boot) and returns its decision pool, whose `warmFor(model)`
601
+ * submits the slot opens WITHOUT any request waiting on them. Null when
602
+ * the caller built no pool (env gate off).
603
+ */
604
+ decisionWarmerFor(caller: CallerIdentity): DecisionPools | null;
503
605
  /** Shutdown: end every pooled session through `Session.end()`. */
504
606
  closeAll(): Promise<void>;
505
607
  }
@@ -1,8 +1,8 @@
1
1
  import { Server } from 'node:http';
2
2
  import * as _prometheus_io_client from '@prometheus-io/client';
3
3
  import { Registry } from '@prometheus-io/client';
4
- import { c as LedgerOutcome, I as InferenceRecord, S as SessionGoneError, P as ProxyClients, M as ModelRouter, i as UsageRowReporter, b as InferenceUsageRecord, e as LedgerWrite, d as LedgerRecorded, L as LedgerFailure } from '../responses-turn-DmzWIpmO.js';
5
- import { createClientToken } from '@urun-sh/core';
4
+ import { c as LedgerOutcome, I as InferenceRecord, S as SessionGoneError, j as billingIdentityOf, P as ProxyClients, M as ModelRouter, i as UsageRowReporter, b as InferenceUsageRecord, e as LedgerWrite, d as LedgerRecorded, L as LedgerFailure } from '../responses-turn-2UJImii3.js';
5
+ import { createClientToken, SessionPhaseName } from '@urun-sh/core';
6
6
  import { U as UrunResponses } from '../ResponsesClient-CSSrOYD8.js';
7
7
  import { b as UrunSessionLike } from '../types-CHPtJx6d.js';
8
8
  import '../models-DUdx_Y6X.js';
@@ -105,6 +105,19 @@ declare class OrgResolver {
105
105
  clear(): void;
106
106
  }
107
107
 
108
+ interface DecisionPoolStats {
109
+
110
+ requested: number;
111
+ attached: number;
112
+
113
+ queued: number;
114
+ paused: number;
115
+
116
+ inFlight: number;
117
+
118
+ draining: boolean;
119
+ }
120
+
108
121
  interface SessionGoneWatch {
109
122
 
110
123
  gone(): SessionGoneError | null;
@@ -134,6 +147,15 @@ type OwnedSession = UrunSessionLike & {
134
147
  signal?: AbortSignal;
135
148
  }) => Promise<void>;
136
149
 
150
+ phase?: {
151
+ name?: SessionPhaseName;
152
+ runtime?: {
153
+ wake?: {
154
+ expectedWakePath?: string;
155
+ };
156
+ };
157
+ };
158
+
137
159
  cancel?: () => Promise<unknown>;
138
160
  };
139
161
 
@@ -143,6 +165,33 @@ type PoolEntry = {
143
165
  gone: SessionGoneWatch;
144
166
  };
145
167
 
168
+ interface DecisionPools {
169
+
170
+ boot(): Promise<void>;
171
+
172
+ sessionFor(model: string | undefined): Promise<{
173
+ app: string;
174
+ entry: PoolEntry;
175
+ identity: ReturnType<typeof billingIdentityOf>;
176
+ }>;
177
+
178
+ warmFor(model: string): Promise<void>;
179
+
180
+ pingReady(timeoutMs: number): Promise<boolean>;
181
+
182
+ end(entry: PoolEntry): void;
183
+
184
+ evict(entry: PoolEntry): void;
185
+
186
+ reap(): void;
187
+ stats(): Array<{
188
+ poolKey: string;
189
+ } & DecisionPoolStats>;
190
+
191
+ drain(timeoutMs?: number): Promise<void>;
192
+ close(): Promise<void>;
193
+ }
194
+
146
195
  declare const MAX_TENANTS = 512;
147
196
  interface TenantRegistryOptions {
148
197
 
@@ -155,6 +204,7 @@ interface TenantRegistryOptions {
155
204
  build?: (caller: CallerIdentity) => {
156
205
  router: ModelRouter<PoolEntry>;
157
206
  clients: ProxyClients;
207
+ decision?: DecisionPools;
158
208
  };
159
209
  }
160
210
 
@@ -168,10 +218,17 @@ declare class TenantRegistry {
168
218
  private label;
169
219
  private build;
170
220
 
221
+ private ensureDecisionReaper;
222
+ private decisionReaper;
223
+
171
224
  clientsFor(caller: CallerIdentity): ProxyClients;
172
225
 
173
226
  get size(): number;
174
227
 
228
+ decisionPools(): IterableIterator<DecisionPools>;
229
+
230
+ decisionWarmerFor(caller: CallerIdentity): DecisionPools | null;
231
+
175
232
  closeAll(): Promise<void>;
176
233
  }
177
234
 
@@ -1 +1 @@
1
- import{A as x,B as v,C as m,D as y,E as B,F as H,G as P,H as u,I as G,J as U,K as F,L as X,M as Y,N as b,O as h,P as k,Q as K,R as V,S as j,T as W,U as q,a as r,b as o,c as t,d as E,e as n,f as _,g as a,h as T,i as O,j as i,k as s,l as I,m as p,n as A,o as R,p as S,q as N,r as C,s as D,t as L,u as M,v as d,w as f,x as l,y as c,z as g}from"../chunk-64WZRHYB.js";import"../chunk-7ZH2UHK6.js";import"../chunk-K23AZPI4.js";import"../chunk-TF2IMK3T.js";import"../chunk-76BZLCGT.js";import"../chunk-BAKPG5S3.js";import"../chunk-3JWYIKHM.js";import"../chunk-6M5JK4YC.js";import"../chunk-7V2JKPIG.js";import{c as e}from"../chunk-YSFSRI3D.js";e();export{N as ANONYMOUS_KEY_ID,y as BIND_HOST,R as BUCKET_DOMAIN,O as BoundedLabel,f as ControlPlaneUnavailableError,X as ConversationBackhauls,F as ConversationCapacityError,v as DEFAULT_PORT,I as EDGE_IDENTITY_PORT,A as EDGE_KEY_FINGERPRINT_HEADER,p as EDGE_KEY_ID_HEADER,i as InferenceMetrics,Y as LEDGER_FUNCTION_PATH,b as LEDGER_WRITE_TIMEOUT_MS,V as LedgerClient,h as LedgerDuplicateError,k as LedgerSurfaceError,g as MAX_CACHED_KEYS,G as MAX_CONVERSATIONS,U as MAX_CONVERSATION_HANDLES,n as MAX_MODEL_LABELS,_ as MAX_ORG_LABELS,H as MAX_TENANTS,o as METRICS_PATH,r as METRICS_PORT,E as NO_MODEL_LABEL,c as ORG_BINDING_TTL_MS,t as OTHER_LABEL,x as OrgResolver,d as ProxyAuthError,W as READINESS_TIMEOUT_MS,j as READINESS_TTL_MS,m as SERVE_FUNCTION,S as TIER_DOMAIN,u as TenantRegistry,l as bearerFrom,L as bearerTokenOf,M as createEdgeIdentityServer,q as createHostedProxy,s as createMetricsServer,C as edgeBucketId,D as edgeTierFingerprint,a as laneOf,K as parseLedgerRecorded,B as resolveHostedConfig,T as statusClassOf,P as tenantSubject};
1
+ import{A as x,B as v,C as m,D as y,E as B,F as H,G as P,H as u,I as G,J as U,K as F,L as X,M as Y,N as b,O as h,P as k,Q as K,R as V,S as j,T as W,U as q,a as r,b as o,c as t,d as E,e as n,f as _,g as a,h as T,i as O,j as i,k as s,l as I,m as p,n as A,o as R,p as S,q as N,r as C,s as D,t as L,u as M,v as d,w as f,x as l,y as c,z as g}from"../chunk-HCAKF2SQ.js";import"../chunk-KSC5Q6PZ.js";import"../chunk-K23AZPI4.js";import"../chunk-4W3ZPIR7.js";import"../chunk-76BZLCGT.js";import"../chunk-CUDFHFNX.js";import"../chunk-3JWYIKHM.js";import"../chunk-6M5JK4YC.js";import"../chunk-7V2JKPIG.js";import{c as e}from"../chunk-YSFSRI3D.js";e();export{N as ANONYMOUS_KEY_ID,y as BIND_HOST,R as BUCKET_DOMAIN,O as BoundedLabel,f as ControlPlaneUnavailableError,X as ConversationBackhauls,F as ConversationCapacityError,v as DEFAULT_PORT,I as EDGE_IDENTITY_PORT,A as EDGE_KEY_FINGERPRINT_HEADER,p as EDGE_KEY_ID_HEADER,i as InferenceMetrics,Y as LEDGER_FUNCTION_PATH,b as LEDGER_WRITE_TIMEOUT_MS,V as LedgerClient,h as LedgerDuplicateError,k as LedgerSurfaceError,g as MAX_CACHED_KEYS,G as MAX_CONVERSATIONS,U as MAX_CONVERSATION_HANDLES,n as MAX_MODEL_LABELS,_ as MAX_ORG_LABELS,H as MAX_TENANTS,o as METRICS_PATH,r as METRICS_PORT,E as NO_MODEL_LABEL,c as ORG_BINDING_TTL_MS,t as OTHER_LABEL,x as OrgResolver,d as ProxyAuthError,W as READINESS_TIMEOUT_MS,j as READINESS_TTL_MS,m as SERVE_FUNCTION,S as TIER_DOMAIN,u as TenantRegistry,l as bearerFrom,L as bearerTokenOf,M as createEdgeIdentityServer,q as createHostedProxy,s as createMetricsServer,C as edgeBucketId,D as edgeTierFingerprint,a as laneOf,K as parseLedgerRecorded,B as resolveHostedConfig,T as statusClassOf,P as tenantSubject};
@@ -1,4 +1,4 @@
1
- import{a as z}from"../chunk-76BZLCGT.js";import{e as W,h as Q}from"../chunk-BAKPG5S3.js";import"../chunk-7V2JKPIG.js";import{c as C}from"../chunk-YSFSRI3D.js";C();import{createAssistantMessageEventStream as he}from"@earendil-works/pi-ai";import{mkdirSync as we,openSync as _e,writeSync as ke}from"fs";import{dirname as ve}from"path";C();import{appendFileSync as de,mkdirSync as pe}from"fs";import fe from"os";import{dirname as ge,join as me}from"path";import{format as ye}from"util";function J(t=fe.homedir()){return me(t,".urun","logs","pi-extension.log")}var V=!1;function te(t,e){let n=J();try{pe(ge(n),{recursive:!0}),de(n,`${new Date().toISOString()} [console.${t}] [urun] ${ye(...e)}
1
+ import{a as z}from"../chunk-76BZLCGT.js";import{e as W,h as Q}from"../chunk-CUDFHFNX.js";import"../chunk-7V2JKPIG.js";import{c as C}from"../chunk-YSFSRI3D.js";C();import{createAssistantMessageEventStream as he}from"@earendil-works/pi-ai";import{mkdirSync as we,openSync as _e,writeSync as ke}from"fs";import{dirname as ve}from"path";C();import{appendFileSync as de,mkdirSync as pe}from"fs";import fe from"os";import{dirname as ge,join as me}from"path";import{format as ye}from"util";function J(t=fe.homedir()){return me(t,".urun","logs","pi-extension.log")}var V=!1;function te(t,e){let n=J();try{pe(ge(n),{recursive:!0}),de(n,`${new Date().toISOString()} [console.${t}] [urun] ${ye(...e)}
2
2
  `)}catch(o){if(!V){V=!0;try{process.stderr.write(`[urun] pi-extension quiet console: cannot write ${n} (${String(o)}); further urun-side console output will be dropped
3
3
  `)}catch{}}}}var f=t=>(...e)=>te(t,e),j={log:f("log"),info:f("info"),warn:f("warn"),error:f("error"),debug:f("debug"),trace:f("trace"),dir:f("dir"),table:f("table"),group:f("group"),groupCollapsed:f("groupCollapsed"),groupEnd:f("groupEnd"),count:f("count"),countReset:f("countReset"),time:f("time"),timeLog:f("timeLog"),timeEnd:f("timeEnd"),assert:(t,...e)=>{t||te("assert",e.length>0?e:["Assertion failed"])}};function q(t){try{process.stderr.write(t)}catch{}}C();async function ne(t){let e=await Q(t),n=e.filter(o=>o.function_name===t.fnName&&o.deployment_status==="active").map(o=>o.app_slug);if(n.length===0)throw new Error(`urun pi extension: the org has no active deployed app exposing "${t.fnName}" (GET ${t.apiUrl}/apps returned ${e.length} app(s), none servable) \u2014 deploy one with \`urun serve <model>\` first`);return n.sort()}var ae="urun-serve",xe="serve",Re=131072,be=16384,oe=3,Te=42e4,Ee=6e4,re=2,Se=15e3;function Ae(t){let e=(t.URUN_API_KEY??"").trim();if(!e)throw new Error("urun pi extension: URUN_API_KEY is required \u2014 model discovery lists the org's deployed serve apps via the org API (URUN_JWT alone cannot list apps)");return{apiKey:e,apiUrl:(t.URUN_API_URL??"").trim()||W,fnName:(t.URUN_FUNCTION??"").trim()||xe}}function Ue(t){let e=(t.URUN_BASE_URL??"").trim(),n=(t.URUN_ORG_ID??"").trim();if(!e)throw new Error("urun pi extension: URUN_BASE_URL is required to open a session");if(/\/v1\/*$/.test(new URL(e).pathname))throw new Error(`urun pi extension: URUN_BASE_URL must be the session-gateway base (e.g. https://api.urun.sh), got ${e} \u2014 a trailing /v1 is the org API form (URUN_API_URL); session allocation 404s against it. Drop the /v1.`);if(!n)throw new Error("urun pi extension: URUN_ORG_ID is required to open a session");let o=(t.URUN_JWT??"").trim();if(o)return{baseUrl:e,orgId:n,auth:{lane:"jwt",jwt:o}};let s=(t.URUN_API_KEY??"").trim();if(!s)throw new Error("urun pi extension: URUN_JWT or URUN_API_KEY is required to open a session");let l=(t.URUN_GATEWAY_URL??"").trim()||void 0;return{baseUrl:e,orgId:n,auth:{lane:"api-key",apiKey:s,gatewayUrl:l}}}function Ie(t){let e=null;return n=>{e===null&&(we(ve(t),{recursive:!0}),e=_e(t,"a"));let o=n.detail?` ${JSON.stringify(n.detail)}`:"";ke(e,`${new Date().toISOString()} [${n.level}] [urun] ${n.message}${o}
4
4
  `)}}function Pe(t){let e=Ie(J());return async(n,o,s)=>{let{baseUrl:l,orgId:i,auth:p}=Ue(n),{App:k,createClientToken:a}=await t(),m=(p.lane==="jwt"?k(o,{baseUrl:l,orgId:i,jwt:p.jwt,diagnosticSink:e}):k(o,{baseUrl:l,orgId:i,diagnosticSink:e,getAccessToken:async()=>(await a(p.apiKey,{baseUrl:p.gatewayUrl,expiresIn:300,allowedFunctions:[`${o}/${s}`]})).token}))[s];if(typeof m!="function")throw new Error(`urun pi extension: app "${o}" has no function "${s}"`);let h=m();if(typeof h.end!="function")throw new Error(`urun pi extension: app "${o}" function "${s}" returned a session without end()`);let A=h.connect;return typeof A=="function"&&await A.call(h),h}}var Ce=Pe(async()=>{let{createRequire:t}=await import("module"),e=t(import.meta.url);if(typeof globalThis.RTCPeerConnection>"u")try{e.resolve("werift")}catch{throw new Error('urun pi extension: token streams require a WebRTC data channel, and this Node runtime has no RTCPeerConnection and no "werift" backend installed (@urun-sh/core\'s optional Node WebRTC backend \u2014 it was probably stripped by a --no-optional install). Install werift (`npm i werift`) and retry.')}return e("@urun-sh/core")});function Ne(t,e){try{return Promise.resolve(t.end()).then(()=>{},n=>e(n))}catch(n){return e(n),Promise.resolve()}}function $e(t){if(t?.hasUI===!1)return!0;if(t?.hasUI===!0)return!1;let e=process.argv.slice(2);if(e.includes("-p")||e.includes("--print"))return!0;let n=e.indexOf("--mode");return n!==-1&&(e[n+1]==="json"||e[n+1]==="rpc")?!0:!process.stdin.isTTY||!process.stdout.isTTY}function le(t,e){return`uRun: releasing the pooled "${t}" session failed \u2014 the backend session may stay allocated until the platform reclaims it: ${e instanceof Error?e.message:String(e)}`}var H=class{constructor(e,n,o,s=(l,i)=>j.warn(le(l,i))){this.open=e;this.env=n;this.fnName=o;this.onReleaseError=s}open;env;fnName;onReleaseError;pool=new Map;releasing=new Set;acquire(e){let n=this.pool.get(e);if(!n){let o=Promise.resolve(this.open(this.env,e,this.fnName)).then(s=>({session:s,responses:new z(s)}));n=o,this.pool.set(e,o),o.catch(()=>{this.pool.get(e)===o&&this.pool.delete(e)})}return n}evict(e){let n=this.pool.get(e);if(!n)return Promise.resolve();this.pool.delete(e);let o=n.then(s=>Ne(s.session,l=>this.onReleaseError(e,l)),()=>{});return this.releasing.add(o),o.then(()=>this.releasing.delete(o)),o}closeAll(){let e=[...this.pool.keys()].map(n=>this.evict(n));return Promise.all([...e,...this.releasing]).then(()=>{})}};function Le(t){let e=[];t.systemPrompt&&e.push({role:"system",content:t.systemPrompt});for(let n of t.messages){if(n.role==="toolResult"){e.push({type:"function_call_output",call_id:n.toolCallId,output:De(n.content)});continue}if(n.role==="assistant"&&Array.isArray(n.content)){let s="",l=()=>{s&&(e.push({role:"assistant",content:s}),s="")};for(let i of n.content)if(i.type==="text")s+=String(i.text??"");else if(i.type==="toolCall")l(),e.push({type:"function_call",call_id:String(i.id??""),name:String(i.name??""),arguments:JSON.stringify(i.arguments??{})});else{if(i.type==="thinking")continue;throw new Error(`urun pi extension: unsupported assistant content part "${String(i.type)}"`)}l();continue}let o=n.role==="assistant"?"assistant":"user";e.push({role:o,content:Me(n.content)})}return Oe(e)}function Oe(t){let e=[];for(let n of t){let o=e[e.length-1];o&&"role"in o&&"role"in n&&o.role===n.role?o.content=[o.content,n.content].filter(s=>s.length>0).join(`