@tangle-network/sandbox 0.10.4 → 0.10.5-develop.20260715115519.fee3d86
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.
- package/README.md +109 -0
- package/dist/agent/index.d.ts +3 -3
- package/dist/{client-B8i6qrQr.d.ts → client-CSaBJ8wD.d.ts} +7 -3
- package/dist/{client-DTpHjPjc.js → client-_OBj4sNO.js} +479 -61
- package/dist/collaboration/index.js +1 -1
- package/dist/{collaboration-QZXrXdIb.js → collaboration-CcZE2xMl.js} +1 -1
- package/dist/core.d.ts +4 -4
- package/dist/core.js +3 -3
- package/dist/{errors--P_nbLzM.d.ts → errors-CNCz3Ms9.d.ts} +1 -1
- package/dist/{errors-DSz87Rkk.js → errors-wd266B9Q.js} +3 -3
- package/dist/{index-BFnMEze6.d.ts → index-CEZaPvfX.d.ts} +2 -2
- package/dist/index.d.ts +28 -7
- package/dist/index.js +7 -282
- package/dist/intelligence/index.js +1 -1
- package/dist/{runtime-api-CYA2DUQw.js → runtime-api-BWq4XSrb.js} +269 -3
- package/dist/runtime.d.ts +50 -6
- package/dist/runtime.js +6 -4
- package/dist/{sandbox-BtNWbfd3.d.ts → sandbox-B9P4tyt4.d.ts} +11 -10
- package/dist/{sandbox-Be9WAqSg.js → sandbox-KiKLRbR_.js} +97 -45
- package/dist/tangle/index.d.ts +1 -1
- package/dist/tangle/index.js +1 -1
- package/dist/{tangle-D6UfK_B0.js → tangle-Os9sH-ms.js} +2 -2
- package/dist/{types-BvSoEHz8.d.ts → types-LNLeU9Ub.d.ts} +142 -25
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -206,9 +206,54 @@ client.connect();
|
|
|
206
206
|
detection, replay-on-reconnect, and `lastEventId` persistence. None of this requires a
|
|
207
207
|
Durable Object.
|
|
208
208
|
|
|
209
|
+
Server-originated product events can arrive before the browser connects:
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
await client.broadcastSessionAgentEvent(sessionId, {
|
|
213
|
+
type: "project.provision_progress",
|
|
214
|
+
properties: { message: "Creating workspace" },
|
|
215
|
+
});
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
The public API binds that pending queue to the authenticated product and Sandbox account and commits it to Redis before returning `success: true`.
|
|
219
|
+
A later connection by the same owner leases and acknowledges the ordered queue; another owner receives none of it.
|
|
220
|
+
A gateway crash before acknowledgement redelivers the same event IDs, which the default `SessionGatewayClient` deduplicates before invoking handlers.
|
|
221
|
+
|
|
209
222
|
See `examples/cf-worker-chat.ts`, `examples/browser-streaming-resume.ts`, and
|
|
210
223
|
`examples/reconnect-from-last-event-id.ts` for end-to-end patterns.
|
|
211
224
|
|
|
225
|
+
### Browser-safe scoped runtime client
|
|
226
|
+
|
|
227
|
+
`@tangle-network/sandbox/runtime` is a browser- and Worker-safe entry point
|
|
228
|
+
(no `node:` imports) for talking directly to one sandbox's runtime with a
|
|
229
|
+
short-lived scoped token — never the account-level Sandbox API key — minted
|
|
230
|
+
server-side via `box.mintScopedToken({ scope: "session-runtime", sessionId })`
|
|
231
|
+
or `box.mintScopedToken({ scope: "read-only" })`.
|
|
232
|
+
|
|
233
|
+
```typescript
|
|
234
|
+
import { createSandboxRuntimeClient } from "@tangle-network/sandbox/runtime";
|
|
235
|
+
|
|
236
|
+
const runtime = createSandboxRuntimeClient({
|
|
237
|
+
baseUrl: scopedToken.sidecarProxyUrl, // browser-safe proxy base from box.mintScopedToken()
|
|
238
|
+
token: scopedToken.token,
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
await runtime.writeFile("/workspace/notes.md", "# from the browser");
|
|
242
|
+
|
|
243
|
+
// Binary-safe, chunked upload for payloads over ~1 MiB — same engine and
|
|
244
|
+
// size contract as SandboxInstance.fs.uploadData, wired to the scoped token
|
|
245
|
+
const blob = await fileInput.files[0].arrayBuffer();
|
|
246
|
+
await runtime.uploadData("/workspace/uploads/file.bin", blob, {
|
|
247
|
+
onProgress: (p) => console.log(`${p.percentage.toFixed(1)}%`),
|
|
248
|
+
});
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
Every method on the scoped client — `writeFile`, `readFiles`, `uploadData`,
|
|
252
|
+
terminals, sessions — carries the same `Authorization: Bearer <token>` header
|
|
253
|
+
and base URL prefix, so the request conventions match whether the token
|
|
254
|
+
scope allows the call or not; a denied call fails with the typed
|
|
255
|
+
`SandboxError`, not a silent no-op.
|
|
256
|
+
|
|
212
257
|
## Features
|
|
213
258
|
|
|
214
259
|
- **Sandbox Management** - Create, list, stop, resume, and delete sandboxes
|
|
@@ -714,6 +759,70 @@ for await (const event of box.events({ signal: controller.signal })) {
|
|
|
714
759
|
}
|
|
715
760
|
```
|
|
716
761
|
|
|
762
|
+
### File I/O
|
|
763
|
+
|
|
764
|
+
| Method | Environment | Payload | Notes |
|
|
765
|
+
|---|---|---|---|
|
|
766
|
+
| `fs.read(path)` / `fs.write(path, content, options?)` | Node + browser | UTF-8 string, or base64 via `options.encoding` | Single request — see the size contract below for the cap |
|
|
767
|
+
| `fs.writeMany(files, options?)` | Node + browser | Same as `write`; per-file `encoding` | Paced, retry-aware batch through `fs.write`'s endpoint; fails loud on the first file that can't be written |
|
|
768
|
+
| `fs.upload(localPath, remotePath, options?)` | Node only | Local file path | Reads the local file with `node:fs`; not available in a browser tab |
|
|
769
|
+
| `fs.uploadData(remotePath, data, options?)` | Node + browser | `Blob \| ArrayBuffer \| ArrayBufferView \| string` | Browser/Worker-safe, binary-safe — the sanctioned path for payloads over ~1 MiB (see below) |
|
|
770
|
+
| `fs.download(remotePath, localPath, options?)` | Node only | — | Writes to a local path with `node:fs` |
|
|
771
|
+
| `fs.uploadDir` / `fs.downloadDir` | Node only | Local directory path | tar-based directory transfer |
|
|
772
|
+
| `fs.list` / `fs.stat` / `fs.mkdir` / `fs.delete` / `fs.rename` / `fs.exists` | Node + browser | — | Directory listing and file metadata operations |
|
|
773
|
+
|
|
774
|
+
```typescript
|
|
775
|
+
// Text write/read (UTF-8 by default)
|
|
776
|
+
await box.fs.write("/workspace/config.json", JSON.stringify(config));
|
|
777
|
+
const raw = await box.fs.read("/workspace/config.json");
|
|
778
|
+
|
|
779
|
+
// Base64 for binary content through the same single-shot endpoint
|
|
780
|
+
await box.fs.write("/workspace/icon.png", base64Png, { encoding: "base64" });
|
|
781
|
+
|
|
782
|
+
// Batch-write many small files (paced, retried)
|
|
783
|
+
await box.fs.writeMany([
|
|
784
|
+
{ path: "skills/review.md", content: reviewSkill },
|
|
785
|
+
{ path: "assets/logo.png", content: base64Logo, encoding: "base64" },
|
|
786
|
+
]);
|
|
787
|
+
|
|
788
|
+
// Node-only: upload a local file
|
|
789
|
+
await box.fs.upload("./model.bin", "/workspace/models/model.bin");
|
|
790
|
+
|
|
791
|
+
// Browser/Worker-safe: upload in-memory data over ~1 MiB (e.g. an
|
|
792
|
+
// <input type="file"> Blob) — chunked and verified end-to-end
|
|
793
|
+
const blob = await fetch("https://example.com/model.bin").then((r) => r.blob());
|
|
794
|
+
await box.fs.uploadData("/workspace/models/model.bin", blob, {
|
|
795
|
+
onProgress: (p) => console.log(`${p.percentage.toFixed(1)}%`),
|
|
796
|
+
});
|
|
797
|
+
|
|
798
|
+
await box.fs.download("/workspace/results.zip", "./results.zip");
|
|
799
|
+
```
|
|
800
|
+
|
|
801
|
+
`fs.uploadData` is the sanctioned path once a payload clears the single-shot
|
|
802
|
+
write cap: it splits the payload into server-sized parts against a chunked
|
|
803
|
+
upload-session and verifies the whole payload with a SHA-256 at commit, so
|
|
804
|
+
it's safe for arbitrarily-shaped binary content (video, model weights,
|
|
805
|
+
archives) up to the session cap. It works identically whether the sandbox is
|
|
806
|
+
reached through the gateway proxy or a direct sidecar connection
|
|
807
|
+
(`box.direct()`).
|
|
808
|
+
|
|
809
|
+
#### File size contract
|
|
810
|
+
|
|
811
|
+
| Surface | Cap | Constant | Failure |
|
|
812
|
+
|---|---|---|---|
|
|
813
|
+
| Single-shot decoded write (`fs.write`, `fs.writeMany`) | 5 MiB | `FILE_DECODED_WRITE_MAX_BYTES` | `FILE_TOO_LARGE` |
|
|
814
|
+
| Gateway proxy request (wire, any route) | 1 MiB | `SANDBOX_PROXY_REQUEST_MAX_BYTES` | `PAYLOAD_TOO_LARGE` |
|
|
815
|
+
| Direct-runtime write request (wire, `box.direct()` only) | 32 MiB | `SANDBOX_DIRECT_FILE_REQUEST_MAX_BYTES` | `PAYLOAD_TOO_LARGE` |
|
|
816
|
+
| Multipart upload (`fs.upload`) | 5 MiB | `FILE_MULTIPART_UPLOAD_MAX_BYTES` | `FILE_TOO_LARGE` |
|
|
817
|
+
| Chunked upload part (`fs.uploadData`, internal) | 768 KiB | `FILE_UPLOAD_PART_MAX_BYTES` | — (server-sized, transparent to callers) |
|
|
818
|
+
| Chunked upload session (`fs.uploadData`) | 64 MiB | `FILE_UPLOAD_SESSION_MAX_BYTES` | `PAYLOAD_TOO_LARGE` |
|
|
819
|
+
|
|
820
|
+
All constants are exported from `@tangle-network/runtime-contracts`. Use
|
|
821
|
+
`fs.uploadData` for anything above the single-shot caps. `PAYLOAD_TOO_LARGE`
|
|
822
|
+
means split the delivery (use `fs.uploadData` instead of one request);
|
|
823
|
+
`FILE_TOO_LARGE` means the content itself exceeds what that surface accepts,
|
|
824
|
+
no matter how it's delivered.
|
|
825
|
+
|
|
717
826
|
### Snapshots
|
|
718
827
|
|
|
719
828
|
#### `box.snapshot(options?)`
|
package/dist/agent/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { D as
|
|
2
|
-
import { n as SandboxInstance } from "../sandbox-
|
|
3
|
-
import { i as SandboxClient } from "../client-
|
|
1
|
+
import { D as CodeExecutionOptions, O as CodeExecutionResult, j as CodeResultPart, k as CodeLanguage } from "../types-LNLeU9Ub.js";
|
|
2
|
+
import { n as SandboxInstance } from "../sandbox-B9P4tyt4.js";
|
|
3
|
+
import { i as SandboxClient } from "../client-CSaBJ8wD.js";
|
|
4
4
|
import * as _$_modelcontextprotocol_sdk_server_index_js0 from "@modelcontextprotocol/sdk/server/index.js";
|
|
5
5
|
|
|
6
6
|
//#region src/agent/tools/_specs.d.ts
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { a as TraceExportSink, i as TraceExportResult, n as SandboxInstance, t as HttpClient } from "./sandbox-
|
|
1
|
+
import { $n as SandboxFleetDriverCapability, An as ReconcileSandboxFleetsResult, B as CreateSandboxOptions, Cn as PublicTemplateInfo, Ct as FleetPromptDispatchResult, Dn as ReapExpiredSandboxFleetsOptions, En as PublishPublicTemplateVersionOptions, Er as SandboxProfileSummary, F as CreateIntelligenceReportOptions, Gt as IntelligenceReportCompareTo, I as CreateRequestOptions, Jn as SandboxFleetArtifact, Kn as SandboxEnvironment, L as CreateSandboxFleetOptions, On as ReapExpiredSandboxFleetsResult, Qn as SandboxFleetDispatchResponse, Qt as ListSandboxOptions, R as CreateSandboxFleetTokenOptions, St as FleetPromptDispatchOptions, Ti as TokenRefreshHandler, Tn as PublishPublicTemplateOptions, Ut as IntelligenceReport, Wn as SandboxClientConfig, Wt as IntelligenceReportBudget, Xn as SandboxFleetCostEstimate, Yn as SandboxFleetArtifactSpec, Zt as ListSandboxFleetOptions, _ as BatchResult, _n as PromptOptions, _t as FleetDispatchResultBufferOptions, a as AttachSandboxFleetMachineOptions, ar as SandboxFleetMachineRecord, br as SandboxFleetWorkspaceSnapshotResult, bt as FleetExecDispatchResult, ci as SshKeysManager, dr as SandboxFleetToken, fi as SubscriptionInfo, fr as SandboxFleetTraceBundle, g as BatchOptions, gn as PromptInputPart, gr as SandboxFleetUsage, gt as FleetDispatchResultBuffer, hr as SandboxFleetTraceOptions, ht as FleetDispatchCancelResult, ji as UsageInfo, kn as ReconcileSandboxFleetsOptions, lr as SandboxFleetOperationsSummary, m as BatchEvent, nt as ExecOptions, qr as SecretsManager, qt as IntelligenceReportWindow, rt as ExecResult, sr as SandboxFleetManifest, tr as SandboxFleetInfo, v as BatchRunOptions, vn as PromptResult, vr as SandboxFleetWorkspaceReconcileResult, vt as FleetDispatchStreamOptions, wn as PublicTemplateVersionInfo, x as BatchTask, xr as SandboxInfo, xt as FleetMachineId, y as BatchRunRequest, yr as SandboxFleetWorkspaceRestoreResult, yt as FleetExecDispatchOptions, z as CreateSandboxFleetWithCoordinatorOptions } from "./types-LNLeU9Ub.js";
|
|
2
|
+
import { a as TraceExportSink, i as TraceExportResult, n as SandboxInstance, t as HttpClient } from "./sandbox-B9P4tyt4.js";
|
|
3
3
|
|
|
4
4
|
//#region src/lib/sse-parser.d.ts
|
|
5
5
|
/**
|
|
@@ -194,7 +194,11 @@ interface SessionBroadcastEvent {
|
|
|
194
194
|
data?: unknown;
|
|
195
195
|
channel?: string;
|
|
196
196
|
}
|
|
197
|
-
/**
|
|
197
|
+
/**
|
|
198
|
+
* Result returned after Sandbox accepts or rejects a session event.
|
|
199
|
+
* For a session that has not connected yet, `success: true` means the event
|
|
200
|
+
* was durably queued for the authenticated owner.
|
|
201
|
+
*/
|
|
198
202
|
interface SessionBroadcastResult {
|
|
199
203
|
success: boolean;
|
|
200
204
|
sessionId: string;
|