@tangle-network/sandbox 0.36.3 → 0.36.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  import { f as assertCurrentBackendType } from "../runtime-api-ClXF8k_q.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-4KbDo0dU.js";
4
- import { t as SandboxInstance } from "../sandbox-DsnIsKUL.js";
3
+ import { n as Sandbox } from "../client-DG0Pwadv.js";
4
+ import { t as SandboxInstance } from "../sandbox--QhO618M.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
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-ClXF8k_q.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 { E as normalizeConnection, O as exportTraceBundle, b as requestInteractiveSessionToken, i as normalizeStartupDiagnostics, n as createSandboxInstanceFromResponse, r as normalizeSandboxCreateReceipt } from "./sandbox-DsnIsKUL.js";
4
+ import { E as normalizeConnection, O as exportTraceBundle, b as requestInteractiveSessionToken, i as normalizeStartupDiagnostics, n as createSandboxInstanceFromResponse, r as normalizeSandboxCreateReceipt } from "./sandbox--QhO618M.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 parseBackendRegistryResponse, f as backendRegistryCapabilitiesSchema, g as isBackendRegistryInteractionKind, h as backendRegistryResponseSchema, m as backendRegistryInteractionKindSchema, n as Sandbox, p as backendRegistryEntrySchema, v as parseBackendRegistryResponseBody } from "./client-4KbDo0dU.js";
3
- import { a as WorkspaceImages, t as SandboxInstance } from "./sandbox-DsnIsKUL.js";
2
+ import { _ as parseBackendRegistryResponse, f as backendRegistryCapabilitiesSchema, g as isBackendRegistryInteractionKind, h as backendRegistryResponseSchema, m as backendRegistryInteractionKindSchema, n as Sandbox, p as backendRegistryEntrySchema, v as parseBackendRegistryResponseBody } from "./client-DG0Pwadv.js";
3
+ import { a as WorkspaceImages, t as SandboxInstance } from "./sandbox--QhO618M.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
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-ClXF8k_q.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 parseBackendRegistryResponse, a as splitInlineProfileSkills, c as SandboxFleetClient, d as validateBatchRunRequest, f as backendRegistryCapabilitiesSchema, g as isBackendRegistryInteractionKind, h as backendRegistryResponseSchema, i as splitInlineProfileFileMounts, l as runtimeWorkspaceCwdSchema, m as backendRegistryInteractionKindSchema, n as Sandbox, o as validateDeferredProfileFileMounts, p as backendRegistryEntrySchema, r as materializeProfileFileMounts, s as SandboxFleet, t as IntelligenceClient, u as createBatchResultAccumulator, v as parseBackendRegistryResponseBody } from "./client-4KbDo0dU.js";
3
+ import { _ as parseBackendRegistryResponse, a as splitInlineProfileSkills, c as SandboxFleetClient, d as validateBatchRunRequest, f as backendRegistryCapabilitiesSchema, g as isBackendRegistryInteractionKind, h as backendRegistryResponseSchema, i as splitInlineProfileFileMounts, l as runtimeWorkspaceCwdSchema, m as backendRegistryInteractionKindSchema, n as Sandbox, o as validateDeferredProfileFileMounts, p as backendRegistryEntrySchema, r as materializeProfileFileMounts, s as SandboxFleet, t as IntelligenceClient, u as createBatchResultAccumulator, v as parseBackendRegistryResponseBody } from "./client-DG0Pwadv.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-Dv0gbFMu.js";
5
- import { A as toOtelJson, C as collectAgentResponseText, D as buildTraceExportPayload, O as exportTraceBundle, S as collectAgentFinalMessageText, T as isToolBearingEvent, _ as TerminalStream, a as WorkspaceImages, c as SandboxTaskSession, d as agentInteractiveSessionPromptRequestDigest, f as InteractiveTerminalFrameLog, g as InteractiveSessionController, h as BrowserInteractiveSessionController, k as otelTraceIdForTangleTrace, l as SandboxSession, m as createInteractiveTerminalSession, o as GPU_LEASE_PROVIDER_NAMES, p as createInteractiveTerminalCapture, s as MAX_EGRESS_DENIALS_LIMIT, t as SandboxInstance, u as InteractiveSessionHandle, v as TerminalStreamError, w as getSandboxEventText, x as applySandboxEventText, y as TERMINAL_WS_ECHO_SUBPROTOCOL } from "./sandbox-DsnIsKUL.js";
5
+ import { A as toOtelJson, C as collectAgentResponseText, D as buildTraceExportPayload, O as exportTraceBundle, S as collectAgentFinalMessageText, T as isToolBearingEvent, _ as TerminalStream, a as WorkspaceImages, c as SandboxTaskSession, d as agentInteractiveSessionPromptRequestDigest, f as InteractiveTerminalFrameLog, g as InteractiveSessionController, h as BrowserInteractiveSessionController, k as otelTraceIdForTangleTrace, l as SandboxSession, m as createInteractiveTerminalSession, o as GPU_LEASE_PROVIDER_NAMES, p as createInteractiveTerminalCapture, s as MAX_EGRESS_DENIALS_LIMIT, t as SandboxInstance, u as InteractiveSessionHandle, v as TerminalStreamError, w as getSandboxEventText, x as applySandboxEventText, y as TERMINAL_WS_ECHO_SUBPROTOCOL } from "./sandbox--QhO618M.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-BbYJI8g_.js";
7
+ import { t as TangleSandboxClient } from "./tangle-CaYKcNaS.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
@@ -3455,6 +3455,65 @@ const delayUntilAborted = (ms, signal) => new Promise((resolve, reject) => {
3455
3455
  }
3456
3456
  signal?.addEventListener("abort", onAbort, { once: true });
3457
3457
  });
