@tangle-network/sandbox 0.31.1 → 0.32.0-develop.20260825062920.7dde010

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,7 +1,7 @@
1
- import { d as assertCurrentBackendType } from "../runtime-api-B0tx7NJM.js";
1
+ import { f as assertCurrentBackendType } from "../runtime-api-paApH4-W.js";
2
2
  import { d as StateError, o as NotFoundError, p as ValidationError } from "../errors-C6kn-3zt.js";
3
- import { n as Sandbox } from "../client-BfnJ44gF.js";
4
- import { t as SandboxInstance } from "../sandbox-AUHcCJe1.js";
3
+ import { n as Sandbox } from "../client-BRegsZuj.js";
4
+ import { t as SandboxInstance } from "../sandbox-CyP8CXaF.js";
5
5
  import { createRequire } from "node:module";
6
6
  //#region src/agent/instances.ts
7
7
  const managers = /* @__PURE__ */ new WeakMap();
@@ -1,7 +1,7 @@
1
- import { c as encodePromptForWire, d as assertCurrentBackendType, f as normalizeRuntimeBackendConfig, g as backendTypeSchema, l as encodeTextForWire, o as SANDBOX_PROXY_REQUEST_MAX_BYTES, u as applyRequestedModel } from "./runtime-api-B0tx7NJM.js";
1
+ import { _ as backendTypeSchema, c as encodePromptForWire, d as applyRequestedModel, f as assertCurrentBackendType, l as encodeTextForWire, o as SANDBOX_PROXY_REQUEST_MAX_BYTES, p as normalizeRuntimeBackendConfig, u as parseSSEStream } from "./runtime-api-paApH4-W.js";
2
2
  import { a as NetworkError, f as TimeoutError, l as SandboxError, m as parseErrorResponse, o as NotFoundError, p as ValidationError, s as PartialFailureError, t as AuthError, u as ServerError } from "./errors-C6kn-3zt.js";
3
3
  import { n as combineAbortSignals } from "./abort-signal-si1WMfJb.js";
4
- import { C as normalizeConnection, O as parseSSEStream, T as exportTraceBundle, _ as requestInteractiveSessionToken, i as normalizeStartupDiagnostics, n as createSandboxInstanceFromResponse, r as normalizeSandboxCreateReceipt } from "./sandbox-AUHcCJe1.js";
4
+ import { C as normalizeConnection, T as exportTraceBundle, _ as requestInteractiveSessionToken, i as normalizeStartupDiagnostics, n as createSandboxInstanceFromResponse, r as normalizeSandboxCreateReceipt } from "./sandbox-CyP8CXaF.js";
5
5
  import { agentProfileSchema } from "@tangle-network/agent-interface";
6
6
  import { z } from "zod";
7
7
  //#region src/backend-registry.ts
package/dist/core.js CHANGED
@@ -1,4 +1,4 @@
1
1
  import { a as NetworkError, c as QuotaError, d as StateError, f as TimeoutError, i as FileWriteConflictError, l as SandboxError, n as CapabilityError, o as NotFoundError, p as ValidationError, s as PartialFailureError, t as AuthError, u as ServerError } from "./errors-C6kn-3zt.js";
2
- import { _ as parseBackendRegistryResponseBody, d as backendRegistryCapabilitiesSchema, f as backendRegistryEntrySchema, g as parseBackendRegistryResponse, h as isBackendRegistryInteractionKind, m as backendRegistryResponseSchema, n as Sandbox, p as backendRegistryInteractionKindSchema } from "./client-BfnJ44gF.js";
3
- import { a as WorkspaceImages, t as SandboxInstance } from "./sandbox-AUHcCJe1.js";
2
+ import { _ as parseBackendRegistryResponseBody, d as backendRegistryCapabilitiesSchema, f as backendRegistryEntrySchema, g as parseBackendRegistryResponse, h as isBackendRegistryInteractionKind, m as backendRegistryResponseSchema, n as Sandbox, p as backendRegistryInteractionKindSchema } from "./client-BRegsZuj.js";
3
+ import { a as WorkspaceImages, t as SandboxInstance } from "./sandbox-CyP8CXaF.js";
4
4
  export { AuthError, CapabilityError, FileWriteConflictError, NetworkError, NotFoundError, PartialFailureError, QuotaError, Sandbox, SandboxError, SandboxInstance, ServerError, StateError, TimeoutError, ValidationError, WorkspaceImages, backendRegistryCapabilitiesSchema, backendRegistryEntrySchema, backendRegistryInteractionKindSchema, backendRegistryResponseSchema, isBackendRegistryInteractionKind, parseBackendRegistryResponse, parseBackendRegistryResponseBody };
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
- import { _ as parseBackendType, f as normalizeRuntimeBackendConfig, g as backendTypeSchema, h as deriveAgentRunOutcome, m as deriveAgentResultOutcome, p as createAgentRunOutcomeTracker } from "./runtime-api-B0tx7NJM.js";
1
+ import { _ as backendTypeSchema, g as deriveAgentRunOutcome, h as deriveAgentResultOutcome, m as createAgentRunOutcomeTracker, p as normalizeRuntimeBackendConfig, u as parseSSEStream, v as parseBackendType } from "./runtime-api-paApH4-W.js";
2
2
  import { a as NetworkError, c as QuotaError, d as StateError, f as TimeoutError, i as FileWriteConflictError, l as SandboxError, n as CapabilityError, o as NotFoundError, p as ValidationError, r as EgressProxyRecoveryError, s as PartialFailureError, t as AuthError, u as ServerError } from "./errors-C6kn-3zt.js";
