@tangle-network/sandbox 1.0.190 → 1.0.192

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/dist/agent/index.d.ts +4 -4
  2. package/dist/agent/index.js +9 -6
  3. package/dist/agent/preview.d.ts +1 -1
  4. package/dist/agent/preview.js +1 -1
  5. package/dist/{agent-run-outcome-Cst4px_l.d.ts → agent-run-outcome-BO5paRhX.d.ts} +2 -2
  6. package/dist/{api-request-CZlFy3ku.js → api-request-BHbSfsRr.js} +1 -1
  7. package/dist/{browser-interactive-control-controller-DHIS8edi.js → browser-interactive-control-controller-BYbNLahH.js} +1 -1
  8. package/dist/{browser-interactive-control-controller-DIvMQyer.d.ts → browser-interactive-control-controller-KOK6qn2s.d.ts} +1 -1
  9. package/dist/{chunked-upload-vAE2hVcP.js → chunked-upload-D5ytV_s6.js} +9 -13
  10. package/dist/{chunked-upload-file-HLSriv3V.js → chunked-upload-file-DL1-AqRp.js} +2 -2
  11. package/dist/{client-BERYosgI.js → client-DuWQNr-Q.js} +159 -109
  12. package/dist/{client-C4SnCCpF.d.ts → client-yWdLuj_P.d.ts} +5 -5
  13. package/dist/collaboration/index.js +1 -1
  14. package/dist/{collaboration-CmT6Ygiv.js → collaboration-Bbr45lyk.js} +3 -3
  15. package/dist/{core-BT-0QZT-.js → core-BU1I2KvV.js} +13 -7
  16. package/dist/core.d.ts +6 -6
  17. package/dist/core.js +5 -5
  18. package/dist/errors-Mzq10WZq.js +583 -0
  19. package/dist/{file-download-BXgu9BNh.js → file-download-CKOxcATB.js} +1 -1
  20. package/dist/{index-DDIymnCZ.d.ts → index-DKsOu5sq.d.ts} +5 -5
  21. package/dist/index.d.ts +9 -9
  22. package/dist/index.js +10 -10
  23. package/dist/intelligence/index.js +9 -5
  24. package/dist/interactive-control.d.ts +1 -1
  25. package/dist/interactive-control.js +1 -1
  26. package/dist/{interactive-controller-DXGWBdYK.d.ts → interactive-controller-YyZEsoB0.d.ts} +3 -3
  27. package/dist/{interactive-controller-C876Pjaj.js → interactive-controller-jr3_74Pq.js} +90 -57
  28. package/dist/lib/prepared-evidence.js +1 -1
  29. package/dist/lib/prepared-process.js +1 -1
  30. package/dist/{lines-Br3ygqhP.d.ts → lines-CCHDUfQg.d.ts} +1 -1
  31. package/dist/{lines-DxHJhxCe.js → lines-DrG0WOW6.js} +1 -1
  32. package/dist/lines.d.ts +1 -1
  33. package/dist/lines.js +1 -1
  34. package/dist/{mcp-local-D7MpwsW0.js → mcp-local-O1HzsQiZ.js} +3 -3
  35. package/dist/{prepared-evidence-CP1MmeCQ.js → prepared-evidence-4prvV0YK.js} +1 -1
  36. package/dist/{prepared-process-BWVz93cT.js → prepared-process-BSpZXDDw.js} +1 -1
  37. package/dist/{preview-DUxqnKSk.d.ts → preview-I1z42VGY.d.ts} +3 -3
  38. package/dist/{public-templates-DQiblzzK.d.ts → public-templates-Cw6gmWJD.d.ts} +2 -2
  39. package/dist/public-templates.d.ts +1 -1
  40. package/dist/public-templates.js +7 -4
  41. package/dist/{raw-evidence-archive-CgbWa4es.js → raw-evidence-archive-BD37zHN5.js} +2 -2
  42. package/dist/runtime.d.ts +5 -5
  43. package/dist/runtime.js +9 -7
  44. package/dist/{sandbox-B_Xbc9wR.js → sandbox-Dtb-_btd.js} +317 -221
  45. package/dist/select-seat-command.d.ts +1 -1
  46. package/dist/select-seat-command.js +5 -2
  47. package/dist/session-gateway/index.js +1 -1
  48. package/dist/tangle/index.d.ts +1 -1
  49. package/dist/tangle/index.js +1 -1
  50. package/dist/{tangle-Sg9ORVAA.js → tangle-fs17QlcY.js} +2 -2
  51. package/dist/{terminal-stream-types-1YKRrkZB.d.ts → terminal-stream-types-BqNv5EuG.d.ts} +280 -305
  52. package/dist/{types-B-UsXSi6.d.ts → types-CiuGb4lZ.d.ts} +4 -2
  53. package/package.json +4 -4
  54. package/dist/errors-CaX0a5Ry.js +0 -636
  55. /package/dist/{abort-signal-PgWPMn_e.js → abort-signal-Cu4F2VVz.js} +0 -0
  56. /package/dist/{file-transfer-DTHgLccV.js → file-transfer-Cr9Ossea.js} +0 -0
  57. /package/dist/{retry-after-header-Bt-XvU-x.js → retry-after-header-DUdCC0KJ.js} +0 -0