3458
+ /**
3459
+ * The platform's typed refusal when one sandbox already has a lifecycle
3460
+ * operation in flight: HTTP 409 from `withSandboxLifecycleClaim`
3461
+ * (products/sandbox/api/src/routes/sandbox-lifecycle-claim.ts).
3462
+ */
3463
+ const LIFECYCLE_CONFLICT_CODE = "SANDBOX_LIFECYCLE_IN_PROGRESS";
3464
+ /**
3465
+ * How long a lifecycle call re-attempts that refusal before it surfaces.
3466
+ *
3467
+ * MEASURED MOTIVE. `resume`, `stop` and `delete` are the only three routes the
3468
+ * API guards, and they share one lease per sandbox, `lifecycle-<id>`. That
3469
+ * lease outlives the response of the call that took it: the delete handler
3470
+ * registers deferred key-revoke and meta-delete work through
3471
+ * `deferSandboxLifecycleWork`, and the release is chained after that work
3472
+ * through `executionCtx.waitUntil`. So a second lifecycle call landing inside
3473
+ * that window is refused even though nothing is wrong and the caller only has
3474
+ * to wait. The platform's own workflow smoke already hand-rolls this retry and
3475
+ * says why (scripts/platform-workflow-deploy-smoke.mjs: "the worker can still
3476
+ * hold the sandbox lifecycle claim while its final action cleanup completes,
3477
+ * so sandbox-api returns a typed 409 for a short, valid window").
3478
+ *
3479
+ * The number: 2 of 2 provider-seam runs on 2026-09-01 (tangle-network/agent-sdk#280)
3480
+ * lost a completed agent turn to this refusal. `agent-runtime`'s provider
3481
+ * executor destroys one environment twice — once when the stream settles and
3482
+ * once from `teardown()` — and the second DELETE was refused, which discarded
3483
+ * the first one's result. Nothing about the sandbox document tells a client the
3484
+ * lease is held (the response schema is `.strict()` and carries no lifecycle
3485
+ * field), so a status poll cannot replace this retry.
3486
+ *
3487
+ * The ceiling is short on purpose. The lease TTL is 360 s, but the window this
3488
+ * closes is the deferred-cleanup tail of an operation that already answered;
3489
+ * a conflict that outlives ~11 s is a genuinely concurrent operation and
3490
+ * belongs to the caller, not to a longer sleep here.
3491
+ */
3492
+ const LIFECYCLE_CONFLICT_MAX_ATTEMPTS = 6;
3493
+ const LIFECYCLE_CONFLICT_BASE_DELAY_MS = 500;
3494
+ const LIFECYCLE_CONFLICT_MAX_DELAY_MS = 4e3;
3495
+ function isLifecycleConflict(cause) {
3496
+ return cause instanceof SandboxError && cause.status === 409 && cause.code === LIFECYCLE_CONFLICT_CODE;
3497
+ }
3498
+ function lifecycleConflictDelayMs(cause, failedAttempt) {
3499
+ if (cause instanceof SandboxError && cause.retryAfterMs !== void 0) return cause.retryAfterMs;
3500
+ return Math.min(LIFECYCLE_CONFLICT_BASE_DELAY_MS * 2 ** Math.max(0, failedAttempt - 1), LIFECYCLE_CONFLICT_MAX_DELAY_MS);
3501
+ }
3502
+ /**
3503
+ * Run one lifecycle mutation, re-attempting only the platform's typed
3504
+ * "already in progress" refusal.
3505
+ *
3506
+ * Every other failure keeps its identity and its stack: this widens no other
3507
+ * error class, and a caller abort ends the wait immediately.
3508
+ */
3509
+ async function withLifecycleConflictRetry(run, options) {
3510
+ for (let attempt = 1;; attempt += 1) try {
3511
+ return await run();
3512
+ } catch (error) {
3513
+ if (!isLifecycleConflict(error) || attempt >= LIFECYCLE_CONFLICT_MAX_ATTEMPTS || options?.signal?.aborted) throw error;
3514
+ await delayUntilAborted(lifecycleConflictDelayMs(error, attempt), options?.signal);
3515
+ }
3516
+ }
3458
3517
  const SANDBOX_STATUS_FRESHNESS_MS = 1e3;
3459
3518
  const sandboxStatusObservedAt = /* @__PURE__ */ new WeakMap();
3460
3519
  const directRuntimeInstances = /* @__PURE__ */ new WeakSet();
