@tangle-network/sandbox 0.11.1-develop.20260718200351.2f5db96 → 0.11.1

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,5 +1,4 @@
1
- import { $r as SendSessionMessageRequest, $t as ListMessagesOptions, At as GitBranch, Bi as WriteManyOptions, Bn as RolloutOptions, Bt as GpuLeaseManager, Cn as ProvisionEvent, D as CodeExecutionOptions, Ei as TeeAttestationResponse, Fr as SandboxRuntimeProfileList, Ft as GpuLease, H as CreateTaskSessionOptions, Hn as RolloutStartResult, Ii as WaitForOptions, In as RestoreSnapshotOptions, Ir as SandboxStatus, Jr as SearchMatch, Jt as IntelligenceReportBudget, K as DispatchPromptOptions, Kn as SSHCommandDescriptor, Kr as ScopedToken, Kt as InstalledTool, Li as WaitForRolloutOptions, Ln as ResumeOptions, M as CommitTaskSessionOptions, N as CompletedTurnResult, Nr as SandboxRuntimeHealth, Nt as GitDiff, O as CodeExecutionResult, Oi as TeePublicKeyResponse, Or as SandboxPortBinding, Pt as GitStatus, Q as DriverInfo, Qr as SendSessionMessageOptions, Qt as JsonValue, Ri as WriteFileOptions, Rn as Rollout, Si as TaskSessionInfo, Sn as PromptResult, Tr as SandboxInfo, V as CreateSessionOptions, Vr as SandboxTraceBundle, Wr as SandboxTraceOptions, X as DriveTurnOptions, Yn as SandboxConnection, Yr as SearchOptions, Yt as IntelligenceReportCompareTo, Zn as SandboxEvent, Zt as IntelligenceReportWindow, _i as TaskOptions, ai as SessionListOptions, bi as TaskSessionCommitResult, bn as PromptInputPart, di as SnapshotResult, ei as SentSessionMessage, et as DurablePlan, fn as PreviewLinkManager, gn as ProcessManager, gr as SandboxFleetTraceBundle, ii as SessionInfo, in as MintScopedTokenOptions, it as EventStreamOptions, ji as TurnDriveResult, jr as SandboxResourceUsage, jt as GitCommit, k as CodeLanguage, l as BackendManager, li as SnapshotInfo, mt as FileSystem, ni as SessionEventStreamOptions, oi as SessionMessage, ot as ExecOptions, pi as StartupDiagnostics, q as DispatchedSession, qn as SSHCredentials, qt as IntelligenceReport, ri as SessionForkOptions, s as BackendConfig, sn as NetworkManager, st as ExecResult, tt as EgressManager, ui as SnapshotOptions, un as PermissionsManager, vi as TaskResult, vt as FileWriteResult, w as BranchOptions, wi as TeeAttestationOptions, wn as ProvisionResult, xn as PromptOptions, yi as TaskSessionChanges, zi as WriteManyFile, zr as SandboxTerminalManager } from "./types-DACKEpON.js";
2
- import { AgentProfile } from "@tangle-network/agent-interface";
1
+ import { $ as DurablePlan, Bn as RolloutStartResult, Cr as SandboxInfo, D as CodeExecutionOptions, Ei as TeePublicKeyResponse, Er as SandboxPortBinding, Fi as WaitForRolloutOptions, Fn as ResumeOptions, G as DispatchPromptOptions, Gn as SSHCredentials, Gt as IntelligenceReport, H as CreateTaskSessionOptions, Hr as SandboxTraceOptions, Ii as WriteFileOptions, In as Rollout, K as DispatchedSession, Kr as SearchMatch, Kt as IntelligenceReportBudget, Li as WriteManyFile, Lr as SandboxTerminalManager, M as CommitTaskSessionOptions, Mt as GitStatus, N as CompletedTurnResult, Nr as SandboxRuntimeProfileList, Nt as GpuLease, O as CodeExecutionResult, Ot as GitBranch, Pi as WaitForOptions, Pn as RestoreSnapshotOptions, Pr as SandboxStatus, Qr as SentSessionMessage, Ri as WriteManyOptions, Rn as RolloutOptions, Rt as GpuLeaseManager, Si as TeeAttestationOptions, Sn as ProvisionResult, V as CreateSessionOptions, Wn as SSHCommandDescriptor, Wr as ScopedToken, Wt as InstalledTool, Xr as SendSessionMessageOptions, Xt as JsonValue, Y as DriveTurnOptions, Yn as SandboxEvent, Yt as IntelligenceReportWindow, Z as DriverInfo, Zr as SendSessionMessageRequest, Zt as ListMessagesOptions, _i as TaskSessionChanges, an as NetworkManager, at as ExecResult, bi as TaskSessionInfo, bn as PromptResult, ci as SnapshotOptions, cn as PermissionsManager, di as StartupDiagnostics, ei as SessionEventStreamOptions, et as EgressManager, ft as FileSystem, gi as TaskResult, gt as FileWriteResult, hi as TaskOptions, ii as SessionMessage, it as ExecOptions, jr as SandboxRuntimeHealth, jt as GitDiff, k as CodeLanguage, ki as TurnDriveResult, kr as SandboxResourceUsage, kt as GitCommit, l as BackendManager, li as SnapshotResult, mn as ProcessManager, mr as SandboxFleetTraceBundle, ni as SessionInfo, nn as MintScopedTokenOptions, nt as EventStreamOptions, qn as SandboxConnection, qr as SearchOptions, qt as IntelligenceReportCompareTo, ri as SessionListOptions, s as BackendConfig, si as SnapshotInfo, ti as SessionForkOptions, un as PreviewLinkManager, vi as TaskSessionCommitResult, vn as PromptInputPart, w as BranchOptions, wi as TeeAttestationResponse, xn as ProvisionEvent, yn as PromptOptions, zr as SandboxTraceBundle } from "./types-D2C72ySk.js";
3
2
 