@@ -1,4 +1,4 @@
1
- import { $ as ProxySecretReceipt, At as SandboxCreateReceipt, G as AgentProfileConfidential, L as AgentExactRunControlRef, Q as ReasoningEffort, U as AgentProfile, V as InteractionRequest, W as AgentProfileCapabilities, Z as AgentProfileValidationResult, a as TerminalStreamOptions, b as SandboxSizePreset, g as TerminalReadyInfo, i as TerminalStreamHandlers, s as TerminalStreamToken, t as TerminalAttachTimings, tt as PlanContinuation, x as AgentRuntimeAttachments } from "./terminal-stream-types-1YKRrkZB.js";
1
+ import { $ as ProxySecretReceipt, At as SandboxCreateReceipt, G as AgentProfileConfidential, L as AgentExactRunControlRef, Q as ReasoningEffort, U as AgentProfile, V as InteractionRequest, W as AgentProfileCapabilities, Z as AgentProfileValidationResult, a as TerminalStreamOptions, b as SandboxSizePreset, g as TerminalReadyInfo, i as TerminalStreamHandlers, s as TerminalStreamToken, t as TerminalAttachTimings, tt as PlanContinuation, x as AgentRuntimeAttachments } from "./terminal-stream-types-BqNv5EuG.js";
2
2
  import { t as CliAuthReference } from "./cli-auth-bundle-Wg3x2hd2.js";
3
3
  import { z } from "zod";
4
4
  //#region ../../../packages/runtime-contracts/dist/backend-types.d.ts