3
- import { _ as parseBackendRegistryResponseBody, a as splitInlineProfileSkills, c as SandboxFleetClient, d as backendRegistryCapabilitiesSchema, f as backendRegistryEntrySchema, g as parseBackendRegistryResponse, h as isBackendRegistryInteractionKind, i as splitInlineProfileFileMounts, l as createBatchResultAccumulator, m as backendRegistryResponseSchema, n as Sandbox, o as validateDeferredProfileFileMounts, p as backendRegistryInteractionKindSchema, r as materializeProfileFileMounts, s as SandboxFleet, t as IntelligenceClient, u as validateBatchRunRequest } from "./client-BfnJ44gF.js";
3
+ import { _ as parseBackendRegistryResponseBody, a as splitInlineProfileSkills, c as SandboxFleetClient, d as backendRegistryCapabilitiesSchema, f as backendRegistryEntrySchema, g as parseBackendRegistryResponse, h as isBackendRegistryInteractionKind, i as splitInlineProfileFileMounts, l as createBatchResultAccumulator, m as backendRegistryResponseSchema, n as Sandbox, o as validateDeferredProfileFileMounts, p as backendRegistryInteractionKindSchema, r as materializeProfileFileMounts, s as SandboxFleet, t as IntelligenceClient, u as validateBatchRunRequest } from "./client-BRegsZuj.js";
4
4
  import { a as INTERACTIVE_CONTROL_CLEANUP_TIMEOUT_MS, c as createInteractiveControlHolderId, l as interactiveSessionIdentityDigest, n as browserInteractiveControlHolderId, o as InteractiveSessionControlController, t as BrowserInteractiveSessionControlController } from "./browser-interactive-control-controller-wXQ7W5pT.js";
5
- import { D as toOtelJson, E as otelTraceIdForTangleTrace, O as parseSSEStream, S as isToolBearingEvent, T as exportTraceBundle, a as WorkspaceImages, b as collectAgentResponseText, c as SandboxTaskSession, d as agentInteractiveSessionPromptRequestDigest, f as BrowserInteractiveSessionController, g as TERMINAL_WS_ECHO_SUBPROTOCOL, h as TerminalStreamError, l as SandboxSession, m as TerminalStream, o as GPU_LEASE_PROVIDER_NAMES, p as InteractiveSessionController, s as MAX_EGRESS_DENIALS_LIMIT, t as SandboxInstance, u as InteractiveSessionHandle, v as applySandboxEventText, w as buildTraceExportPayload, x as getSandboxEventText, y as collectAgentFinalMessageText } from "./sandbox-AUHcCJe1.js";
5
+ import { D as toOtelJson, E as otelTraceIdForTangleTrace, S as isToolBearingEvent, T as exportTraceBundle, a as WorkspaceImages, b as collectAgentResponseText, c as SandboxTaskSession, d as agentInteractiveSessionPromptRequestDigest, f as BrowserInteractiveSessionController, g as TERMINAL_WS_ECHO_SUBPROTOCOL, h as TerminalStreamError, l as SandboxSession, m as TerminalStream, o as GPU_LEASE_PROVIDER_NAMES, p as InteractiveSessionController, s as MAX_EGRESS_DENIALS_LIMIT, t as SandboxInstance, u as InteractiveSessionHandle, v as applySandboxEventText, w as buildTraceExportPayload, x as getSandboxEventText, y as collectAgentFinalMessageText } from "./sandbox-CyP8CXaF.js";
6
6
  import { a as CollaborationClient, i as parseCollaborationDocumentId, n as buildCollaborationDocumentId, r as normalizeCollaborationPath, t as CollaborationFileBridge } from "./collaboration-DQD9kCdN.js";
7
- import { t as TangleSandboxClient } from "./tangle-iDk_s8vt.js";
7
+ import { t as TangleSandboxClient } from "./tangle-DcZBrAGY.js";
8
8
  import { SANDBOX_SIZE_PRESET_NAMES, agentProfileConfidentialSchema, agentProfileSchema } from "@tangle-network/agent-interface";
9
9
  import { z } from "zod";
10
10
  //#region src/confidential.ts
@@ -495,6 +495,197 @@ function normalizeRuntimeBackendConfig(backend) {
495
495
  };
496
496
  }
497
497
  //#endregion