@@ -6820,11 +6879,14 @@ var SandboxInstance = class SandboxInstance {
6820
6879
  * returns it (replacing the create breakdown).
6821
6880
  */
6822
6881
  async stop() {
6823
- const response = await this.client.fetch(`/v1/sandboxes/${this.id}/stop`, { method: "POST" });
6824
- if (!response.ok) {
6825
- const body = await response.text();
6826
- throw parseErrorResponse(response.status, body, void 0, response.headers);
6827
- }
6882
+ const response = await withLifecycleConflictRetry(async () => {
6883
+ const attempt = await this.client.fetch(`/v1/sandboxes/${this.id}/stop`, { method: "POST" });
6884
+ if (!attempt.ok) {
6885
+ const body = await attempt.text();
6886
+ throw parseErrorResponse(attempt.status, body, void 0, attempt.headers);
6887
+ }
6888
+ return attempt;
6889
+ });
6828
6890
  const data = await this.readLifecycleResponse(response);
6829
6891
  if (!this.applyLifecycleResponse(data)) await this.refresh();
6830
6892
  const diagnostics = data ? normalizeStartupDiagnostics(data.startupDiagnostics) : null;
@@ -6837,14 +6899,17 @@ var SandboxInstance = class SandboxInstance {
6837
6899
  if (options.timeoutMs !== void 0 && (!Number.isFinite(options.timeoutMs) || options.timeoutMs <= 0)) throw new ValidationError("resume timeoutMs must be a positive number");
6838
6900
  const timeoutSignal = options.timeoutMs ? AbortSignal.timeout(options.timeoutMs) : void 0;
6839
6901
  const signal = timeoutSignal ? options.signal ? combineAbortSignals([options.signal, timeoutSignal]) : timeoutSignal : options.signal;
6840
- const response = await this.client.fetch(`/v1/sandboxes/${this.id}/resume`, {
6841
- method: "POST",
6842
- ...signal ? { signal } : {}
6843
- }, usableTimeoutMs(options.timeoutMs));
6844
- if (!response.ok) {
6845
- const body = await response.text();
6846
- throw parseErrorResponse(response.status, body, void 0, response.headers);
6847
- }
6902
+ const response = await withLifecycleConflictRetry(async () => {
6903
+ const attempt = await this.client.fetch(`/v1/sandboxes/${this.id}/resume`, {
6904
+ method: "POST",
6905
+ ...signal ? { signal } : {}
6906
+ }, usableTimeoutMs(options.timeoutMs));
6907
+ if (!attempt.ok) {
6908
+ const body = await attempt.text();
6909
+ throw parseErrorResponse(attempt.status, body, void 0, attempt.headers);
6910
+ }
6911
+ return attempt;
6912
+ }, signal ? { signal } : {});
6848
6913
  const data = await this.readLifecycleResponse(response);
6849
6914
  if (!this.applyLifecycleResponse(data)) await this.refresh();
6850
6915
  const diagnostics = data ? normalizeStartupDiagnostics(data.startupDiagnostics) : null;
@@ -6863,10 +6928,26 @@ var SandboxInstance = class SandboxInstance {
6863
6928
  * now-gone sandbox.
6864
6929
  */
6865
6930
  async delete() {
6866
- const response = await this.client.fetch(`/v1/sandboxes/${this.id}`, { method: "DELETE" });
6867
- if (!response.ok) {
6868
- const body = await response.text();
6869
- throw parseErrorResponse(response.status, body, void 0, response.headers);
6931
+ let sawLifecycleConflict = false;
6932
+ let response;
6933
+ try {
6934
+ response = await withLifecycleConflictRetry(async () => {
6935
+ const attempt = await this.client.fetch(`/v1/sandboxes/${this.id}`, { method: "DELETE" });
6936
+ if (!attempt.ok) {
6937
+ const body = await attempt.text();
6938
+ const refusal = parseErrorResponse(attempt.status, body, void 0, attempt.headers);
6939
+ if (isLifecycleConflict(refusal)) sawLifecycleConflict = true;
6940
+ throw refusal;
6941
+ }
6942
+ return attempt;
6943
+ });
6944
+ } catch (caught) {
6945
+ if (!sawLifecycleConflict || !(caught instanceof NotFoundError)) throw caught;
6946
+ sandboxStatusObservedAt.delete(this);
6947
+ return {
6948
+ sandboxId: this.id,
6949
+ outcome: "already_absent"
6950
+ };
6870
6951
  }
6871
6952
  const data = await response.json().catch(() => null);
6872
6953
  const diagnostics = data ? normalizeStartupDiagnostics(data.startupDiagnostics) : null;
@@ -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-BbYJI8g_.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-CaYKcNaS.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-DsnIsKUL.js";
2
+ import { n as createSandboxInstanceFromResponse } from "./sandbox--QhO618M.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.36.3",
3
+ "version": "0.36.4",
4
4
  "description": "Client SDK for the Tangle Sandbox platform - build AI agent applications with dev containers",
5
5
  "type": "module",
6
6
  "sideEffects": [