@@ -3667,11 +3667,13 @@ interface SdkRequestPhases {
3667
3667
  * none did.
3668
3668
  * - `sdk.refresh`: one status read. `desc` is the reason it was sent, the same
3669
3669
  * value the `x-tangle-refresh-reason` header carries.
3670
+ * - `sdk.retry`: one create attempt the SDK retries; `desc` is its wire code
3671
+ * and Retry-After, `status` its HTTP status.
3670
3672
  * - `sdk.request`: one HTTP request. `durMs` runs from the call to the end of
3671
3673
  * the body, or to the response headers when the body is not read here.
3672
3674
  */
3673
3675
  interface SdkTimingEntry {
3674
- name: "sdk.ensureRunning" | "sdk.refresh" | "sdk.request";
3676
+ name: "sdk.ensureRunning" | "sdk.refresh" | "sdk.request" | "sdk.retry";
3675
3677
  durMs: number;
3676
3678
  desc: string;
3677
3679
  /** `sdk.request` only. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/sandbox",
3
- "version": "1.0.190",
3
+ "version": "1.0.192",
4
4
  "description": "Client SDK for the Tangle Sandbox platform - build AI agent applications with dev containers",
5
5
  "type": "module",
6
6
  "sideEffects": [
@@ -155,13 +155,13 @@
155
155
  "yjs": "13.6.33",
156
156
  "@products/sandbox-test-utils": "0.0.0",
157
157
  "@repo/shared": "0.0.0",
158
- "@tangle-network/cli-agent-registry": "0.15.0",
159
158
  "@tangle-network/agent-profile-materialize": "0.27.1",
159
+ "@tangle-network/cli-agent-registry": "0.15.0",
160
160
  "@tangle-network/runtime-contracts": "0.20.0"
161
161
  },
162
162
  "tangleRelease": {
163
- "sourceSha": "f41fd1645824c17db6abeca83a9637311792837d",
164
- "mergedAt": "2026-11-02T07:52:44-08:00"
163
+ "sourceSha": "4ebbdbe755569ab872dd1b5b540bbd0688c00dea",
164
+ "mergedAt": "2026-11-02T08:29:09-08:00"
165
165
  },
166
166
  "scripts": {
167
167
  "build": "node scripts/build-dist.mjs",
@@ -1,636 +0,0 @@
1
- import "./file-transfer-DTHgLccV.js";
2
- import { t as parseSandboxRetryAfterHeader } from "./retry-after-header-Bt-XvU-x.js";
3
- //#region src/error-classes.ts
4
- /**
5
- * Base error class for all Sandbox SDK errors.
6
- */
7
- var SandboxError = class extends Error {
8
- /** HTTP status code if applicable */
9
- status;
10
- /** Error code for programmatic handling */
11
- code;
12
- /** Best-effort origin of the failing request */
13
- origin;
14
- /** Request path or endpoint when known */
15
- endpoint;
16
- /** Retry-after duration in ms when surfaced by the upstream */
17
- retryAfterMs;
18
- /** Sidecar version when the runtime emitted it */
19
- sidecarVersion;
20
- /** Sidecar image/tag/sha when the runtime emitted it */
21
- containerImage;
22
- /**
23
- * Seconds the control plane expects to need before it can serve this
24
- * request, when it published one. Today only a capacity refusal on create
25
- * carries it: the cell sizes it from the host add already in flight plus
26
- * the measured p95 host-birth time, so it is a real wait, not a backoff
27
- * hint. `retryAfterMs` paces the SDK's own retry; this is the number to
28
- * show a human or feed to a scheduler.
29
- */
30
- etaSeconds;
31
- /**
32
- * On create's top-level error, proves this call's attempts admitted no
33
- * sandbox. Absence is unknown. Earlier errors in `cause` describe only
34
- * their attempt prefix, not subsequent attempts or earlier calls using
35
- * the same idempotency key.
36
- */
37
- createFailureDisposition;
38
- /**
39
- * The cell kept its last free slots for customer creates and refused this
40
- * internal create at once. Only customers may take that room, so create()
41
- * ends on it instead of re-POSTing; a caller records it as held for
42
- * customers, not as a failure.
43
- */
44
- capacityHold;
45
- constructor(message, code, status, metadata) {
46
- super(message);
47
- this.name = "SandboxError";
48
- this.code = code;
49
- this.status = status;
50
- this.origin = metadata?.origin;
51
- this.endpoint = metadata?.endpoint;
52
- this.retryAfterMs = metadata?.retryAfterMs;
53
- this.sidecarVersion = metadata?.sidecarVersion;
54
- this.containerImage = metadata?.containerImage;
55
- this.etaSeconds = metadata?.etaSeconds;
56
- this.createFailureDisposition = metadata?.createFailureDisposition;
57
- this.capacityHold = metadata?.capacityHold;
58
- }
59
- };
60
- /**
61
- * Authentication failed or API key is invalid.
62
- */
63
- var AuthError = class extends SandboxError {
64
- constructor(message = "Authentication failed", metadata) {
65
- super(message, "AUTH_ERROR", 401, metadata);
66
- this.name = "AuthError";
67
- }
68
- };
69
- /**
70
- * The requested resource was not found.
71
- */
72
- var NotFoundError = class extends SandboxError {
73
- /** The resource type that was not found */
74
- resourceType;
75
- /** The resource ID that was not found */
76
- resourceId;
77
- constructor(resourceType, resourceId, metadata, message = `${resourceType} not found: ${resourceId}`, code = "NOT_FOUND") {
78
- super(message, code, 404, metadata);
79
- this.name = "NotFoundError";
80
- this.resourceType = resourceType;
81
- this.resourceId = resourceId;
82
- }
83
- };
84
- /**
85
- * Account quota or rate limit exceeded.
86
- */
87
- var QuotaError = class extends SandboxError {
88
- /** The type of quota that was exceeded */
89
- quotaType;
90
- /** Current usage */
91
- current;
92
- /** Maximum allowed */
93
- limit;
94
- /** Suggested retry-after duration in ms */
95
- retryAfterMs;
96
- constructor(quotaType, message, current, limit, metadata, status = 429) {
97
- super(message ?? `Quota exceeded: ${quotaType}`, "QUOTA_EXCEEDED", status, metadata);
98
- this.name = "QuotaError";
99
- this.quotaType = quotaType;
100
- this.current = current;
101
- this.limit = limit;
102
- this.retryAfterMs = metadata?.retryAfterMs;
103
- }
104
- };
105
- /** Sandbox create denials that cannot succeed while the account state stays fixed. */
106
- const NON_RETRYABLE_CREATE_QUOTA_REASONS = new Set([
107
- "CONCURRENT_LIMIT",
108
- "CREDIT_EXHAUSTED",
109
- "EGRESS_LIMIT"
110
- ]);
111
- /**
112
- * The requested capability is unavailable for the account, driver, or sandbox.
113
- */
114
- var CapabilityError = class extends SandboxError {
115
- /** Capability or feature that was rejected when known */
116
- capability;
117
- constructor(message, code = "CAPABILITY_UNSUPPORTED", status = 400, metadata, capability) {
118
- super(message, code, status, metadata);
119
- this.name = "CapabilityError";
120
- this.capability = capability;
121
- }
122
- };
123
- /**
124
- * No configured GPU provider can take the lease: none is configured, the
125
- * named one is not, or the provider refused its credential. Status 503, code
126
- * `GPU_PROVIDER_NOT_CONFIGURED`. The message names every supported provider
127
- * and the orchestrator variables it needs; `providers` carries the same.
128
- */
129
- var GpuProviderNotConfiguredError = class extends CapabilityError {
130
- providers;
131
- constructor(message, providers = [], status = 503, metadata) {
132
- super(message, "GPU_PROVIDER_NOT_CONFIGURED", status, metadata, "gpu");
133
- this.name = "GpuProviderNotConfiguredError";
134
- this.providers = providers;
135
- }
136
- };
137
- /**
138
- * A create that requires HIPAA placement was refused. `code` says why:
139
- * `COMPLIANCE_NOT_ENTITLED` (403) when the credential carries no HIPAA
140
- * entitlement, `COMPLIANCE_CELL_UNAVAILABLE` (503) when no HIPAA-designated
141
- * cell can take the create now. Either way nothing was created, and the
142
- * create was not placed in any other cell. The SDK does not retry it.
143
- */
144
- var CompliancePlacementError = class extends SandboxError {
145
- constructor(message, code, status, metadata) {
146
- super(message, code, status, metadata);
147
- this.name = "CompliancePlacementError";
148
- }
149
- };
150
- /**
151
- * A multi-resource operation failed for one or more branches.
152
- */
153
- var PartialFailureError = class extends SandboxError {
154
- /** Per-resource failures returned by the API when available */
155
- failures;
156
- /** The operation that failed after another resource was already created. */
157
- cause;
158
- /** Allocation returned before create readiness failed. */
159
- allocationId;
160
- /** Key used for the create call that returned the allocation. */
161
- idempotencyKey;
162
- /** Ownership verdict returned by that create call, if available. */
163
- createReceipt;
164
- constructor(message, code = "PARTIAL_FAILURE", status = 502, metadata, failures, cause, createFailure) {
165
- super(message, code, status, metadata);
166
- this.name = "PartialFailureError";
167
- this.failures = failures;
168
- this.cause = cause;
169
- this.allocationId = createFailure?.allocationId;
170
- this.idempotencyKey = createFailure?.idempotencyKey;
171
- this.createReceipt = createFailure?.createReceipt;
172
- }
173
- };
174
- /**
175
- * The request was invalid or malformed.
176
- */
177
- var ValidationError = class extends SandboxError {
178
- /** Field-level validation errors */
179
- fields;
180
- constructor(message, fields, metadata, code = "VALIDATION_ERROR") {
181
- super(message, code, 400, metadata);
182
- this.name = "ValidationError";
183
- this.fields = fields;
184
- }
185
- };
186
- /**
187
- * A profile file mount the sandbox refuses; a retry with the same profile gets
188
- * the same refusal. `PROFILE_FILE_MOUNT_OUTSIDE_ROOTS` (422): an absolute path
189
- * outside `SANDBOX_FILE_API_ABSOLUTE_ROOTS`, refused before any write.
190
- * `PROFILE_FILE_CONFLICT` (409): the file changed both in the sandbox and in
191
- * the profile since its last mount, so a turn refuses to replace it.
192
- */
193
- var ProfileFileMountPathError = class extends SandboxError {
194
- /** The refused mount path, exactly as the profile gave it. */
195
- path;
196
- constructor(path, message, code, metadata, status = 422) {
197
- super(message, code, status, metadata);
198
- this.name = "ProfileFileMountPathError";
199
- this.path = path;
200
- }
201
- };
202
- /**
203
- * The sandbox is not in a valid state for the requested operation.
204
- */
205
- var StateError = class extends SandboxError {
206
- /** Current state of the sandbox */
207
- currentState;
208
- /** Required state for the operation */
209
- requiredState;
210
- constructor(message, currentState, requiredState, metadata, code = "INVALID_STATE") {
211
- super(message, code, 409, metadata);
212
- this.name = "StateError";
213
- this.currentState = currentState;
214
- this.requiredState = requiredState;
215
- }
216
- };
217
- /**
218
- * The sandbox lifecycle is running, but its consumer-facing runtime edge is
219
- * still attaching or has failed to attach.
220
- */
221
- var EdgeNotReadyError = class extends SandboxError {
222
- /** Current public edge state. */
223
- edgeStatus;
224
- constructor(message, edgeStatus, metadata) {
225
- super(message, "EDGE_NOT_READY", edgeStatus === "failed" ? 502 : 409, metadata);
226
- this.name = "EdgeNotReadyError";
227
- this.edgeStatus = edgeStatus;
228
- }
229
- };
230
- var FileWriteConflictError = class extends SandboxError {
231
- expectedHash;
232
- constructor(message, path, expectedHash, currentHash, currentMtime, metadata) {
233
- super(message, "FILE_WRITE_CONFLICT", 409, metadata);
234
- this.path = path;
235
- this.currentHash = currentHash;
236
- this.currentMtime = currentMtime;
237
- this.name = "FileWriteConflictError";
238
- if (expectedHash !== void 0) this.expectedHash = expectedHash;
239
- }
240
- };
241
- /**
242
- * The Platform key funding the request has no lifetime budget left.
243
- *
244
- * A budgeted key funds any number of sandboxes until its budget is spent;
245
- * then every create, resume, and model credential it funds is refused with
246
- * this error. The refusal is decided: retrying cannot succeed until the
247
- * budget is raised or another key is used, so the SDK never retries it.
248
- */
249
- var KeyBudgetExhaustedError = class extends SandboxError {
250
- /**
251
- * The key the refusal names: the budgeted key with nothing left when
252
- * Platform refused a delegation, or the presented key when authentication
253
- * refused it. Absent when the server named none.
254
- */
255
- keyId;
256
- /** That key's lifetime budget, in USD, when Platform reported it. */
257
- budgetUsd;
258
- /** What that key has spent, in USD. */
259
- spentUsd;
260
- /** What that key has reserved for budgeted children, in USD. */
261
- reservedUsd;
262
- constructor(message, details = {}, metadata) {
263
- super(message, "KEY_BUDGET_EXHAUSTED", 402, metadata);
264
- this.name = "KeyBudgetExhaustedError";
265
- this.keyId = details.keyId;
266
- this.budgetUsd = details.budgetUsd;
267
- this.spentUsd = details.spentUsd;
268
- this.reservedUsd = details.reservedUsd;
269
- }
270
- };
271
- var EgressProxyRecoveryError = class extends SandboxError {
272
- phase;
273
- constructor(message, metadata) {
274
- super(message, "EGRESS_PROXY_RECOVERY_REQUIRED", 409, metadata);
275
- this.name = "EgressProxyRecoveryError";
276
- this.phase = "egress_proxy_recovery";
277
- }
278
- };
279
- /**
280
- * Resume must build a new runtime, and that runtime needs public env values
281
- * the platform does not store at rest: a per-run coordination or capability
282
- * token, or a secret passed at create. Resume again with each key in
283
- * `missingEnvKeys` in `ResumeOptions.env`.
284
- */
285
- var ResumeEnvRequiredError = class extends SandboxError {
286
- /** The env keys the next resume must carry. */
287
- missingEnvKeys;
288
- constructor(message, missingEnvKeys, metadata) {
289
- super(message, "RESUME_ENV_REQUIRED", 409, metadata);
290
- this.name = "ResumeEnvRequiredError";
291
- this.missingEnvKeys = missingEnvKeys;
292
- }
293
- };
294
- /**
295
- * A branch asked for more children than the parent's host has memory for.
296
- * Children can only live on the parent's host (their clone is local to its
297
- * volume), so no other host can take the rest. `maxChildren` is how many
298
- * children that host admits now; branch that many or fewer, or wait for the
299
- * host to free memory. Nothing was created and nothing is held.
300
- *
301
- * A retry under the same idempotency key replays this refusal unchanged,
302
- * `maxChildren` included, so the count is the host's room when the key was
303
- * first used. To branch fewer children, use a new key.
304
- */
305
- var BranchFanoutExceedsHostError = class extends SandboxError {
306
- /** Children the parent's host admitted when it refused (0 when none). */
307
- maxChildren;
308
- /** The fan-out width this request asked for. */
309
- requestedChildren;
310
- constructor(message, counts, metadata) {
311
- super(message, "BRANCH_FANOUT_EXCEEDS_HOST", 409, metadata);
312
- this.name = "BranchFanoutExceedsHostError";
313
- this.maxChildren = counts.maxChildren;
314
- this.requestedChildren = counts.requestedChildren;
315
- }
316
- };
317
- /**
318
- * The request timed out.
319
- */
320
- var TimeoutError = class extends SandboxError {
321
- /** The operation's configured budget, in milliseconds. NOT how long it ran. */
322
- timeoutMs;
323
- /**
324
- * How long the operation actually ran before this error, in milliseconds,
325
- * when the thrower measured it.
326
- *
327
- * `create()` can end before its budget: when a server-supplied `Retry-After`
328
- * outlasts the remaining budget, no further attempt can follow that sleep,
329
- * so the create ends there rather than idling. Reading `timeoutMs` as the
330
- * duration would record a two-minute timeout for a three-second refusal.
331
- * Absent means the thrower did not measure it; it never means `timeoutMs`.
332
- */
333
- elapsedMs;
334
- /**
335
- * The last typed failure the operation had already received when the
336
- * deadline fired, when there was one.
337
- *
338
- * An operation that spends its budget across several attempts (create's
339
- * bounded POST retry) usually learns the server's failure class on an
340
- * earlier attempt — `CONTAINER_START_FAILED`, `PROVISIONING_ERROR`,
341
- * `RATE_LIMIT_EXCEEDED`. Without this field that class dies at the
342
- * deadline and the caller is left with a timeout that names no cause,
343
- * which is the last discard in a chain built specifically to deliver it.
344
- */
345
- cause;
346
- constructor(timeoutMs, message, metadata, cause) {
347
- super(message ?? `Request timed out after ${timeoutMs}ms`, "TIMEOUT", 408, metadata);
348
- this.name = "TimeoutError";
349
- this.timeoutMs = timeoutMs;
350
- this.elapsedMs = metadata?.elapsedMs;
351
- this.cause = cause;
352
- }
353
- };
354
- /**
355
- * A network or connection error occurred.
356
- */
357
- var NetworkError = class extends SandboxError {
358
- /** The underlying error */
359
- cause;
360
- constructor(message, causeOrMetadata, metadata) {
361
- const cause = causeOrMetadata instanceof Error ? causeOrMetadata : void 0;
362
- const resolvedMetadata = causeOrMetadata instanceof Error ? metadata : causeOrMetadata ?? metadata;
363
- super(message, "NETWORK_ERROR", void 0, resolvedMetadata);
364
- this.name = "NetworkError";
365
- this.cause = cause;
366
- }
367
- };
368
- /**
369
- * The stream of an admitted execution ended without its terminal event, and
370
- * the SDK could not rejoin it. The execution's outcome is UNKNOWN: it may
371
- * still be running, or it may have finished while no reader was attached.
372
- * This is never a failure verdict. Rejoin later with `streamPrompt(message,
373
- * { executionId, lastEventId, sessionId })`, or read the session status.
374
- */
375
- var StreamInterruptedError = class extends SandboxError {
376
- executionId;
377
- sessionId;
378
- /** The last event id delivered to the caller; replay resumes after it. */
379
- lastEventId;
380
- reason;
381
- /** Last HTTP status the replay endpoint answered, when it answered. */
382
- lastReplayStatus;
383
- /** Last execution status the runtime reported, when it reported one. */
384
- lastExecutionStatus;
385
- cause;
386
- constructor(details) {
387
- super(details.message, "STREAM_INTERRUPTED", void 0, {
388
- origin: "runtime",
389
- endpoint: `/agents/run/${details.executionId}/events`
390
- });
391
- this.name = "StreamInterruptedError";
392
- this.executionId = details.executionId;
393
- this.sessionId = details.sessionId;
394
- this.lastEventId = details.lastEventId;
395
- this.reason = details.reason;
396
- this.lastReplayStatus = details.lastReplayStatus;
397
- this.lastExecutionStatus = details.lastExecutionStatus;
398
- this.cause = details.cause;
399
- }
400
- };
401
- /**
402
- * The server returned an unexpected error.
403
- */
404
- var ServerError = class extends SandboxError {
405
- constructor(message, status = 500, metadata, code = "SERVER_ERROR") {
406
- super(message, code, status, metadata);
407
- this.name = "ServerError";
408
- }
409
- };
410
- //#endregion
411
- //#region src/errors.ts
412
- /**
413
- * Sandbox SDK Errors
414
- *
415
- * Error classes for the Sandbox client SDK.
416
- */
417
- function quotaTypeFromResponse(data, reason) {
418
- const normalizedReason = reason?.trim().toUpperCase();
419
- if (normalizedReason && NON_RETRYABLE_CREATE_QUOTA_REASONS.has(normalizedReason)) return normalizedReason;
420
- if (typeof data.quotaType === "string" && data.quotaType.trim()) return data.quotaType;
421
- return "rate_limit";
422
- }
423
- function readGpuProviderRequirements(data) {
424
- return (Array.isArray(data.providers) ? data.providers : []).flatMap((entry) => {
425
- if (!isFailureDetail(entry)) return [];
426
- const provider = asString(entry.provider);
427
- const state = asString(entry.state);
428
- const envVars = Array.isArray(entry.envVars) ? entry.envVars : [];
429
- if (!provider || !state) return [];
430
- return [{
431
- provider,
432
- state,
433
- envVars: envVars.filter((name) => typeof name === "string")
434
- }];
435
- });
436
- }
437
- function parseRetryAfterMs(rawValue, data) {
438
- if (typeof data.retryAfterMs === "number" && Number.isFinite(data.retryAfterMs)) return Math.max(0, data.retryAfterMs);
439
- return parseSandboxRetryAfterHeader(rawValue);
440
- }
441
- /**
442
- * The server's published wait, in seconds. Only a positive finite number is
443
- * a wait; anything else is absent. Never derived from `Retry-After` — that
444
- * header is a pacing hint every refusal carries, while `etaSeconds` is a
445
- * measurement the cell only publishes when it has one.
446
- */
447
- function parseEtaSeconds(data) {
448
- const raw = data.etaSeconds;
449
- if (typeof raw !== "number" || !Number.isFinite(raw) || raw <= 0) return;
450
- return raw;
451
- }
452
- /**
453
- * What a capacity refusal publishes: the cell's measured wait, and whether its
454
- * customer floor refused an internal create (SandboxError.capacityHold).
455
- */
456
- function capacityRefusalMetadata(data) {
457
- return {
458
- etaSeconds: parseEtaSeconds(data),
459
- capacityHold: data.code === "CAPACITY_EXHAUSTED" && data.reason === "customer_floor" ? "customer_floor" : void 0
460
- };
461
- }
462
- function inferOrigin(headers, context) {
463
- const derivedPath = context?.path ?? headers?.get("x-tangle-request-path") ?? void 0;
464
- if (!headers) return context?.path ? "sandbox-api" : void 0;
465
- if (headers.has("x-sidecar-version") || headers.has("x-sidecar-image") || headers.has("x-sidecar-image-tag")) return "sidecar";
466
- if (headers.has("x-orchestrator-version")) return "control-plane";
467
- if (derivedPath?.startsWith("/v1/")) return "sandbox-api";
468
- if (derivedPath) {
469
- if (derivedPath.startsWith("/projects") || derivedPath.startsWith("/sidecars") || derivedPath.startsWith("/instances")) return "control-plane";
470
- return "runtime";
471
- }
472
- return "unknown";
473
- }
474
- function isQuotaCode(code) {
475
- return code === "QUOTA_EXCEEDED" || code?.endsWith("_QUOTA_EXCEEDED") === true;
476
- }
477
- function isCapabilityCode(code) {
478
- return code === "CAPABILITY_NOT_ENABLED" || code === "CAPABILITY_UNSUPPORTED" || code === "UNSUPPORTED_CAPABILITY" || code === "FLEET_SHARED_WORKSPACE_UNSUPPORTED" || code === "SHARED_WORKSPACE_UNSUPPORTED";
479
- }
480
- function isPartialFailureCode(code) {
481
- return code === "PARTIAL_FAILURE" || code === "FLEET_PARTIAL_FAILURE" || code === "FLEET_DISPATCH_PARTIAL_FAILURE" || code === "FLEET_DEPROVISION_FAILED";
482
- }
483
- function asString(value) {
484
- return typeof value === "string" && value.trim().length > 0 ? value : void 0;
485
- }
486
- const ERROR_CODE_PATTERN = /^[A-Z][A-Z0-9_]{0,63}$/;
487
- function asErrorCode(value) {
488
- return typeof value === "string" && ERROR_CODE_PATTERN.test(value) ? value : void 0;
489
- }
490
- function isFailureDetail(value) {
491
- return typeof value === "object" && value !== null && !Array.isArray(value);
492
- }
493
- function finiteNumber(value) {
494
- return typeof value === "number" && Number.isFinite(value) ? value : void 0;
495
- }
496
- function readKeyBudgetDetails(value) {
497
- if (!isFailureDetail(value)) return {};
498
- return {
499
- keyId: asString(value.keyId),
500
- budgetUsd: finiteNumber(value.budgetUsd),
501
- spentUsd: finiteNumber(value.spentUsd),
502
- reservedUsd: finiteNumber(value.reservedUsd)
503
- };
504
- }
505
- function readCapability(data, errorObj) {
506
- const nested = typeof errorObj === "object" && errorObj !== null ? asString(errorObj.capability) : void 0;
507
- return asString(data.capability) ?? nested;
508
- }
509
- function readFileWriteConflictDetails(errorObj) {
510
- if (typeof errorObj !== "object" || errorObj === null) return void 0;
511
- const path = asString(errorObj.path);
512
- const expectedHash = errorObj.expectedHash === void 0 ? void 0 : asString(errorObj.expectedHash);
513
- const currentHash = errorObj.currentHash === null ? null : asString(errorObj.currentHash);
514
- const currentMtime = errorObj.currentMtime === null && Object.hasOwn(errorObj, "currentMtime") ? null : typeof errorObj.currentMtime === "number" && Number.isFinite(errorObj.currentMtime) ? errorObj.currentMtime : void 0;
515
- if (path === void 0 || errorObj.expectedHash !== void 0 && expectedHash === void 0 || currentHash === void 0 || currentMtime === void 0) return;
516
- return {
517
- path,
518
- expectedHash,
519
- currentHash,
520
- currentMtime
521
- };
522
- }
523
- function readFailures(data, errorObj) {
524
- if (Array.isArray(data.failures)) return data.failures.filter(isFailureDetail);
525
- if (Array.isArray(data.results)) {
526
- const failures = data.results.filter((result) => typeof result === "object" && result !== null && result.ok === false);
527
- if (failures.length > 0) return failures.filter(isFailureDetail);
528
- }
529
- if (typeof errorObj === "object" && errorObj !== null && Array.isArray(errorObj.failures)) return errorObj.failures.filter(isFailureDetail);
530
- }
531
- /**
532
- * Parse an error response from the API.
533
- * @param status - HTTP status code
534
- * @param body - Response body text
535
- * @param context - Optional request context for better error messages
536
- */
537
- function parseErrorResponse(status, body, context, headers) {
538
- let data;
539
- try {
540
- data = JSON.parse(body);
541
- } catch {
542
- data = { message: body };
543
- }
544
- const errorObj = data.error;
545
- const nestedMessage = typeof errorObj === "object" && errorObj !== null ? errorObj.message : void 0;
546
- const nestedCode = typeof errorObj === "object" && errorObj !== null ? typeof errorObj.code === "string" ? asErrorCode(errorObj.code) : void 0 : void 0;
547
- const baseMessage = data.message || nestedMessage || (typeof errorObj === "string" ? errorObj : void 0) || body || "Unknown error";
548
- const details = typeof data.details === "string" && data.details.trim().length > 0 ? data.details.trim() : void 0;
549
- const shouldAppendDetails = !!details && details !== baseMessage && (baseMessage === "Unknown error" || /^failed\b/i.test(baseMessage) || /^provision failed\b/i.test(baseMessage) || /^deprovision failed\b/i.test(baseMessage));
550
- const rawReason = typeof data.reason === "string" ? data.reason : typeof errorObj === "object" && errorObj !== null ? errorObj.reason : void 0;
551
- const reason = typeof rawReason === "string" && rawReason.trim().length > 0 ? rawReason.trim() : void 0;
552
- const code = (typeof data.code === "string" ? asErrorCode(data.code) : void 0) ?? nestedCode;
553
- const rawLog = typeof errorObj === "object" && errorObj !== null ? errorObj.log : void 0;
554
- const logTail = typeof rawLog === "string" && rawLog.trim().length > 0 ? rawLog.trim() : void 0;
555
- const prefix = context?.method || context?.path ? `${context.method ?? "REQUEST"} ${context.path ?? ""}: ` : "";
556
- const composedMessage = shouldAppendDetails ? `${baseMessage}: ${details}` : baseMessage;
557
- const messageWithReason = `${prefix}${reason && !composedMessage.includes(reason) ? `${composedMessage}: ${reason}` : composedMessage}`;
558
- const message = logTail && !messageWithReason.includes(logTail) ? `${messageWithReason}\n${logTail}` : messageWithReason;
559
- const metadata = {
560
- origin: inferOrigin(headers, context),
561
- endpoint: context?.path ?? headers?.get("x-tangle-request-path") ?? void 0,
562
- retryAfterMs: parseRetryAfterMs(headers?.get("retry-after") ?? void 0, data),
563
- ...capacityRefusalMetadata(data),
564
- sidecarVersion: headers?.get("x-sidecar-version") ?? void 0,
565
- containerImage: headers?.get("x-sidecar-image") ?? headers?.get("x-sidecar-image-tag") ?? void 0,
566
- createFailureDisposition: context?.allPreviousCreateAttemptsRefused === true && (context.method ?? headers?.get("x-tangle-request-method")) === "POST" && (context.path ?? headers?.get("x-tangle-request-path")) === "/v1/sandboxes" && status === 429 && (code === "RATE_LIMIT_EXCEEDED" || code === "QUOTA_EXCEEDED" || code === "PLATFORM_RATE_LIMITED") ? "not-admitted" : void 0
567
- };
568
- if (isQuotaCode(code)) return new QuotaError(quotaTypeFromResponse(data, reason), message, data.current, data.limit, metadata, status);
569
- if (code === "GPU_PROVIDER_NOT_CONFIGURED" || code === "GPU_PROVIDERS_NOT_CONFIGURED") return new GpuProviderNotConfiguredError(message, readGpuProviderRequirements(data), status, metadata);
570
- if (isCapabilityCode(code)) return new CapabilityError(message, code, status, metadata, readCapability(data, errorObj));
571
- if (isPartialFailureCode(code)) return new PartialFailureError(message, code, status, metadata, readFailures(data, errorObj));
572
- if (code === "COMPLIANCE_NOT_ENTITLED" || code === "COMPLIANCE_CELL_UNAVAILABLE") return new CompliancePlacementError(message, code, status, metadata);
573
- if (code === "EGRESS_PROXY_RECOVERY_REQUIRED") return new EgressProxyRecoveryError(message, metadata);
574
- if (code === "PROFILE_FILE_MOUNT_OUTSIDE_ROOTS" && typeof data.path === "string") return new ProfileFileMountPathError(data.path, message, code, metadata);
575
- if (code === "RESUME_ENV_REQUIRED") {
576
- const keys = data.missingEnvKeys;
577
- return new ResumeEnvRequiredError(message, Array.isArray(keys) ? keys.filter((key) => typeof key === "string") : [], metadata);
578
- }
579
- if (code === "BRANCH_FANOUT_EXCEEDS_HOST") {
580
- const count = (raw) => typeof raw === "number" && Number.isSafeInteger(raw) && raw >= 0 ? raw : void 0;
581
- return new BranchFanoutExceedsHostError(message, {
582
- maxChildren: count(data.maxChildren),
583
- requestedChildren: count(data.requestedChildren)
584
- }, metadata);
585
- }
586
- if (code === "KEY_BUDGET_EXHAUSTED") return new KeyBudgetExhaustedError(message, readKeyBudgetDetails(data.details), metadata);
587
- if (code === "FILE_WRITE_CONFLICT") {
588
- const conflict = readFileWriteConflictDetails(errorObj);
589
- if (!conflict) return new ServerError(`${message}: malformed FILE_WRITE_CONFLICT response`, 502, metadata, "INVALID_ERROR_RESPONSE");
590
- return new FileWriteConflictError(message, conflict.path, conflict.expectedHash, conflict.currentHash, conflict.currentMtime, metadata);
591
- }
592
- switch (status) {
593
- case 400: return new ValidationError(message, data.fields, metadata, code);
594
- case 401: return new AuthError(message, metadata);
595
- case 404: return new NotFoundError(data.resourceType || "Resource", data.resourceId || "unknown", metadata, message, code);
596
- case 408: return new TimeoutError(data.timeoutMs || 3e4, message, metadata);
597
- case 409: return new StateError(message, data.currentState || "unknown", data.requiredState, metadata, code);
598
- case 429: return new QuotaError(quotaTypeFromResponse(data, reason), message, data.current, data.limit, metadata);
599
- case 501: return new SandboxError(message, code || "NOT_IMPLEMENTED", status, metadata);
600
- default:
601
- if (status >= 500) return new ServerError(message, status, metadata, code);
602
- return new SandboxError(message, code || "UNKNOWN_ERROR", status, metadata);
603
- }
604
- }
605
- /** Read a failed HTTP response without changing its typed error or retry metadata. */
606
- async function parseResponseError(response) {
607
- const body = await response.text();
608
- return parseErrorResponse(response.status, body, void 0, response.headers);
609
- }
610
- /** Read a checked response once; callers interpret its JSON wire value. */
611
- function readResponseJson(response) {
612
- if (response.ok) return response.json();
613
- return parseResponseError(response).then((error) => {
614
- throw error;
615
- });
616
- }
617
- /** A protocol `error` control frame or a transport failure. */
618
- var TerminalStreamError = class extends Error {
619
- /** Protocol error code (e.g. `INIT_FAILED`) or `TRANSPORT` for socket faults. */
620
- code;
621
- /**
622
- * True when the socket never reached OPEN: the upgrade was refused (a
623
- * WebSocket client cannot read the HTTP status, so a 401 and a network drop
624
- * look alike) or the runtime rejected the dial's options. No PTY work had
625
- * started on the client's side of that dial.
626
- */
627
- beforeOpen;
628
- constructor(message, code, options = {}) {
629
- super(message);
630
- this.name = "TerminalStreamError";
631
- this.code = code;
632
- this.beforeOpen = options.beforeOpen === true;
633
- }
634
- };
635
- //#endregion
636
- export { StateError as C, ValidationError as E, ServerError as S, TimeoutError as T, PartialFailureError as _, AuthError as a, ResumeEnvRequiredError as b, CompliancePlacementError as c, FileWriteConflictError as d, GpuProviderNotConfiguredError as f, NotFoundError as g, NetworkError as h, readResponseJson as i, EdgeNotReadyError as l, NON_RETRYABLE_CREATE_QUOTA_REASONS as m, parseErrorResponse as n, BranchFanoutExceedsHostError as o, KeyBudgetExhaustedError as p, parseResponseError as r, CapabilityError as s, TerminalStreamError as t, EgressProxyRecoveryError as u, ProfileFileMountPathError as v, StreamInterruptedError as w, SandboxError as x, QuotaError as y };