498
+ //#region ../../../packages/sse-core/dist/index.js
499
+ /**
500
+ * Incremental SSE frame parser. Feed decoded text via `push()`; call
501
+ * `flush()` when the stream ends.
502
+ */
503
+ var SSEFrameParser = class {
504
+ buffer = "";
505
+ frameEvent = "";
506
+ frameId;
507
+ frameDataLines = null;
508
+ bomChecked = false;
509
+ /**
510
+ * Append a decoded text chunk and return every frame the chunk
511
+ * completes. Frame state survives across calls: one frame can
512
+ * straddle any number of chunks.
513
+ */
514
+ push(chunk) {
515
+ let text = chunk;
516
+ if (!this.bomChecked && text.length > 0) {
517
+ this.bomChecked = true;
518
+ if (text.charCodeAt(0) === 65279) text = text.slice(1);
519
+ }
520
+ this.buffer += text;
521
+ const lines = this.buffer.split("\n");
522
+ this.buffer = lines.pop() ?? "";
523
+ return this.processLines(lines);
524
+ }
525
+ /**
526
+ * End-of-stream: process the unterminated trailing line, then
527
+ * dispatch a dangling frame that never got its blank line.
528
+ * Well-behaved servers end frames with "\n\n", but some close early.
529
+ */
530
+ flush() {
531
+ const rest = this.buffer;
532
+ this.buffer = "";
533
+ const frames = rest.length > 0 ? this.processLines([rest]) : [];
534
+ const dangling = this.dispatch();
535
+ if (dangling) frames.push(dangling);
536
+ return frames;
537
+ }
538
+ processLines(lines) {
539
+ const frames = [];
540
+ for (const rawLine of lines) {
541
+ const line = rawLine.endsWith("\r") ? rawLine.slice(0, -1) : rawLine;
542
+ if (line === "") {
543
+ const frame = this.dispatch();
544
+ if (frame) frames.push(frame);
545
+ continue;
546
+ }
547
+ if (line.startsWith(":")) continue;
548
+ if (line.startsWith("data:")) {
549
+ let value = line.slice(5);
550
+ if (value.startsWith(" ")) value = value.slice(1);
551
+ if (this.frameDataLines === null) this.frameDataLines = [];
552
+ this.frameDataLines.push(value);
553
+ continue;
554
+ }
555
+ if (line.startsWith("event:")) {
556
+ this.frameEvent = line.slice(6).trim();
557
+ continue;
558
+ }
559
+ if (line.startsWith("id:")) this.frameId = line.slice(3).trim();
560
+ }
561
+ return frames;
562
+ }
563
+ /**
564
+ * Dispatch the accumulated frame. A frame with no `data:` field (an
565
+ * `event:`/`id:`-only frame, or a bare comment) produces nothing, and
566
+ * its field state is consumed and reset either way.
567
+ */
568
+ dispatch() {
569
+ const dataLines = this.frameDataLines;
570
+ const frame = dataLines ? {
571
+ event: this.frameEvent,
572
+ data: dataLines.join("\n"),
573
+ id: this.frameId || void 0
574
+ } : null;
575
+ this.frameEvent = "";
576
+ this.frameId = void 0;
577
+ this.frameDataLines = null;
578
+ return frame;
579
+ }
580
+ };
581
+ /**
582
+ * Read a streaming SSE response body into parsed frames.
583
+ *
584
+ * @throws `TypeError` when the body is missing.
585
+ * @throws `DOMException` with `name === "AbortError"` on cancellation —
586
+ * including the WHATWG-fetch variant where an aborted body resolves
587
+ * `done: true` instead of rejecting the read.
588
+ */
589
+ async function* streamSSEFrames(body, options) {
590
+ if (!body) throw new TypeError("SSE stream has no response body");
591
+ const reader = body.getReader();
592
+ const decoder = new TextDecoder();
593
+ const parser = new SSEFrameParser();
594
+ const { signal } = options ?? {};
595
+ let completed = false;
596
+ try {
597
+ for (;;) {
598
+ if (signal?.aborted) throw new DOMException("SSE stream aborted", "AbortError");
599
+ const { done, value } = await reader.read();
600
+ if (done) {
601
+ if (signal?.aborted) throw new DOMException("SSE stream aborted", "AbortError");
602
+ break;
603
+ }
604
+ for (const frame of parser.push(decoder.decode(value, { stream: true }))) yield frame;
605
+ }
606
+ for (const frame of parser.push(decoder.decode())) yield frame;
607
+ for (const frame of parser.flush()) yield frame;
608
+ completed = true;
609
+ } finally {
610
+ if (!completed) await reader.cancel().catch(() => void 0);
611
+ reader.releaseLock();
612
+ }
613
+ }
614
+ //#endregion
615
+ //#region src/lib/sse-parser.ts
616
+ /**
617
+ * SSE Stream Parser
618
+ *
619
+ * EventSource stream parsing for SDK consumers. Framing — buffering
620
+ * chunk-straddling frames, LF/CRLF terminators, multi-line `data:` joins,
621
+ * comment heartbeats, BOM — lives in `@tangle-network/sse-core`, the one
622
+ * wire-format implementation shared across the repo (bundled into this
623
+ * package's dist, so the SDK stays dependency-free at runtime). This
624
+ * module owns the SDK's payload contract on top of it: JSON parsing, the
625
+ * `"message"` default event type, and the malformed-frame policy. Used by
626
+ * `Sandbox.streamBatch` and by the web dashboard's batch page; exported
627
+ * so downstream surfaces don't maintain their own copies.
628
+ *
629
+ * Guarantees:
630
+ * - Correctly buffers frames that straddle chunk boundaries.
631
+ * - Accepts LF- and CRLF-terminated streams interchangeably.
632
+ * - Joins multi-line `data:` per the spec (dispatch joins with
633
+ * "\n" before JSON parse).
634
+ * - Defaults event type to `"message"` when a frame carries
635
+ * `data:` but no `event:` field (SSE spec §9.2.6 step 3).
636
+ * - Surfaces optional `id:` so callers can implement reconnection.
637
+ * - Flushes a dangling event when the stream closes without a
638
+ * terminating blank line (well-behaved servers emit `\n\n`, but
639
+ * some close early).
640
+ * - Throws `AbortError` when the caller-supplied signal fires, so
641
+ * consumers can distinguish "ran to completion" from "cancelled"
642
+ * without peeking at signal state.
643
+ * - Rejects malformed JSON by default. Callers handling recoverable output
644
+ * streams can explicitly warn and skip one invalid frame.
645
+ *
646
+ * What it does NOT do:
647
+ * - CR-only (legacy Mac) line terminators. No known emitter uses
648
+ * them; supporting them would risk splitting payloads that
649
+ * legitimately contain CR.
650
+ * - Retry/reconnect (caller's responsibility).
651
+ * - Event-type filtering (caller's responsibility).
652
+ */
653
+ /**
654
+ * Parse a streaming SSE response body into an async iterable of
655
+ * structured events.
656
+ *
657
+ * @throws `TypeError` when the response has no body.
658
+ * @throws `DOMException` with `name === "AbortError"` on cancellation.
659
+ */
660
+ async function* parseSSEStream(body, options) {
661
+ const { signal, invalidEvent = "throw" } = options ?? {};
662
+ for await (const frame of streamSSEFrames(body, { signal })) {
663
+ const effectiveEvent = frame.event || "message";
664
+ let data;
665
+ try {
666
+ data = JSON.parse(frame.data);
667
+ } catch (error) {
668
+ if (invalidEvent === "warn-and-skip") {
669
+ console.warn(`[sandbox-sdk] Malformed SSE JSON for event "${effectiveEvent}": ${frame.data.slice(0, 200)}`);
670
+ continue;
671
+ }
672
+ throw new SyntaxError(`Malformed SSE JSON for event "${effectiveEvent}"`, { cause: error });
673
+ }
674
+ if (typeof data !== "object" || data === null || Array.isArray(data)) {
675
+ if (invalidEvent === "warn-and-skip") {
676
+ console.warn(`[sandbox-sdk] SSE event "${effectiveEvent}" data must be a JSON object`);
677
+ continue;
678
+ }
679
+ throw new TypeError(`SSE event "${effectiveEvent}" data must be a JSON object`);
680
+ }
681
+ yield {
682
+ type: effectiveEvent,
683
+ data,
684
+ id: frame.id
685
+ };
686
+ }
687
+ }
688
+ //#endregion
498
689
  //#region src/lib/wire-encoding.ts