4
3
  //#region src/mcp.d.ts
5
4
  /**
@@ -113,6 +112,18 @@ declare function buildControlPlaneMcpConfig(options: BuildControlPlaneMcpConfigO
113
112
  };
114
113
  //#endregion
115
114
  //#region src/interactive.d.ts
115
+ /**
116
+ * Interactive harness sessions on the public SDK.
117
+ *
118
+ * `box.session(id).interactive()` returns a handle that spawns a coding
119
+ * harness's native interactive TUI in the sandbox (start), drives it with
120
+ * prompts (sendPrompt), and tears it down (stop). The live framebuffer is
121
+ * streamed over the WebSocket at the returned `streamUrl` (the secured
122
+ * `/terminals/:id/ws` pixel lane) — open it with your terminal/xterm client.
123
+ *
124
+ * This is the public SDK surface of the Session Protocol Gateway; it rides the
125
+ * same secured runtime routes as the rest of the SDK.
126
+ */
116
127
  /** CLI auth file materialized into the harness's auth home before launch. */
117
128
  interface InteractiveAuthFile {
118
129
  path: string;
@@ -120,12 +131,7 @@ interface InteractiveAuthFile {
120
131
  mode?: number;
121
132
  }
122
133
  interface StartInteractiveOptions {
123
- /**
124
- * Harness with a native interactive TUI (bare binary launches it): e.g.
125
- * "claude-code", "codex", "opencode", "kimi-code", "factory-droids",
126
- * "forge", "pi", "amp", "hermes". The sidecar's harness registry is the
127
- * authority; it rejects harnesses without a TUI entrypoint (e.g. "cursor").
128
- */
134
+ /** Harness with a native interactive TUI: "claude-code" | "codex" | "kimi-code". */
129
135
  harness: string;
130
136
  model?: string;
131
137
  apiKey?: string;
@@ -136,20 +142,6 @@ interface StartInteractiveOptions {
136
142
  cols?: number;
137
143
  rows?: number;
138
144
  authFiles?: InteractiveAuthFile[];
139
- /**
140
- * Canonical agent profile (persona, skills, tool policy, MCP). When set, the
141
- * sidecar materializes it into `cwd` before spawning the TUI, so the
142
- * interactive session runs AS the configured agent rather than a bare harness.
143
- * Omit to launch the harness's default TUI.
144
- */
145
- profile?: AgentProfile;
146
- /**
147
- * Opening message the TUI submits on its own once ready (via the harness's
148
- * prompt launch arg). Use this to start the agent working immediately instead
149
- * of writing keystrokes after start — a TUI drops input sent before it is
150
- * ready to read. Omit for a session that opens idle.
151
- */
152
- initialPrompt?: string;
153
145
  }
154
146
  interface InteractiveSessionInfo {
155
147
  sessionId: string;
@@ -162,28 +154,6 @@ interface InteractiveSessionInfo {
162
154
  */
163
155
  streamUrl: string;
164
156
  }
165
- /**
166
- * Snapshot of an interactive session's lifecycle: still running, or exited
167
- * with its exit code (served from the sidecar's bounded exit tombstone).
168
- * `status()` returns `null` when the sidecar no longer knows the id — never
169
- * started, tombstone evicted, or superseded by a restart under the same id.
170
- */
171
- type InteractiveSessionStatus = {
172
- state: "running";
173
- sessionId: string;
174
- harness: string;
175
- startedAt: string;
176
- streamUrl: string;
177
- } | {
178
- state: "exited";
179
- sessionId: string;
180
- harness: string;
181
- startedAt: string;
182
- endedAt: string;
183
- exitCode?: number;
184
- exitSignal?: string; /** "exited" = the process ended on its own; "stopped" = explicit stop(). */
185
- reason: "exited" | "stopped";
186
- };
187
157
  /** Decision passed to `respondToPermission`. */
188
158
  interface RespondToPermissionOptions {
189
159
  /** The human's decision for the awaiting permission interaction. */
@@ -208,13 +178,6 @@ interface InteractiveSessionHost {
208
178
  _startInteractive(id: string, options: StartInteractiveOptions): Promise<InteractiveSessionInfo>;
209
179
  _sendInteractivePrompt(id: string, prompt: string): Promise<void>;
210
180
  _stopInteractive(id: string): Promise<void>;
211
- /**
212
- * Optional so adding it does not break existing implementers of this exported
213
- * interface (a required addition is a breaking change; this is additive). A
214
- * host that omits it makes `InteractiveSessionHandle.status()` reject with a
215
- * clear "not supported" error instead of failing to compile downstream.
216
- */
217
- _interactiveStatus?(id: string): Promise<InteractiveSessionStatus | null>;
218
181
  }
219
182
  /**
220
183
  * Handle for one session's interactive harness. Obtained via
@@ -228,19 +191,12 @@ declare class InteractiveSessionHandle {
228
191
  /**
229
192
  * Spawn the harness's interactive TUI for this session. Returns the
230
193
  * `streamUrl` to attach a terminal client to. Throws if the harness has no
231
- * interactive entrypoint (e.g. cursor, which is SDK-only), the binary is
232
- * not installed, or a session is already running for this id.
194
+ * interactive entrypoint (e.g. opencode), the binary is not installed, or a
195
+ * session is already running for this id.
233
196
  */
234
197
  start(options: StartInteractiveOptions): Promise<InteractiveSessionInfo>;
235
198
  /** Inject a prompt as keystrokes into the live harness (submitted on send). */
236
199
  sendPrompt(prompt: string): Promise<void>;
237
- /**
238
- * Observe the session: running, exited (with its exit code), or `null`
239
- * when the sidecar no longer knows the id. Poll this to detect completion —
240
- * an interactive session has no structured result stream, so the exit
241
- * tombstone is the completion signal.
242
- */
243
- status(): Promise<InteractiveSessionStatus | null>;
244
200
  /** Stop the interactive harness and reap its PTY. */
245
201
  stop(): Promise<void>;
246
202
  }
@@ -256,7 +212,7 @@ interface SandboxSessionHost extends InteractiveSessionHost {
256
212
  prompt(message: string | PromptInputPart[], options?: PromptOptions): Promise<PromptResult>;
257
213
  _sessionStatus(id: string): Promise<SessionInfo | null>;
258
214
  _sessionEvents(id: string, opts?: SessionEventStreamOptions): AsyncGenerator<SandboxEvent>;
259
- _sessionResult(id: string, session?: SessionInfo): Promise<PromptResult>;
215
+ _sessionResult(id: string): Promise<PromptResult>;
260
216
  _sessionCancel(id: string): Promise<void>;
261
217
  _sessionDelete(id: string): Promise<void>;
262
218
  _sessionSendMessage(id: string, request: SendSessionMessageRequest, options?: SendSessionMessageOptions): Promise<SentSessionMessage>;
@@ -307,10 +263,9 @@ declare class SandboxSession {
307
263
  */
308
264
  events(opts?: SessionEventStreamOptions): AsyncGenerator<SandboxEvent>;
309
265
  /**
310
- * Await the session's terminal result. Reads status and drains events
311
- * from the latest execution until the session reaches a terminal state,
312
- * then returns the aggregated `PromptResult`. Event replay makes this safe
313
- * to call after the execution has already finished.
266
+ * Await the session's terminal result. Polls status + drains events
267
+ * until the session reaches a terminal state, then returns the
268
+ * aggregated `PromptResult`.
314
269
  *
315
270
  * Use this to wait for a session that was started by another caller
316
271
  * (e.g. `dispatchPrompt`).
@@ -328,10 +283,8 @@ declare class SandboxSession {
328
283
  */
329
284
  prompt(message: string | PromptInputPart[], opts?: PromptOptions): Promise<PromptResult>;
330
285
  /**
331
- * Submit a structured message through the session message endpoint. The
332
- * returned receipt confirms admission; follow progress with `events()` or
333
- * await the terminal response with `result()`. Model and message identifiers
334
- * are translated to the runtime's wire names by the SDK.
286
+ * Send a structured message through the session message endpoint. Model and
287
+ * message identifiers are translated to the runtime's wire names by the SDK.
335
288
  */
336
289
  sendMessage(request: SendSessionMessageRequest, options?: SendSessionMessageOptions): Promise<SentSessionMessage>;
337
290
  /**
@@ -503,7 +456,6 @@ interface ToolsCapability {
503
456
  declare class SandboxInstance {
504
457
  private readonly client;
505
458
  private info;
506
- private refreshInFlight?;
507
459
  private readonly defaultRuntimeBackend?;
508
460
  private readonly runtime;
509
461
  constructor(client: HttpClient, info: SandboxInfo, defaultRuntimeBackend?: BackendConfig);
@@ -604,7 +556,6 @@ declare class SandboxInstance {
604
556
  * Refresh sandbox information from the server.
605
557
  */
606
558
  refresh(): Promise<void>;
607
- private refreshInfo;
608
559
  /**
609
560
  * Fetch fresh TEE attestation evidence for this sandbox.
610
561
  *
@@ -1083,7 +1034,6 @@ declare class SandboxInstance {
1083
1034
  * ```
1084
1035
  */
1085
1036
  get process(): ProcessManager;
1086
- private processEnsureDevServer;
1087
1037
  private processSpawn;
1088
1038
  private processSpawnExact;
1089
1039
  private processRunCode;
@@ -1439,13 +1389,13 @@ declare class SandboxInstance {
1439
1389
  * ```typescript
1440
1390
  * await box.registerSessionMapping({
1441
1391
  * sessionId: "sess_abc",
1442
- * runtimeSessionId: "runtime_abc",
1392
+ * userId: "user_123",
1443
1393
  * });
1444
1394
  * ```
1445
1395
  */
1446
1396
  registerSessionMapping(opts: {
1447
- sessionId: string; /** @deprecated Ownership is derived from the Sandbox API key. */
1448
- userId?: string; /** The runtime (sidecar) session id this agent session routes to. */
1397
+ sessionId: string;
1398
+ userId: string; /** The runtime (sidecar) session id this agent session routes to. */
1449
1399
  runtimeSessionId: string; /** Optional container id for direct routing. */
1450
1400
  sidecarId?: string; /** Optional projectRef so the server can detect a stale sidecar. */
1451
1401
  projectRef?: string;
@@ -1456,8 +1406,8 @@ declare class SandboxInstance {
1456
1406
  * sandbox stays alive.
1457
1407
  */
1458
1408
  unregisterSessionMapping(opts: {
1459
- sessionId: string; /** @deprecated Ownership is derived from the Sandbox API key. */
1460
- userId?: string;
1409
+ sessionId: string;
1410
+ userId: string;
1461
1411
  }): Promise<{
1462
1412
  success: boolean;
1463
1413
  sessionId: string;
@@ -1580,7 +1530,7 @@ declare class SandboxInstance {
1580
1530
  /** @internal — invoked by SandboxSession.events(). */
1581
1531
  _sessionEvents(id: string, opts?: SessionEventStreamOptions, stopOnTurnTerminal?: boolean): AsyncGenerator<SandboxEvent>;
1582
1532
  /** @internal — invoked by SandboxSession.result(). */
1583
- _sessionResult(id: string, knownSession?: SessionInfo): Promise<PromptResult>;
1533
+ _sessionResult(id: string): Promise<PromptResult>;
1584
1534
  /**
1585
1535
  * @internal — invoked by SandboxSession.cancel(). Void-returning alias of
1586
1536
  * `_interrupt`: both abort the in-flight execution via `POST /{id}/abort`
@@ -1593,8 +1543,6 @@ declare class SandboxInstance {
1593
1543
  _startInteractive(id: string, options: StartInteractiveOptions): Promise<InteractiveSessionInfo>;
1594
1544
  /** @internal — invoked by InteractiveSessionHandle.sendPrompt(). */
1595
1545
  _sendInteractivePrompt(id: string, prompt: string): Promise<void>;
1596
- /** @internal — invoked by InteractiveSessionHandle.status(). */
1597
- _interactiveStatus(id: string): Promise<InteractiveSessionStatus | null>;
1598
1546
  /** @internal — invoked by InteractiveSessionHandle.stop(). */
1599
1547
  _stopInteractive(id: string): Promise<void>;
1600
1548
  /** @internal — invoked by SandboxSession.respondToPermission(). */
@@ -1619,4 +1567,4 @@ declare class SandboxInstance {
1619
1567
  }): Promise<DurablePlan>;
1620
1568
  }
1621
1569
  //#endregion
1622
- export { SANDBOX_MCP_SERVER_NAME as C, buildControlPlaneMcpConfig as D, SandboxMcpServerEntry as E, buildSandboxMcpConfig as O, CONTROL_PLANE_MCP_SERVER_NAME as S, SandboxMcpEndpoint as T, InterruptResult as _, TraceExportSink as a, BuildControlPlaneMcpConfigOptions as b, otelTraceIdForTangleTrace as c, SandboxSession as d, InteractiveAuthFile as f, InteractiveSessionStatus as g, InteractiveSessionInfo as h, TraceExportResult as i, toOtelJson as l, InteractiveSessionHost as m, SandboxInstance as n, buildTraceExportPayload as o, InteractiveSessionHandle as p, TraceExportFormat as r, exportTraceBundle as s, HttpClient as t, SandboxTaskSession as u, RespondToPermissionOptions as v, SandboxMcpConfig as w, BuildSandboxMcpConfigOptions as x, StartInteractiveOptions as y };
1570
+ export { SandboxMcpConfig as C, buildSandboxMcpConfig as D, buildControlPlaneMcpConfig as E, SANDBOX_MCP_SERVER_NAME as S, SandboxMcpServerEntry as T, RespondToPermissionOptions as _, TraceExportSink as a, BuildSandboxMcpConfigOptions as b, otelTraceIdForTangleTrace as c, SandboxSession as d, InteractiveAuthFile as f, InterruptResult as g, InteractiveSessionInfo as h, TraceExportResult as i, toOtelJson as l, InteractiveSessionHost as m, SandboxInstance as n, buildTraceExportPayload as o, InteractiveSessionHandle as p, TraceExportFormat as r, exportTraceBundle as s, HttpClient as t, SandboxTaskSession as u, StartInteractiveOptions as v, SandboxMcpEndpoint as w, CONTROL_PLANE_MCP_SERVER_NAME as x, BuildControlPlaneMcpConfigOptions as y };
@@ -1,5 +1,5 @@
1
- import { l as normalizeRuntimeBackendConfig, n as normalizeSessionInfo, o as combineAbortSignals, r as uploadChunked, s as encodePromptForWire, t as SandboxRuntimeApi, u as normalizeRuntimeModelOverride } from "./runtime-api-r8vQVMe4.js";
2
- import { a as NotFoundError, c as SandboxError, d as TimeoutError, f as ValidationError, i as NetworkError, l as ServerError, n as CapabilityError, p as parseErrorResponse, s as QuotaError, t as AuthError, u as StateError } from "./errors-hbpL_-S6.js";
1
+ import { l as normalizeRuntimeBackendConfig, n as normalizeSessionInfo, o as combineAbortSignals, r as uploadChunked, s as encodePromptForWire, t as SandboxRuntimeApi } from "./runtime-api-kukaWPtF.js";
2
+ import { c as SandboxError, d as TimeoutError, f as ValidationError, i as NetworkError, l as ServerError, n as CapabilityError, p as parseErrorResponse, s as QuotaError, t as AuthError, u as StateError } from "./errors-Cbs78OlF.js";
3
3
  import { addTokenUsage, readTokenCostUsd, readTokenUsage } from "@tangle-network/agent-core";
4
4
  //#region src/lib/sse-parser.ts
5
5
  /**
@@ -434,8 +434,8 @@ var InteractiveSessionHandle = class {
434
434
  /**
435
435
  * Spawn the harness's interactive TUI for this session. Returns the
436
436
  * `streamUrl` to attach a terminal client to. Throws if the harness has no
437
- * interactive entrypoint (e.g. cursor, which is SDK-only), the binary is
438
- * not installed, or a session is already running for this id.
437
+ * interactive entrypoint (e.g. opencode), the binary is not installed, or a
438
+ * session is already running for this id.
439
439
  */
440
440
  start(options) {
441
441
  return this.host._startInteractive(this.sessionId, options);
@@ -444,16 +444,6 @@ var InteractiveSessionHandle = class {
444
444
  sendPrompt(prompt) {
445
445
  return this.host._sendInteractivePrompt(this.sessionId, prompt);
446
446
  }
447
- /**
448
- * Observe the session: running, exited (with its exit code), or `null`
449
- * when the sidecar no longer knows the id. Poll this to detect completion —
450
- * an interactive session has no structured result stream, so the exit
451
- * tombstone is the completion signal.
452
- */
453
- status() {
454
- if (!this.host._interactiveStatus) return Promise.reject(/* @__PURE__ */ new Error("Interactive session status is not supported by this host"));
455
- return this.host._interactiveStatus(this.sessionId);
456
- }
457
447
  /** Stop the interactive harness and reap its PTY. */
458
448
  stop() {
459
449
  return this.host._stopInteractive(this.sessionId);
@@ -519,10 +509,9 @@ var SandboxSession = class SandboxSession {
519
509
  return this.box._sessionEvents(this.id, opts);
520
510
  }
521
511
  /**
522
- * Await the session's terminal result. Reads status and drains events
523
- * from the latest execution until the session reaches a terminal state,
524
- * then returns the aggregated `PromptResult`. Event replay makes this safe
525
- * to call after the execution has already finished.
512
+ * Await the session's terminal result. Polls status + drains events
513
+ * until the session reaches a terminal state, then returns the
514
+ * aggregated `PromptResult`.
526
515
  *
527
516
  * Use this to wait for a session that was started by another caller
528
517
  * (e.g. `dispatchPrompt`).
@@ -552,10 +541,8 @@ var SandboxSession = class SandboxSession {
552
541
  });
553
542
  }
554
543
  /**
555
- * Submit a structured message through the session message endpoint. The
556
- * returned receipt confirms admission; follow progress with `events()` or
557
- * await the terminal response with `result()`. Model and message identifiers
558
- * are translated to the runtime's wire names by the SDK.
544
+ * Send a structured message through the session message endpoint. Model and
545
+ * message identifiers are translated to the runtime's wire names by the SDK.
559
546
  */
560
547
  async sendMessage(request, options) {
561
548
  return this.box._sessionSendMessage(this.id, request, options);
@@ -748,10 +735,6 @@ const SNAPSHOT_RESTORE_POLL_INTERVAL_MS = 1e3;
748
735
  const SNAPSHOT_RESTORE_TIMEOUT_MS = 600 * 1e3;
749
736
  const SNAPSHOT_VISIBILITY_POLL_INTERVAL_MS = 1e3;
750
737
  const SNAPSHOT_VISIBILITY_TIMEOUT_MS = 120 * 1e3;
751
- const EXEC_DEFAULT_TIMEOUT_MS = 3e4;
752
- const EXEC_MIN_TIMEOUT_MS = 100;
753
- const EXEC_MAX_TIMEOUT_MS = 6e5;
754
- const EXEC_TRANSPORT_MARGIN_MS = 15e3;
755
738
  const SNAPSHOT_CREATE_REQUEST_TIMEOUT_MS = 600 * 1e3;
756
739
  function toSnapshotResult(data) {
757
740
  return {
@@ -968,14 +951,6 @@ function parseTextFileReadResponse(body) {
968
951
  return payload.data.content;
969
952
  }
970
953
  const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
971
- const SANDBOX_STATUS_FRESHNESS_MS = 1e3;
972
- const sandboxStatusObservedAt = /* @__PURE__ */ new WeakMap();
973
- const directRuntimeInstances = /* @__PURE__ */ new WeakSet();
974
- function createSandboxInstanceFromResponse(client, info, defaultRuntimeBackend) {
975
- const instance = new SandboxInstance(client, info, defaultRuntimeBackend);
976
- sandboxStatusObservedAt.set(instance, Date.now());
977
- return instance;
978
- }
979
954
  /** Transient file-write failures worth retrying: rate-limit (quota), 5xx,
980
955
  * transport (network), and request timeouts. A non-transient error (bad path,
981
956
  * auth, validation) fails loud immediately. */
@@ -988,7 +963,6 @@ function isTransientWriteError(err) {
988
963
  var SandboxInstance = class SandboxInstance {
989
964
  client;
990
965
  info;
991
- refreshInFlight;
992
966
  defaultRuntimeBackend;
993
967
  runtime;
994
968
  constructor(client, info, defaultRuntimeBackend) {
@@ -1121,7 +1095,6 @@ var SandboxInstance = class SandboxInstance {
1121
1095
  const client = this.client;
1122
1096
  if (next && typeof client._emitTokenRefresh === "function") client._emitTokenRefresh(this.id, next);
1123
1097
  }), { ...this.info }, this.defaultRuntimeBackend);
1124
- directRuntimeInstances.add(directInstance);
1125
1098
  return directInstance;
1126
1099
  }
1127
1100
  /**
@@ -1161,19 +1134,6 @@ var SandboxInstance = class SandboxInstance {
1161
1134
  * Refresh sandbox information from the server.
1162
1135
  */
1163
1136
  async refresh() {
1164
- if (this.refreshInFlight) {
1165
- await this.refreshInFlight;
1166
- return;
1167
- }
1168
- const refresh = this.refreshInfo();
1169
- this.refreshInFlight = refresh;
1170
- try {
1171
- await refresh;
1172
- } finally {
1173
- if (this.refreshInFlight === refresh) this.refreshInFlight = void 0;
1174
- }
1175
- }
1176
- async refreshInfo() {
1177
1137
  const response = await this.client.fetch(`/v1/sandboxes/${this.id}`);
1178
1138
  if (!response.ok) {
1179
1139
  const body = await response.text();
@@ -1181,7 +1141,6 @@ var SandboxInstance = class SandboxInstance {
1181
1141
  }
1182
1142
  const data = await response.json();
1183
1143
  this.info = this.parseInfo(data);
1184
- sandboxStatusObservedAt.set(this, Date.now());
1185
1144
  }
1186
1145
  /**
1187
1146
  * Fetch fresh TEE attestation evidence for this sandbox.
@@ -1311,31 +1270,28 @@ var SandboxInstance = class SandboxInstance {
1311
1270
  */
1312
1271
  async exec(command, options) {
1313
1272
  await this.ensureRunning();
1314
- const timeoutMs = options?.timeoutMs ?? EXEC_DEFAULT_TIMEOUT_MS;
1315
- if (!Number.isInteger(timeoutMs) || timeoutMs < EXEC_MIN_TIMEOUT_MS || timeoutMs > EXEC_MAX_TIMEOUT_MS) throw new ValidationError(`exec timeoutMs must be an integer between ${EXEC_MIN_TIMEOUT_MS} and ${EXEC_MAX_TIMEOUT_MS}`);
1316
1273
  const headers = {};
1317
1274
  if (options?.sessionId) headers["X-Session-Id"] = options.sessionId;
1318
- const response = await this.runtimeFetch("/process/spawn", {
1275
+ const response = await this.runtimeFetch("/terminals/commands", {
1319
1276
  method: "POST",
1320
1277
  headers,
1321
1278
  body: JSON.stringify({
1322
1279
  command,
1323
1280
  cwd: options?.cwd,
1324
1281
  env: options?.env,
1325
- timeoutMs,
1326
- blocking: true
1282
+ timeout: options?.timeoutMs
1327
1283
  })
1328
- }, { timeoutMs: timeoutMs + EXEC_TRANSPORT_MARGIN_MS });
1284
+ });
1329
1285
  if (!response.ok) {
1330
1286
  const body = await response.text();
1331
1287
  throw parseErrorResponse(response.status, body, void 0, response.headers);
1332
1288
  }
1333
- const result = (await response.json()).data;
1334
- if (!result || typeof result.exitCode !== "number" || typeof result.stdout !== "string" || typeof result.stderr !== "string") throw new ServerError("Sandbox process response was malformed", 502);
1289
+ const data = await response.json();
1290
+ const result = data.result ?? data;
1335
1291
  return {
1336
- exitCode: result.exitCode,
1337
- stdout: result.stdout,
1338
- stderr: result.stderr
1292
+ exitCode: result.exitCode ?? 0,
1293
+ stdout: result.stdout ?? "",
1294
+ stderr: result.stderr ?? ""
1339
1295
  };
1340
1296
  }
1341
1297
  /**
@@ -1693,8 +1649,7 @@ var SandboxInstance = class SandboxInstance {
1693
1649
  requireVisibleAssistantOutput: options?.requireVisibleAssistantOutput,
1694
1650
  ...timeoutMs ? { timeoutMs } : {},
1695
1651
  ...options?.detach ? { detach: true } : {},
1696
- backend: normalizeRuntimeBackendConfig(options?.backend ?? this.defaultRuntimeBackend),
1697
- ...options?.model ? { model: normalizeRuntimeModelOverride(options.model) } : {}
1652
+ backend: normalizeRuntimeBackendConfig(options?.backend ?? this.defaultRuntimeBackend, { model: options?.model })
1698
1653
  })
1699
1654
  };
1700
1655
  response = await this.runtimeFetch(requestEndpoint, request);
@@ -3049,7 +3004,6 @@ var SandboxInstance = class SandboxInstance {
3049
3004
  */
3050
3005
  get process() {
3051
3006
  return {
3052
- ensureDevServer: (options) => this.processEnsureDevServer(options),
3053
3007
  spawn: (command, options) => this.processSpawn(command, options),
3054
3008
  spawnExact: (executable, args, options) => this.processSpawnExact(executable, args, options),
3055
3009
  runCode: (code, options) => this.processRunCode(code, options),
@@ -3057,26 +3011,6 @@ var SandboxInstance = class SandboxInstance {
3057
3011
  get: (pid) => this.processGet(pid)
3058
3012
  };
3059
3013
  }
3060
- async processEnsureDevServer(options) {
3061
- if (options?.sessionId !== void 0) assertValidSessionId(options.sessionId);
3062
- if (options?.cwd !== void 0 && (typeof options.cwd !== "string" || options.cwd.trim().length === 0)) throw new ValidationError("Dev server cwd must be a non-empty string");
3063
- await this.ensureRunning();
3064
- const headers = options?.sessionId ? { "X-Session-Id": options.sessionId } : void 0;
3065
- const response = await this.runtimeFetch("/process/ensure-dev-server", {
3066
- method: "POST",
3067
- headers,
3068
- body: JSON.stringify(options?.cwd ? { cwd: options.cwd } : {})
3069
- });
3070
- if (!response.ok) {
3071
- const body = await response.text();
3072
- throw parseErrorResponse(response.status, body, void 0, response.headers);
3073
- }
3074
- const payload = await response.json();
3075
- return {
3076
- ...payload.data,
3077
- startedAt: new Date(payload.data.startedAt)
3078
- };
3079
- }
3080
3014
  async processSpawn(command, options) {
3081
3015
  await this.ensureRunning();
3082
3016
  const response = await this.runtimeFetch("/process/spawn", {
@@ -3105,7 +3039,6 @@ var SandboxInstance = class SandboxInstance {
3105
3039
  args,
3106
3040
  cwd: options?.cwd,
3107
3041
  env: options?.env,
3108
- inheritEnv: options?.inheritEnv,
3109
3042
  timeoutMs: options?.timeoutMs,
3110
3043
  stdin: options?.stdin,
3111
3044
  blocking: false
@@ -3896,7 +3829,7 @@ var SandboxInstance = class SandboxInstance {
3896
3829
  const body = await response.text();
3897
3830
  throw parseErrorResponse(response.status, body, void 0, response.headers);
3898
3831
  }
3899
- return ((await response.json()).children ?? []).map((child) => createSandboxInstanceFromResponse(this.client, this.parseInfo(child), this.defaultRuntimeBackend));
3832
+ return ((await response.json()).children ?? []).map((child) => new SandboxInstance(this.client, this.parseInfo(child), this.defaultRuntimeBackend));
3900
3833
  }
3901
3834
  /**
3902
3835
  * Speculative rollouts: branch this RUNNING sandbox into `n` copy-on-write
@@ -4029,7 +3962,6 @@ var SandboxInstance = class SandboxInstance {
4029
3962
  }
4030
3963
  const diagnostics = await this.readLifecycleDiagnostics(response);
4031
3964
  if (diagnostics) this.info.startupDiagnostics = diagnostics;
4032
- sandboxStatusObservedAt.delete(this);
4033
3965
  }
4034
3966
  /**
4035
3967
  * Read the per-phase lifecycle breakdown off a stop/resume/delete response
@@ -4238,15 +4170,12 @@ var SandboxInstance = class SandboxInstance {
4238
4170
  }
4239
4171
  }
4240
4172
  async ensureRunning() {
4241
- const statusObservedAt = sandboxStatusObservedAt.get(this) ?? 0;
4242
- const statusAgeMs = Date.now() - statusObservedAt;
4243
- if (directRuntimeInstances.has(this) || statusObservedAt <= 0 || statusAgeMs < 0 || statusAgeMs >= SANDBOX_STATUS_FRESHNESS_MS) await this.refresh();
4173
+ await this.refresh();
4244
4174
  if (this.status !== "running") throw new StateError(`Sandbox is not running (status: ${this.status})`, this.status, "running");
4245
4175
  }
4246
- async runtimeFetch(path, options, fetchOptions) {
4176
+ async runtimeFetch(path, options) {
4247
4177
  const url = `/v1/sandboxes/${encodeURIComponent(this.id)}/runtime${path}`;
4248
4178
  try {
4249
- if (fetchOptions) return await this.client.fetch(url, options, fetchOptions);
4250
4179
  return options ? await this.client.fetch(url, options) : await this.client.fetch(url);
4251
4180
  } catch (err) {
4252
4181
  throw new NetworkError(`Failed to connect to sandbox: ${err instanceof Error ? err.message : String(err)}`, err instanceof Error ? err : void 0, {
@@ -4284,16 +4213,17 @@ var SandboxInstance = class SandboxInstance {
4284
4213
  * ```typescript
4285
4214
  * await box.registerSessionMapping({
4286
4215
  * sessionId: "sess_abc",
4287
- * runtimeSessionId: "runtime_abc",
4216
+ * userId: "user_123",
4288
4217
  * });
4289
4218
  * ```
4290
4219
  */
4291
4220
  async registerSessionMapping(opts) {
4292
4221
  const response = await this.client.fetch(`/v1/session/${encodeURIComponent(opts.sessionId)}/mapping`, {
4293
4222
  method: "PUT",
4223
+ headers: { "x-user-id": opts.userId },
4294
4224
  body: JSON.stringify({
4295
4225
  sidecarSessionId: opts.runtimeSessionId,
4296
- sidecarId: opts.sidecarId ?? this.id,
4226
+ ...opts.sidecarId ? { sidecarId: opts.sidecarId } : {},
4297
4227
  ...opts.projectRef ? { projectRef: opts.projectRef } : {}
4298
4228
  })
4299
4229
  });
@@ -4322,7 +4252,10 @@ var SandboxInstance = class SandboxInstance {
4322
4252
  * sandbox stays alive.
4323
4253
  */
4324
4254
  async unregisterSessionMapping(opts) {
4325
- const response = await this.client.fetch(`/v1/session/${encodeURIComponent(opts.sessionId)}/mapping`, { method: "DELETE" });
4255
+ const response = await this.client.fetch(`/v1/session/${encodeURIComponent(opts.sessionId)}/mapping`, {
4256
+ method: "DELETE",
4257
+ headers: { "x-user-id": opts.userId }
4258
+ });
4326
4259
  if (!response.ok) {
4327
4260
  const body = await response.text();
4328
4261
  throw parseErrorResponse(response.status, body, void 0, response.headers);
@@ -4581,11 +4514,7 @@ var SandboxInstance = class SandboxInstance {
4581
4514
  };
4582
4515
  }
4583
4516
  if (info) {
4584
- if (!info.latestExecutionId) return {
4585
- state: "failed",
4586
- error: `session ${opts.sessionId} ${info.status}: no execution result is available`
4587
- };
4588
- const result = await this._sessionResult(opts.sessionId, info);
4517
+ const result = await this._sessionResult(opts.sessionId);
4589
4518
  const settled = settleTurnDrive({ ...result });
4590
4519
  if (settled.state === "awaiting_plan_decision") return settled;
4591
4520
  if (!result.success) return {
@@ -4608,14 +4537,12 @@ var SandboxInstance = class SandboxInstance {
4608
4537
  */
4609
4538
  async mintScopedToken(opts) {
4610
4539
  if ((opts.scope === "session" || opts.scope === "session-runtime") && !opts.sessionId) throw new ValidationError(`${opts.scope} scope requires a sessionId`);
4611
- if (opts.scope === "session" && !opts.runtimeSessionId) throw new ValidationError("session scope requires the actual runtimeSessionId");
4612
4540
  const response = await this.client.fetch(`/v1/sandboxes/${encodeURIComponent(this.id)}/scoped-token`, {
4613
4541
  method: "POST",
4614
4542
  headers: { "Content-Type": "application/json" },
4615
4543
  body: JSON.stringify({
4616
4544
  scope: opts.scope,
4617
4545
  ...opts.sessionId ? { sessionId: opts.sessionId } : {},
4618
- ...opts.scope === "session" ? { runtimeSessionId: opts.runtimeSessionId } : {},
4619
4546
  ...opts.ttlMinutes ? { ttlMinutes: opts.ttlMinutes } : {}
4620
4547
  })
4621
4548
  });
@@ -4663,17 +4590,8 @@ var SandboxInstance = class SandboxInstance {
4663
4590
  }
4664
4591
  }
4665
4592
  /** @internal — invoked by SandboxSession.result(). */
4666
- async _sessionResult(id, knownSession) {
4593
+ async _sessionResult(id) {
4667
4594
  const startTime = Date.now();
4668
- const session = knownSession ?? await this._sessionStatus(id);
4669
- if (!session) throw new NotFoundError("Session", id, {
4670
- origin: "runtime",
4671
- endpoint: `/agents/sessions/${encodeURIComponent(id)}`
4672
- });
4673
- if (!session.latestExecutionId) throw new StateError(`Session ${id} has no execution result to await`, session.status, "session with an admitted execution", {
4674
- origin: "runtime",
4675
- endpoint: `/agents/sessions/${encodeURIComponent(id)}`
4676
- }, "SESSION_EXECUTION_MISSING");
4677
4595
  let response;
4678
4596
  let runError;
4679
4597
  let runErrorCode;
@@ -4684,10 +4602,7 @@ var SandboxInstance = class SandboxInstance {
4684
4602
  let question;
4685
4603
  let plan;
4686
4604
  let terminalReached = false;
4687
- for await (const event of this._sessionEvents(id, {
4688
- since: "0",
4689
- executionId: session.latestExecutionId
4690
- }, true)) {
4605
+ for await (const event of this._sessionEvents(id, void 0, true)) {
4691
4606
  response = applySandboxEventText(response, event);
4692
4607
  if (event.type === "result" || event.type === "done") {
4693
4608
  const data = event.data;
@@ -4777,22 +4692,6 @@ var SandboxInstance = class SandboxInstance {
4777
4692
  throw parseErrorResponse(response.status, body, void 0, response.headers);
4778
4693
  }
4779
4694
  }
4780
- /** @internal — invoked by InteractiveSessionHandle.status(). */
4781
- async _interactiveStatus(id) {
4782
- await this.ensureRunning();
4783
- const response = await this.runtimeFetch(`/agents/sessions/${encodeURIComponent(id)}/interactive`, { method: "GET" });
4784
- if (response.status === 404) return null;
4785
- if (!response.ok) {
4786
- const body = await response.text();
4787
- throw parseErrorResponse(response.status, body, void 0, response.headers);
4788
- }
4789
- const data = (await response.json())?.data;
4790
- if (!data || data.state !== "running" && data.state !== "exited") throw new ServerError("Interactive status response missing data", 502, {
4791
- endpoint: `/agents/sessions/${encodeURIComponent(id)}/interactive`,
4792
- origin: "runtime"
4793
- });
4794
- return data;
4795
- }
4796
4695
  /** @internal — invoked by InteractiveSessionHandle.stop(). */
4797
4696
  async _stopInteractive(id) {
4798
4697
  await this.ensureRunning();
@@ -5002,4 +4901,4 @@ function quoteForShell(value) {
5002
4901
  return `'${value.replace(/'/g, "'\\''")}'`;
5003
4902
  }
5004
4903
  //#endregion
5005
- export { SandboxSession as a, collectAgentResponseText as c, buildTraceExportPayload as d, exportTraceBundle as f, parseSSEStream as h, SandboxTaskSession as i, getSandboxEventText as l, toOtelJson as m, createSandboxInstanceFromResponse as n, InteractiveSessionHandle as o, otelTraceIdForTangleTrace as p, normalizeStartupDiagnostics as r, applySandboxEventText as s, SandboxInstance as t, normalizeConnection as u };
4904
+ export { InteractiveSessionHandle as a, getSandboxEventText as c, exportTraceBundle as d, otelTraceIdForTangleTrace as f, SandboxSession as i, normalizeConnection as l, parseSSEStream as m, normalizeStartupDiagnostics as n, applySandboxEventText as o, toOtelJson as p, SandboxTaskSession as r, collectAgentResponseText as s, SandboxInstance as t, buildTraceExportPayload as u };