499
690
  /**
500
691
  * Encode a prompt text part for the wire. Server decodes at the route
@@ -851,6 +1042,51 @@ var SandboxRuntimeApi = class {
851
1042
  await this.transport.ensureRunning();
852
1043
  return (await this.json("/ports", { method: "GET" })).data?.ports ?? [];
853
1044
  }
1045
+ /**
1046
+ * Subscribe to a session's agent event stream (`/agents/events`).
1047
+ *
1048
+ * The consume half of the supervisor pattern: construct the client from a
1049
+ * `read-only` or `session-runtime` scoped token
1050
+ * (`SandboxInstance.mintScopedToken`) and a parent agent observes a child
1051
+ * sandbox's stream while holding no credential that can mutate the child.
1052
+ * With `executionId` set, the stream ends at that turn's terminal
1053
+ * `done`/`error` event; a stream that dies before the terminal throws
1054
+ * instead of reading like a finished turn. Aborting `options.signal` ends
1055
+ * the generator cleanly, matching every other SDK stream. Events carry no
1056
+ * `data.sandboxId` stamp here: a scoped-token client knows only its own
1057
+ * runtime URL, and the subscriber already knows which sandbox it minted
1058
+ * the token for.
1059
+ */
1060
+ async *events(sessionId, options = {}) {
1061
+ await this.transport.ensureRunning();
1062
+ const search = new URLSearchParams();
1063
+ search.set("sessionId", sessionId);
1064
+ if (options.since) search.set("since", options.since);
1065
+ if (options.executionId) search.set("executionId", options.executionId);
1066
+ const response = await this.request(`/agents/events?${search.toString()}`, { signal: options.signal });
1067
+ if (!response.body) throw new NetworkError("event stream has no response body");
1068
+ let sawTerminal = false;
1069
+ try {
1070
+ for await (const event of parseSSEStream(response.body, {
1071
+ signal: options.signal,
1072
+ invalidEvent: "warn-and-skip"
1073
+ })) {
1074
+ yield {
1075
+ type: event.type,
1076
+ data: event.data,
1077
+ ...event.id !== void 0 ? { id: event.id } : {}
1078
+ };
1079
+ if (options.executionId !== void 0 && (event.type === "done" || event.type === "error")) {
1080
+ sawTerminal = true;
1081
+ return;
1082
+ }
1083
+ }
1084
+ } catch (err) {
1085
+ if (err instanceof DOMException && err.name === "AbortError") return;
1086
+ throw err;
1087
+ }
1088
+ if (options.executionId !== void 0 && !sawTerminal) throw new NetworkError("event stream ended before a terminal event — the connection dropped mid-turn");
1089
+ }
854
1090
  async readFiles(paths, options = {}) {
855
1091
  const params = new URLSearchParams();
856
1092
  appendSessionIdQuery(params, options.sessionId);
@@ -1207,4 +1443,4 @@ function normalizeSessionInfo(raw) {
1207
1443
  };
1208
1444
  }
1209
1445
  //#endregion
1210
- export { parseBackendType as _, uploadChunked as a, encodePromptForWire as c, assertCurrentBackendType as d, normalizeRuntimeBackendConfig as f, backendTypeSchema as g, deriveAgentRunOutcome as h, sessionHeaders as i, encodeTextForWire as l, deriveAgentResultOutcome as m, normalizeSessionInfo as n, SANDBOX_PROXY_REQUEST_MAX_BYTES as o, createAgentRunOutcomeTracker as p, appendSessionIdQuery as r, FILE_DECODED_WRITE_MAX_BYTES as s, SandboxRuntimeApi as t, applyRequestedModel as u };
1446
+ export { backendTypeSchema as _, uploadChunked as a, encodePromptForWire as c, applyRequestedModel as d, assertCurrentBackendType as f, deriveAgentRunOutcome as g, deriveAgentResultOutcome as h, sessionHeaders as i, encodeTextForWire as l, createAgentRunOutcomeTracker as m, normalizeSessionInfo as n, SANDBOX_PROXY_REQUEST_MAX_BYTES as o, normalizeRuntimeBackendConfig as p, appendSessionIdQuery as r, FILE_DECODED_WRITE_MAX_BYTES as s, SandboxRuntimeApi as t, parseSSEStream as u, parseBackendType as v };
package/dist/runtime.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { C as ChunkedUploadResult, Fi as TaskSessionCommitResult, Gn as RenameOptions, Kr as SandboxRuntimeHealth, L as CreateSessionOptions, Li as TaskSessionInfo, O as CommitTaskSessionOptions, Pi as TaskSessionChanges, Qr as SandboxTerminalRequestOptions, R as CreateTaskSessionOptions, S as ChunkedUploadOptions, St as FileWriteResult, Vr as SandboxPortBinding, Xr as SandboxTerminalInfo, Yi as UploadProgress, Yr as SandboxTerminalCreateOptions, Zr as SandboxTerminalManager, bt as FileUsageOptions, di as SentSessionMessage, dt as FileReadBatchOptions, ea as WriteFileOptions, ft as FileReadBatchResult, gi as SessionInfo, ht as FileRenameResult, li as SendSessionMessageOptions, sn as ListMessagesOptions, ui as SendSessionMessageRequest, vt as FileTreeOptions, xt as FileUsageResult, yi as SessionMessage, yt as FileTreeResult } from "./types-BwYLVqxX.js";
1
+ import { C as ChunkedUploadResult, Fi as TaskSessionCommitResult, Gn as RenameOptions, Kr as SandboxRuntimeHealth, L as CreateSessionOptions, Li as TaskSessionInfo, O as CommitTaskSessionOptions, Pi as TaskSessionChanges, Qr as SandboxTerminalRequestOptions, R as CreateTaskSessionOptions, S as ChunkedUploadOptions, St as FileWriteResult, Vr as SandboxPortBinding, Xr as SandboxTerminalInfo, Yi as UploadProgress, Yr as SandboxTerminalCreateOptions, Zr as SandboxTerminalManager, bt as FileUsageOptions, di as SentSessionMessage, dt as FileReadBatchOptions, ea as WriteFileOptions, ft as FileReadBatchResult, gi as SessionInfo, ht as FileRenameResult, li as SendSessionMessageOptions, pi as SessionEventStreamOptions, sn as ListMessagesOptions, ui as SendSessionMessageRequest, ur as SandboxEvent, vt as FileTreeOptions, xt as FileUsageResult, yi as SessionMessage, yt as FileTreeResult } from "./types-BwYLVqxX.js";
2
2
  import { a as NetworkError, c as QuotaError, d as SandboxFailureDetail, f as ServerError, h as ValidationError, i as FileWriteConflictError, l as SandboxError, m as TimeoutError, n as CapabilityError, o as NotFoundError, p as StateError, s as PartialFailureError, t as AuthError, u as SandboxErrorJson } from "./errors-CQOvGddH.js";
3
3
  import { a as deriveAgentRunOutcome, i as deriveAgentResultOutcome, n as AgentRunOutcomeTracker, r as createAgentRunOutcomeTracker, t as AgentRunOutcome } from "./agent-run-outcome-CM7xD7Mg.js";
4
4
 
@@ -39,6 +39,22 @@ declare class SandboxRuntimeApi {
39
39
  constructor(transport: RuntimeTransport);
40
40
  health(): Promise<SandboxRuntimeHealth>;
41
41
  ports(): Promise<SandboxPortBinding[]>;
42
+ /**
43
+ * Subscribe to a session's agent event stream (`/agents/events`).
44
+ *
45
+ * The consume half of the supervisor pattern: construct the client from a
46
+ * `read-only` or `session-runtime` scoped token
47
+ * (`SandboxInstance.mintScopedToken`) and a parent agent observes a child
48
+ * sandbox's stream while holding no credential that can mutate the child.
49
+ * With `executionId` set, the stream ends at that turn's terminal
50
+ * `done`/`error` event; a stream that dies before the terminal throws
51
+ * instead of reading like a finished turn. Aborting `options.signal` ends
52
+ * the generator cleanly, matching every other SDK stream. Events carry no
53
+ * `data.sandboxId` stamp here: a scoped-token client knows only its own
54
+ * runtime URL, and the subscriber already knows which sandbox it minted
55
+ * the token for.
56
+ */
57
+ events(sessionId: string, options?: SessionEventStreamOptions): AsyncGenerator<SandboxEvent>;
42
58
  readFiles(paths: string[], options?: FileReadBatchOptions): Promise<FileReadBatchResult>;
43
59
  writeFile(path: string, content: string, options?: WriteFileOptions): Promise<FileWriteResult>;
44
60
  /**
@@ -104,4 +120,4 @@ declare class SandboxRuntimeClient extends SandboxRuntimeApi {
104
120
  }
105
121
  declare function createSandboxRuntimeClient(config: SandboxRuntimeClientConfig): SandboxRuntimeClient;
106
122
  //#endregion
107
- export { type AgentRunOutcome, type AgentRunOutcomeTracker, AuthError, CapabilityError, type ChunkedUploadOptions, type ChunkedUploadResult, type ChunkedUploadTransport, type FileReadBatchOptions, type FileReadBatchResult, type FileRenameResult, type FileTreeOptions, type FileTreeResult, FileWriteConflictError, type FileWriteResult, type ListMessagesOptions, NetworkError, NotFoundError, PartialFailureError, QuotaError, type RenameOptions, SandboxError, type SandboxErrorJson, type SandboxFailureDetail, SandboxRuntimeClient, type SandboxRuntimeClientConfig, type SandboxRuntimeHealth, type SandboxTerminalCreateOptions, type SandboxTerminalInfo, type SandboxTerminalManager, type SandboxTerminalRequestOptions, ServerError, type SessionMessage, StateError, TimeoutError, type UploadProgress, ValidationError, type WriteFileOptions, createAgentRunOutcomeTracker, createSandboxRuntimeClient, deriveAgentResultOutcome, deriveAgentRunOutcome, uploadChunked };
123
+ export { type AgentRunOutcome, type AgentRunOutcomeTracker, AuthError, CapabilityError, type ChunkedUploadOptions, type ChunkedUploadResult, type ChunkedUploadTransport, type FileReadBatchOptions, type FileReadBatchResult, type FileRenameResult, type FileTreeOptions, type FileTreeResult, FileWriteConflictError, type FileWriteResult, type ListMessagesOptions, NetworkError, NotFoundError, PartialFailureError, QuotaError, type RenameOptions, SandboxError, type SandboxErrorJson, type SandboxEvent, type SandboxFailureDetail, SandboxRuntimeClient, type SandboxRuntimeClientConfig, type SandboxRuntimeHealth, type SandboxTerminalCreateOptions, type SandboxTerminalInfo, type SandboxTerminalManager, type SandboxTerminalRequestOptions, ServerError, type SessionEventStreamOptions, type SessionMessage, StateError, TimeoutError, type UploadProgress, ValidationError, type WriteFileOptions, createAgentRunOutcomeTracker, createSandboxRuntimeClient, deriveAgentResultOutcome, deriveAgentRunOutcome, uploadChunked };
package/dist/runtime.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as uploadChunked, h as deriveAgentRunOutcome, m as deriveAgentResultOutcome, p as createAgentRunOutcomeTracker, t as SandboxRuntimeApi } from "./runtime-api-B0tx7NJM.js";
1
+ import { a as uploadChunked, g as deriveAgentRunOutcome, h as deriveAgentResultOutcome, m as createAgentRunOutcomeTracker, t as SandboxRuntimeApi } from "./runtime-api-paApH4-W.js";
2
2
  import { a as NetworkError, c as QuotaError, d as StateError, f as TimeoutError, i as FileWriteConflictError, l as SandboxError, n as CapabilityError, o as NotFoundError, p as ValidationError, s as PartialFailureError, t as AuthError, u as ServerError } from "./errors-C6kn-3zt.js";
3
3
  import { n as combineAbortSignals } from "./abort-signal-si1WMfJb.js";
4
4
  //#region src/runtime-client.ts
@@ -1,4 +1,4 @@
1
- import { a as uploadChunked, c as encodePromptForWire, d as assertCurrentBackendType, f as normalizeRuntimeBackendConfig, i as sessionHeaders, m as deriveAgentResultOutcome, n as normalizeSessionInfo, o as SANDBOX_PROXY_REQUEST_MAX_BYTES, p as createAgentRunOutcomeTracker, r as appendSessionIdQuery, t as SandboxRuntimeApi, u as applyRequestedModel } from "./runtime-api-B0tx7NJM.js";
1
+ import { a as uploadChunked, c as encodePromptForWire, d as applyRequestedModel, f as assertCurrentBackendType, h as deriveAgentResultOutcome, i as sessionHeaders, m as createAgentRunOutcomeTracker, n as normalizeSessionInfo, o as SANDBOX_PROXY_REQUEST_MAX_BYTES, p as normalizeRuntimeBackendConfig, r as appendSessionIdQuery, t as SandboxRuntimeApi, u as parseSSEStream } from "./runtime-api-paApH4-W.js";
2
2
  import { a as NetworkError, c as QuotaError, d as StateError, f as TimeoutError, l as SandboxError, m as parseErrorResponse, n as CapabilityError, o as NotFoundError, p as ValidationError, t as AuthError, u as ServerError } from "./errors-C6kn-3zt.js";
3
3
  import { c as createInteractiveControlHolderId, d as interactiveSessionControlReleaseResponseSchema, f as interactiveSessionStatusResponseSchema, i as createBrowserInteractiveSessionControlTransport, o as InteractiveSessionControlController, r as browserInteractiveTerminalEndpoint, s as assertInteractiveSessionRef, u as interactiveSessionControlClaimResponseSchema } from "./browser-interactive-control-controller-wXQ7W5pT.js";
4
4
  import { n as combineAbortSignals, t as awaitWithAbort } from "./abort-signal-si1WMfJb.js";
@@ -6,197 +6,6 @@ import { AgentExactRunControlRefSchema, AgentInteractiveSessionAttachSchema, Age
6
6
  import { z } from "zod";
7
7
  import { AgentInteractiveSessionControlClaimSchema as AgentInteractiveSessionControlClaimSchema$1, AgentInteractiveSessionPromptAcknowledgementSchema as AgentInteractiveSessionPromptAcknowledgementSchema$1, AgentInteractiveSessionRefSchema as AgentInteractiveSessionRefSchema$1, AgentInteractiveSessionStatusSchema, AgentInteractiveSessionStopAcknowledgementSchema as AgentInteractiveSessionStopAcknowledgementSchema$1 } from "@tangle-network/agent-interface/environment-interactive-control";
8
8
  import { readTokenCostUsd, readTokenUsage } from "@tangle-network/agent-core";
9
- //#region ../../../packages/sse-core/dist/index.js
10
- /**
11
- * Incremental SSE frame parser. Feed decoded text via `push()`; call
12
- * `flush()` when the stream ends.
13
- */
14
- var SSEFrameParser = class {
15
- buffer = "";
16
- frameEvent = "";
17
- frameId;
18
- frameDataLines = null;
19
- bomChecked = false;
20
- /**
21
- * Append a decoded text chunk and return every frame the chunk
22
- * completes. Frame state survives across calls: one frame can
23
- * straddle any number of chunks.
24
- */
25
- push(chunk) {
26
- let text = chunk;
27
- if (!this.bomChecked && text.length > 0) {
28
- this.bomChecked = true;
29
- if (text.charCodeAt(0) === 65279) text = text.slice(1);
30
- }
31
- this.buffer += text;
32
- const lines = this.buffer.split("\n");
33
- this.buffer = lines.pop() ?? "";
34
- return this.processLines(lines);
35
- }
36
- /**
37
- * End-of-stream: process the unterminated trailing line, then
38
- * dispatch a dangling frame that never got its blank line.
39
- * Well-behaved servers end frames with "\n\n", but some close early.
40
- */
41
- flush() {
42
- const rest = this.buffer;
43
- this.buffer = "";
44
- const frames = rest.length > 0 ? this.processLines([rest]) : [];
45
- const dangling = this.dispatch();
46
- if (dangling) frames.push(dangling);
47
- return frames;
48
- }
49
- processLines(lines) {
50
- const frames = [];
51
- for (const rawLine of lines) {
52
- const line = rawLine.endsWith("\r") ? rawLine.slice(0, -1) : rawLine;
53
- if (line === "") {
54
- const frame = this.dispatch();
55
- if (frame) frames.push(frame);
56
- continue;
57
- }
58
- if (line.startsWith(":")) continue;
59
- if (line.startsWith("data:")) {
60
- let value = line.slice(5);
61
- if (value.startsWith(" ")) value = value.slice(1);
62
- if (this.frameDataLines === null) this.frameDataLines = [];
63
- this.frameDataLines.push(value);
64
- continue;
65
- }
66
- if (line.startsWith("event:")) {
67
- this.frameEvent = line.slice(6).trim();
68
- continue;
69
- }
70
- if (line.startsWith("id:")) this.frameId = line.slice(3).trim();
71
- }
72
- return frames;
73
- }
74
- /**
75
- * Dispatch the accumulated frame. A frame with no `data:` field (an
76
- * `event:`/`id:`-only frame, or a bare comment) produces nothing, and
77
- * its field state is consumed and reset either way.
78
- */
79
- dispatch() {
80
- const dataLines = this.frameDataLines;
81
- const frame = dataLines ? {
82
- event: this.frameEvent,
83
- data: dataLines.join("\n"),
84
- id: this.frameId || void 0
85
- } : null;
86
- this.frameEvent = "";
87
- this.frameId = void 0;
88
- this.frameDataLines = null;
89
- return frame;
90
- }
91
- };
92
- /**
93
- * Read a streaming SSE response body into parsed frames.
94
- *
95
- * @throws `TypeError` when the body is missing.
96
- * @throws `DOMException` with `name === "AbortError"` on cancellation —
97
- * including the WHATWG-fetch variant where an aborted body resolves
98
- * `done: true` instead of rejecting the read.
99
- */
100
- async function* streamSSEFrames(body, options) {
101
- if (!body) throw new TypeError("SSE stream has no response body");
102
- const reader = body.getReader();
103
- const decoder = new TextDecoder();
104
- const parser = new SSEFrameParser();
105
- const { signal } = options ?? {};
106
- let completed = false;
107
- try {
108
- for (;;) {
109
- if (signal?.aborted) throw new DOMException("SSE stream aborted", "AbortError");
110
- const { done, value } = await reader.read();
111
- if (done) {
112
- if (signal?.aborted) throw new DOMException("SSE stream aborted", "AbortError");
113
- break;
114
- }
115
- for (const frame of parser.push(decoder.decode(value, { stream: true }))) yield frame;
116
- }
117
- for (const frame of parser.push(decoder.decode())) yield frame;
118
- for (const frame of parser.flush()) yield frame;
119
- completed = true;
120
- } finally {
121
- if (!completed) await reader.cancel().catch(() => void 0);
122
- reader.releaseLock();
123
- }
124
- }
125
- //#endregion
126
- //#region src/lib/sse-parser.ts
127
- /**
128
- * SSE Stream Parser
129
- *
130
- * EventSource stream parsing for SDK consumers. Framing — buffering
131
- * chunk-straddling frames, LF/CRLF terminators, multi-line `data:` joins,
132
- * comment heartbeats, BOM — lives in `@tangle-network/sse-core`, the one
133
- * wire-format implementation shared across the repo (bundled into this
134
- * package's dist, so the SDK stays dependency-free at runtime). This
135
- * module owns the SDK's payload contract on top of it: JSON parsing, the
136
- * `"message"` default event type, and the malformed-frame policy. Used by
137
- * `Sandbox.streamBatch` and by the web dashboard's batch page; exported
138
- * so downstream surfaces don't maintain their own copies.
139
- *
140
- * Guarantees:
141
- * - Correctly buffers frames that straddle chunk boundaries.
142
- * - Accepts LF- and CRLF-terminated streams interchangeably.
143
- * - Joins multi-line `data:` per the spec (dispatch joins with
144
- * "\n" before JSON parse).
145
- * - Defaults event type to `"message"` when a frame carries
146
- * `data:` but no `event:` field (SSE spec §9.2.6 step 3).
147
- * - Surfaces optional `id:` so callers can implement reconnection.
148
- * - Flushes a dangling event when the stream closes without a
149
- * terminating blank line (well-behaved servers emit `\n\n`, but
150
- * some close early).
151
- * - Throws `AbortError` when the caller-supplied signal fires, so
152
- * consumers can distinguish "ran to completion" from "cancelled"
153
- * without peeking at signal state.
154
- * - Rejects malformed JSON by default. Callers handling recoverable output
155
- * streams can explicitly warn and skip one invalid frame.
156
- *
157
- * What it does NOT do:
158
- * - CR-only (legacy Mac) line terminators. No known emitter uses
159
- * them; supporting them would risk splitting payloads that
160
- * legitimately contain CR.
161
- * - Retry/reconnect (caller's responsibility).
162
- * - Event-type filtering (caller's responsibility).
163
- */
164
- /**
165
- * Parse a streaming SSE response body into an async iterable of
166
- * structured events.
167
- *
168
- * @throws `TypeError` when the response has no body.
169
- * @throws `DOMException` with `name === "AbortError"` on cancellation.
170
- */
171
- async function* parseSSEStream(body, options) {
172
- const { signal, invalidEvent = "throw" } = options ?? {};
173
- for await (const frame of streamSSEFrames(body, { signal })) {
174
- const effectiveEvent = frame.event || "message";
175
- let data;
176
- try {
177
- data = JSON.parse(frame.data);
178
- } catch (error) {
179
- if (invalidEvent === "warn-and-skip") {
180
- console.warn(`[sandbox-sdk] Malformed SSE JSON for event "${effectiveEvent}": ${frame.data.slice(0, 200)}`);
181
- continue;
182
- }
183
- throw new SyntaxError(`Malformed SSE JSON for event "${effectiveEvent}"`, { cause: error });
184
- }
185
- if (typeof data !== "object" || data === null || Array.isArray(data)) {
186
- if (invalidEvent === "warn-and-skip") {
187
- console.warn(`[sandbox-sdk] SSE event "${effectiveEvent}" data must be a JSON object`);
188
- continue;
189
- }
190
- throw new TypeError(`SSE event "${effectiveEvent}" data must be a JSON object`);
191
- }
192
- yield {
193
- type: effectiveEvent,
194
- data,
195
- id: frame.id
196
- };
197
- }
198
- }
199
- //#endregion
200
9
  //#region src/trace-exporter.ts
201
10
  function buildTraceExportPayload(bundle, format = "tangle", serviceName = "tangle-sandbox") {
202
11
  if (format === "tangle") return bundle;
@@ -7584,4 +7393,4 @@ function quoteForShell(value) {
7584
7393
  return `'${value.replace(/'/g, "'\\''")}'`;
7585
7394
  }
7586
7395
  //#endregion
7587
- export { normalizeConnection as C, toOtelJson as D, otelTraceIdForTangleTrace as E, parseSSEStream as O, isToolBearingEvent as S, exportTraceBundle as T, requestInteractiveSessionToken as _, WorkspaceImages as a, collectAgentResponseText as b, SandboxTaskSession as c, agentInteractiveSessionPromptRequestDigest as d, BrowserInteractiveSessionController as f, TERMINAL_WS_ECHO_SUBPROTOCOL as g, TerminalStreamError as h, normalizeStartupDiagnostics as i, SandboxSession as l, TerminalStream as m, createSandboxInstanceFromResponse as n, GPU_LEASE_PROVIDER_NAMES as o, InteractiveSessionController as p, normalizeSandboxCreateReceipt as r, MAX_EGRESS_DENIALS_LIMIT as s, SandboxInstance as t, InteractiveSessionHandle as u, applySandboxEventText as v, buildTraceExportPayload as w, getSandboxEventText as x, collectAgentFinalMessageText as y };
7396
+ export { normalizeConnection as C, toOtelJson as D, otelTraceIdForTangleTrace as E, isToolBearingEvent as S, exportTraceBundle as T, requestInteractiveSessionToken as _, WorkspaceImages as a, collectAgentResponseText as b, SandboxTaskSession as c, agentInteractiveSessionPromptRequestDigest as d, BrowserInteractiveSessionController as f, TERMINAL_WS_ECHO_SUBPROTOCOL as g, TerminalStreamError as h, normalizeStartupDiagnostics as i, SandboxSession as l, TerminalStream as m, createSandboxInstanceFromResponse as n, GPU_LEASE_PROVIDER_NAMES as o, InteractiveSessionController as p, normalizeSandboxCreateReceipt as r, MAX_EGRESS_DENIALS_LIMIT as s, SandboxInstance as t, InteractiveSessionHandle as u, applySandboxEventText as v, buildTraceExportPayload as w, getSandboxEventText as x, collectAgentFinalMessageText as y };
@@ -1,2 +1,2 @@
1
- import { a as TANGLE_JOBS_CONTRACT, c as ITangleJobsAbi, d as SandboxCreateResponseParamTypes, f as SandboxIdParamTypes, i as TANGLE_CHAIN_ID, l as JsonResponseParamTypes, n as JOB_SANDBOX_CREATE, o as TANGLE_MAINNET_RPC, r as JOB_SANDBOX_DELETE, s as AgentSandboxBlueprintAbi, t as TangleSandboxClient, u as SandboxCreateParamTypes } from "../tangle-iDk_s8vt.js";
1
+ import { a as TANGLE_JOBS_CONTRACT, c as ITangleJobsAbi, d as SandboxCreateResponseParamTypes, f as SandboxIdParamTypes, i as TANGLE_CHAIN_ID, l as JsonResponseParamTypes, n as JOB_SANDBOX_CREATE, o as TANGLE_MAINNET_RPC, r as JOB_SANDBOX_DELETE, s as AgentSandboxBlueprintAbi, t as TangleSandboxClient, u as SandboxCreateParamTypes } from "../tangle-DcZBrAGY.js";
2
2
  export { AgentSandboxBlueprintAbi, ITangleJobsAbi, JOB_SANDBOX_CREATE, JOB_SANDBOX_DELETE, JsonResponseParamTypes, SandboxCreateParamTypes, SandboxCreateResponseParamTypes, SandboxIdParamTypes, TANGLE_CHAIN_ID, TANGLE_JOBS_CONTRACT, TANGLE_MAINNET_RPC, TangleSandboxClient };
@@ -1,5 +1,5 @@
1
1
  import { m as parseErrorResponse } from "./errors-C6kn-3zt.js";
2
- import { n as createSandboxInstanceFromResponse } from "./sandbox-AUHcCJe1.js";
2
+ import { n as createSandboxInstanceFromResponse } from "./sandbox-CyP8CXaF.js";
3
3
  //#region src/tangle/abi.ts
4
4
  /**
5
5
  * Tangle Contract ABI Definitions
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/sandbox",
3
- "version": "0.31.1",
3
+ "version": "0.32.0-develop.20260825062920.7dde010",
4
4
  "description": "Client SDK for the Tangle Sandbox platform - build AI agent applications with dev containers",
5
5
  "type": "module",
6
6
  "sideEffects": [
@@ -137,8 +137,8 @@
137
137
  "yjs": "13.6.30",
138
138
  "@repo/shared": "0.0.0",
139
139
  "@tangle-network/cli-agent-registry": "0.3.11",
140
- "@tangle-network/sse-core": "0.0.0",
141
- "@tangle-network/runtime-contracts": "0.6.2"
140
+ "@tangle-network/runtime-contracts": "0.6.2",
141
+ "@tangle-network/sse-core": "0.0.0"
142
142
  },
143
143
  "scripts": {
144
144
  "build": "node scripts/build-dist.mjs",