withruntime 0.10.0 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/BLAXEL.md +7 -8
- package/DAYTONA.md +40 -35
- package/E2B.md +70 -57
- package/README.md +3 -3
- package/README.src.md +3 -3
- package/VERCEL.md +23 -20
- package/compatibility-lock.json +63 -84
- package/dist/api-defaults.d.ts +1 -1
- package/dist/api-defaults.js +1 -1
- package/dist/blaxel/lookup.d.ts +2 -1
- package/dist/blaxel/lookup.js +2 -1
- package/dist/blaxel/sandbox.d.ts +7 -5
- package/dist/blaxel/sandbox.js +15 -10
- package/dist/cli.js +112 -17
- package/dist/client.d.ts +17 -1
- package/dist/client.js +46 -3
- package/dist/compat/files.js +5 -1
- package/dist/compat/lease.d.ts +37 -0
- package/dist/compat/lease.js +93 -0
- package/dist/credentials.d.ts +9 -0
- package/dist/credentials.js +26 -4
- package/dist/daytona/computer-use.d.ts +162 -0
- package/dist/daytona/computer-use.js +324 -0
- package/dist/daytona/context.d.ts +10 -0
- package/dist/daytona/context.js +24 -0
- package/dist/daytona/daytona.d.ts +20 -0
- package/dist/daytona/daytona.js +150 -26
- package/dist/daytona/filesystem.js +8 -0
- package/dist/daytona/index.d.ts +2 -26
- package/dist/daytona/index.js +2 -7
- package/dist/daytona/process.d.ts +63 -6
- package/dist/daytona/process.js +224 -23
- package/dist/daytona/sandbox.d.ts +25 -6
- package/dist/daytona/sandbox.js +60 -27
- package/dist/e2b/client.d.ts +5 -0
- package/dist/e2b/client.js +5 -1
- package/dist/e2b/commands.d.ts +15 -6
- package/dist/e2b/commands.js +83 -18
- package/dist/e2b/errors.d.ts +7 -0
- package/dist/e2b/errors.js +20 -0
- package/dist/e2b/filesystem.d.ts +2 -1
- package/dist/e2b/filesystem.js +43 -6
- package/dist/e2b/index.d.ts +2 -2
- package/dist/e2b/index.js +1 -1
- package/dist/e2b/pty.js +6 -3
- package/dist/e2b/sandbox.d.ts +20 -6
- package/dist/e2b/sandbox.js +207 -31
- package/dist/e2b/users.d.ts +30 -0
- package/dist/e2b/users.js +185 -0
- package/dist/errors.d.ts +6 -0
- package/dist/errors.js +6 -0
- package/dist/identity.js +2 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2 -1
- package/dist/mcp.d.ts +2 -1
- package/dist/mcp.js +6 -1
- package/dist/modal/index.js +6 -2
- package/dist/network-cli.js +33 -5
- package/dist/products/browser.d.ts +61 -0
- package/dist/products/browser.js +27 -0
- package/dist/products/desktop.d.ts +4 -3
- package/dist/products/desktop.js +7 -32
- package/dist/products/images.d.ts +3 -1
- package/dist/products/images.js +14 -2
- package/dist/products/index.d.ts +2 -0
- package/dist/products/index.js +2 -0
- package/dist/products/jobs.d.ts +7 -5
- package/dist/products/jobs.js +7 -3
- package/dist/products/mcp.d.ts +5 -1
- package/dist/products/mcp.js +29 -8
- package/dist/products/network-products.d.ts +8 -1
- package/dist/products/network-products.js +4 -1
- package/dist/products/observability.d.ts +1 -1
- package/dist/products/private-network.d.ts +22 -0
- package/dist/products/private-network.js +10 -0
- package/dist/products/secrets.d.ts +2 -2
- package/dist/runloop/index.js +6 -2
- package/dist/sandbox.d.ts +44 -14
- package/dist/sandbox.js +162 -48
- package/dist/tar.d.ts +2 -0
- package/dist/tar.js +74 -16
- package/dist/transport.d.ts +33 -7
- package/dist/transport.js +171 -36
- package/dist/types.d.ts +59 -11
- package/dist/vercel/filesystem.js +3 -1
- package/dist/vercel/index.d.ts +1 -7
- package/dist/vercel/index.js +1 -3
- package/dist/vercel/sandbox-user.d.ts +70 -0
- package/dist/vercel/sandbox-user.js +206 -0
- package/dist/vercel/sandbox.d.ts +57 -15
- package/dist/vercel/sandbox.js +219 -47
- package/dist/wait.d.ts +12 -0
- package/dist/wait.js +47 -0
- package/package.json +1 -1
package/BLAXEL.md
CHANGED
|
@@ -48,15 +48,14 @@ name, or through `getByExternalId`, use the same Runtime key.
|
|
|
48
48
|
resumes on the next call. On Runtime it pauses after 60 seconds without a
|
|
49
49
|
call (Runtime's shortest idle pause; Blaxel's is about 15 seconds), keeping
|
|
50
50
|
its memory, files and processes, and wakes by itself on the next command,
|
|
51
|
-
file call or preview visit.
|
|
52
|
-
|
|
53
|
-
does run out the sandbox pauses rather than ends.
|
|
51
|
+
file call or preview visit. It has no time limit, so a sandbox in use is
|
|
52
|
+
never paused on a clock.
|
|
54
53
|
- **How long it is kept:** Blaxel keeps a sandbox until it is deleted or its
|
|
55
54
|
TTL ends. A paused Runtime sandbox is kept 365 days when no TTL, expiry or
|
|
56
55
|
lifecycle is given. With one, it is never deleted before Blaxel would delete
|
|
57
56
|
it, and may be kept longer:
|
|
58
|
-
- a `ttl`, `expires`, `ttl-max-age` or `date` within the hour is a
|
|
59
|
-
ends the sandbox at that time, or later if the sandbox paused and woke;
|
|
57
|
+
- a `ttl`, `expires`, `ttl-max-age` or `date` within the hour is a time limit
|
|
58
|
+
that ends the sandbox at that time, or later if the sandbox paused and woke;
|
|
60
59
|
- any other deadline, and any `ttl-idle`, keeps a paused sandbox that many
|
|
61
60
|
days, rounded up, counted from each pause; with several, the shortest wins;
|
|
62
61
|
- at most 365 days.
|
|
@@ -161,9 +160,9 @@ Some differences are not refusals:
|
|
|
161
160
|
The old idle pause comes back once no `keepAlive` process runs, when a client
|
|
162
161
|
sees one end (a waited exec, `wait` or `get`), stops or kills one, or calls
|
|
163
162
|
`SandboxInstance.get`. With no such call, the sandbox pauses when it has been
|
|
164
|
-
idle for that `timeout`.
|
|
165
|
-
is paused with the sandbox when the
|
|
166
|
-
carries on at the next call.
|
|
163
|
+
idle for that `timeout`. On a sandbox with a time limit, a `keepAlive`
|
|
164
|
+
process past it is paused with the sandbox when the limit ends with no call
|
|
165
|
+
to renew it, and carries on at the next call.
|
|
167
166
|
- **A name is not refused while its process runs:** a second process may take a
|
|
168
167
|
running process's name, and `get(name)` answers the newest.
|
|
169
168
|
- **`process.list()` leaves each process's output empty** (Blaxel includes a
|
package/DAYTONA.md
CHANGED
|
@@ -38,11 +38,13 @@ package talks only to Runtime.
|
|
|
38
38
|
kept for Runtime's retention: 30 days on credit, 7 on the trial, or
|
|
39
39
|
`autoDeleteInterval` minutes rounded up to whole days. `delete()` ends it.
|
|
40
40
|
An `ephemeral` sandbox (or `autoDeleteInterval: 0`) ends on `stop()`.
|
|
41
|
-
- **Auto-stop:**
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
- **Auto-stop:** `autoStopInterval` minutes (default 15; `0` never) is the
|
|
42
|
+
sandbox's idle pause: it pauses after that long with nothing happening in
|
|
43
|
+
it, counted by the sandbox itself, so a long command is never paused for
|
|
44
|
+
want of calls. It has no time limit. `ttlMinutes` gives it one, and with
|
|
45
|
+
it Daytona's own rule: the sandbox pauses after `autoStopInterval` minutes
|
|
46
|
+
without a call through the adapter, each call moving the limit on, and ends
|
|
47
|
+
at the deadline.
|
|
46
48
|
- **Funding:** left to Runtime, as `withruntime`'s own `create()` does: the free
|
|
47
49
|
trial while the account has trial time, then prepaid credit. Pass
|
|
48
50
|
`withruntime: { create: { funding: "trial" } }` to `new Daytona(...)` or to
|
|
@@ -55,32 +57,35 @@ package talks only to Runtime.
|
|
|
55
57
|
|
|
56
58
|
## Mapping
|
|
57
59
|
|
|
58
|
-
| Daytona | On Runtime
|
|
59
|
-
| ----------------------------------------------------------------------------- |
|
|
60
|
-
| `daytona.create()`, `create({ snapshot })` | `sandboxes.create`. Daytona's own snapshots (`daytona-*`) are Runtime's stock image. Any other name is a ready Runtime image of that name, then a Runtime snapshot of that name.
|
|
61
|
-
| `create({ image: "python:3.12" })` | Built once as a Runtime image from the registry reference (named after it), then reused. `onSnapshotCreateLogs` receives the build log.
|
|
62
|
-
| `create({ image: Image.debianSlim(...).pipInstall(...)... })` | The Dockerfile Daytona's `Image` stands for, with its local files, built as a Runtime image named after its content and reused.
|
|
63
|
-
| `resources`, `envVars`, `labels`, `name`, `volumes` | `vcpu`, `memoryMiB`, `diskMiB`; environment given to every command; labels; name; Runtime volumes by id or by name.
|
|
64
|
-
| `setLabels` (Python `set_labels`) | Replaces customer labels while preserving the language and Runtime compatibility labels; reconnects retain the language.
|
|
65
|
-
| `networkBlockAll`, `networkAllowList`, `domainAllowList`, `outboundProxyUrl` | Runtime network rules (`internet: false`, or an `allow` list); the proxy as `HTTP_PROXY` and `HTTPS_PROXY` for commands.
|
|
66
|
-
| `public: true` | `getPreviewLink(port)` shares the port publicly; without it, privately with a token.
|
|
67
|
-
| `language` | The language of `codeRun`, kept in Daytona's `code-toolbox-language` label so a sandbox found later keeps it.
|
|
68
|
-
| `daytona.get(idOrName)`, `daytona.list(
|
|
69
|
-
| `process.executeCommand(cmd, cwd, env, timeout)` | `exec` under bash with stderr joined to stdout, as Daytona's `result`, streamed so the whole output comes back. A non-zero exit is a result. Past `timeout` (seconds): `DaytonaProcessExecutionTimeoutError`.
|
|
70
|
-
| `process.codeRun(code, { argv, env })` | `python3 -c`, `node -e` or `bun -e` by the sandbox's language. `artifacts.charts` is always empty.
|
|
71
|
-
| `createSession`, `executeSessionCommand`, `getSessionCommandLogs` | One bash per session, kept running: directory, variables and functions carry from one command to the next. `runAsync` returns at once; logs stream to callbacks.
|
|
72
|
-
| `sendSessionCommandInput`, `getSession`, `getSessionCommand`, `deleteSession` | Input to the session's shell, which the running command reads; the commands sent through this object; killing the shell.
|
|
73
|
-
| `fs.uploadFile(s)`, `downloadFile(s)`, `listFiles`, `getFileDetails` | Runtime's files API. Relative paths resolve from `/workspace`. `owner` and `group` are always `""`.
|
|
74
|
-
| `fs.createFolder`, `deleteFile`, `moveFiles`, `setFilePermissions` | `mkdir -m`, `files.remove`, `files.rename`, `chmod` and `sudo chown`.
|
|
75
|
-
| `fs.findFiles`, `searchFiles`, `replaceInFiles` | `grep -rn`, a files glob, and a read and write of each file.
|
|
76
|
-
| `git.clone`, `status`, `add`, `commit`, `push`, `pull`, branches | The sandbox's git. Credentials reach git through the environment, never the command line.
|
|
77
|
-
| `codeInterpreter.runCode`, contexts | Runtime's Python interpreter. The sandbox's `envVars` reach code through a context made once for them.
|
|
78
|
-
| `start`, `stop`, `pause`, `archive`, `delete`, `fork`, `createSnapshot` | `wake`, `pause` (or `stop` when ephemeral), `pause`, `pause`, `stop`, Runtime's fork with memory, a Runtime snapshot with that name.
|
|
79
|
-
| `getPreviewLink(port)` | A Runtime preview. Send its token as `x-runtime-preview-token`; Daytona's header is `x-daytona-preview-token`.
|
|
80
|
-
| `getUserHomeDir`, `getWorkDir`, `user` | `/workspace`, and `daytona`, so `/home/daytona` (linked to `/workspace` the first time something names it) works.
|
|
81
|
-
| `
|
|
82
|
-
| `
|
|
83
|
-
|
|
|
60
|
+
| Daytona | On Runtime |
|
|
61
|
+
| ----------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
62
|
+
| `daytona.create()`, `create({ snapshot })` | `sandboxes.create`. Daytona's own snapshots (`daytona-*`) are Runtime's stock image. Any other name is a ready Runtime image of that name, then a Runtime snapshot of that name. |
|
|
63
|
+
| `create({ image: "python:3.12" })` | Built once as a Runtime image from the registry reference (named after it), then reused. `onSnapshotCreateLogs` receives the build log. |
|
|
64
|
+
| `create({ image: Image.debianSlim(...).pipInstall(...)... })` | The Dockerfile Daytona's `Image` stands for, with its local files, built as a Runtime image named after its content and reused. |
|
|
65
|
+
| `resources`, `envVars`, `labels`, `name`, `volumes` | `vcpu`, `memoryMiB`, `diskMiB`; environment given to every command; labels; name; Runtime volumes by id or by name. |
|
|
66
|
+
| `setLabels` (Python `set_labels`) | Replaces customer labels while preserving the language and Runtime compatibility labels; reconnects retain the language. |
|
|
67
|
+
| `networkBlockAll`, `networkAllowList`, `domainAllowList`, `outboundProxyUrl` | Runtime network rules (`internet: false`, or an `allow` list); the proxy as `HTTP_PROXY` and `HTTPS_PROXY` for commands. |
|
|
68
|
+
| `public: true` | `getPreviewLink(port)` shares the port publicly; without it, privately with a token. |
|
|
69
|
+
| `language` | The language of `codeRun`, kept in Daytona's `code-toolbox-language` label so a sandbox found later keeps it. |
|
|
70
|
+
| `daytona.get(idOrName)`, `daytona.list(query)` | `sandboxes.get`, or the newest live sandbox with that name; `sandboxes.list` by labels and states, then Daytona's other filters (`id` and `name` prefixes, CPU, memory, disk, dates), `sort` and `order` here. Awaiting `list()` gives the older `{ items, total }` shape. |
|
|
71
|
+
| `process.executeCommand(cmd, cwd, env, timeout)` | `exec` under bash with stderr joined to stdout, as Daytona's `result`, streamed so the whole output comes back. A non-zero exit is a result. Past `timeout` (seconds): `DaytonaProcessExecutionTimeoutError`. |
|
|
72
|
+
| `process.codeRun(code, { argv, env })` | `python3 -c`, `node -e` or `bun -e` by the sandbox's language. `artifacts.charts` is always empty. |
|
|
73
|
+
| `createSession`, `executeSessionCommand`, `getSessionCommandLogs` | One bash per session, kept running: directory, variables and functions carry from one command to the next. `runAsync` returns at once; logs stream to callbacks. |
|
|
74
|
+
| `sendSessionCommandInput`, `getSession`, `getSessionCommand`, `deleteSession` | Input to the session's shell, which the running command reads; the commands sent through this object; killing the shell. |
|
|
75
|
+
| `fs.uploadFile(s)`, `downloadFile(s)`, `listFiles`, `getFileDetails` | Runtime's files API. Relative paths resolve from `/workspace`. `owner` and `group` are always `""`. |
|
|
76
|
+
| `fs.createFolder`, `deleteFile`, `moveFiles`, `setFilePermissions` | `mkdir -m`, `files.remove`, `files.rename`, `chmod` and `sudo chown`. |
|
|
77
|
+
| `fs.findFiles`, `searchFiles`, `replaceInFiles` | `grep -rn`, a files glob, and a read and write of each file. |
|
|
78
|
+
| `git.clone`, `status`, `add`, `commit`, `push`, `pull`, branches | The sandbox's git. Credentials reach git through the environment, never the command line. |
|
|
79
|
+
| `codeInterpreter.runCode`, contexts | Runtime's Python interpreter. The sandbox's `envVars` reach code through a context made once for them. |
|
|
80
|
+
| `start`, `stop`, `pause`, `archive`, `delete`, `fork`, `createSnapshot` | `wake`, `pause` (or `stop` when ephemeral), `pause`, `pause`, `stop`, Runtime's fork with memory, a Runtime snapshot with that name. |
|
|
81
|
+
| `getPreviewLink(port)` | A Runtime preview. Send its token as `x-runtime-preview-token`; Daytona's header is `x-daytona-preview-token`. |
|
|
82
|
+
| `getUserHomeDir`, `getWorkDir`, `user` | `/workspace`, and `daytona`, so `/home/daytona` (linked to `/workspace` the first time something names it) works. |
|
|
83
|
+
| `create({ user })` (Python `os_user`) | The user must exist in the image, as on Daytona. Commands, sessions and terminals run as it through `sudo`; files written through `fs` are given to it. It joins the owner's group, so both can share `/workspace`. |
|
|
84
|
+
| `process.createPty`, `connectPty`, `listPtySessions`, `resizePtySession` | A shell started with a terminal, which outlives the connection: `disconnect()` leaves it running, `connectPty` attaches again with what it printed so far, `killPtySession` ends it. |
|
|
85
|
+
| `computerUse.mouse`, `keyboard`, `screenshot`, `display`, `recording` | Runtime's desktop. `start()` installs it the first time, which takes a minute or two. Key names are Daytona's or xdotool's. |
|
|
86
|
+
| `daytona.snapshot.create`, `get`, `list`, `delete` | Runtime images built, found, listed and deleted by name. |
|
|
87
|
+
| `daytona.volume.get`, `list`, `delete` | Runtime volumes by name. |
|
|
88
|
+
| Error classes | Daytona's names and parents, by HTTP status. Each also carries Runtime's `code`, `hint` and `requestId`, with the original error as `cause`. |
|
|
84
89
|
|
|
85
90
|
## Gaps
|
|
86
91
|
|
|
@@ -92,9 +97,9 @@ Each of these throws `NotSupportedError` before anything happens. Its
|
|
|
92
97
|
| A snapshot name with no Runtime image or snapshot | `daytona.snapshot.create({ name, image })` here, or `npx withruntime image build`. This throws `DaytonaNotFoundError`. |
|
|
93
98
|
| GPUs, `spot`, `linkedSandbox`, `secrets`, `otelEndpointOverride` | Runtime runs Linux on CPUs. For `secrets`, a Runtime secret (`npx withruntime secrets set NAME --host <host>`): the sandbox sees a placeholder. For telemetry, `runtime.otel.create()`. |
|
|
94
99
|
| A `target` other than `us`, `jwtToken` | Runtime runs in one US region and signs in with keys. |
|
|
95
|
-
|
|
|
96
|
-
|
|
|
97
|
-
| `computerUse
|
|
100
|
+
| The entrypoint session, language servers | Sessions with `runAsync`. |
|
|
101
|
+
| Screenshots of a region, with the cursor, scaled, or as WebP | The whole screen as PNG or JPEG; crop and scale it yourself. |
|
|
102
|
+
| `computerUse.accessibility`, the desktop's processes one by one | Screenshots with the mouse and keyboard; `computerUse.getStatus()`, `stop()` and `start()`. |
|
|
98
103
|
| `resize`, `recover` | Set labels and resources at create; create a new sandbox. |
|
|
99
104
|
| Signed preview URLs, signed upload and download URLs, SSH access | `getPreviewLink`, `fs.uploadFile` and `downloadFile`, `npx withruntime sandbox ssh <id>`. |
|
|
100
105
|
| `getMetrics` | `sandbox.withruntime.metrics()`: its CPU and memory over time. |
|
|
@@ -102,7 +107,7 @@ Each of these throws `NotSupportedError` before anything happens. Its
|
|
|
102
107
|
| `volume.create(name)` | Runtime volumes have a size: `runtime.volumes.create({ name, sizeMiB })`. |
|
|
103
108
|
| `secret`, `warmPool` | A Runtime secret for credentials; Runtime starts from warm templates already. |
|
|
104
109
|
| `runCode(code, { envs })` | `envVars` at create, or `os.environ` in the code. |
|
|
105
|
-
| Listing by
|
|
110
|
+
| Listing by `isPublic`, `snapshots` or `autoDestroyAt` | Filter by a label you set at create. |
|
|
106
111
|
|
|
107
112
|
File download timeouts are seconds, including buffer and local-path overloads
|
|
108
113
|
and batches. A batch shares one deadline and stops starting later files once
|
package/E2B.md
CHANGED
|
@@ -20,9 +20,9 @@ from withruntime.e2b import Sandbox # was: from e2b import Sandbox
|
|
|
20
20
|
from withruntime.e2b.code_interpreter import Sandbox # was: from e2b_code_interpreter import Sandbox
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
The mapping was written against `e2b` 2.51.0 and
|
|
24
|
-
2.8.0 (Python: `e2b` 2.
|
|
25
|
-
|
|
23
|
+
The mapping was written against `e2b` 2.51.0 and checked against `e2b` 2.52.0
|
|
24
|
+
and `@e2b/code-interpreter` 2.8.0 (Python: `e2b` 2.52.0, `e2b-code-interpreter`
|
|
25
|
+
2.10.1) on 2 October 2026. The exact package releases and artifact hashes are kept in
|
|
26
26
|
`compatibility-lock.json`.
|
|
27
27
|
|
|
28
28
|
## Keys
|
|
@@ -41,6 +41,20 @@ machine. An E2B key (`e2b_...`) is never sent anywhere. If one is passed as
|
|
|
41
41
|
- **Timeout:** E2B's default of 300 seconds. When it ends, the sandbox is
|
|
42
42
|
stopped, as E2B kills it. `lifecycle: { onTimeout: "pause" }` pauses it
|
|
43
43
|
instead.
|
|
44
|
+
- **Idle pause:** Runtime's default, which E2B does not have. After 60
|
|
45
|
+
seconds with nothing happening in it (no request, running command, open
|
|
46
|
+
connection, traffic or CPU use) the sandbox pauses with its memory kept, and
|
|
47
|
+
the next command or file call wakes it. While it is paused, `isRunning()`
|
|
48
|
+
is `false` and `getInfo()` says `paused`, so code that reads either as
|
|
49
|
+
"the sandbox is gone" should not. Pass
|
|
50
|
+
`runtime: { create: { idlePauseSeconds: 0 } }` (Python:
|
|
51
|
+
`runtime_create={"idle_pause_seconds": 0}`) to keep it running, as on E2B.
|
|
52
|
+
- **Connections:** one client per key, holding at most 48 connections to the
|
|
53
|
+
API at once, since one address may hold 64. Each command being run holds
|
|
54
|
+
one while its output is read, and 8 are kept for other calls, so past 40
|
|
55
|
+
commands at once from one process the rest wait their turn. Pass your own
|
|
56
|
+
client with `runtime: { client: new Runtime({ maxConnections }) }` (Python:
|
|
57
|
+
`client=Runtime(max_connections=...)`).
|
|
44
58
|
- **Funding:** left to Runtime, as `withruntime`'s own `create()` does. The
|
|
45
59
|
free trial is used while the account has trial time, then prepaid credit.
|
|
46
60
|
Pass `runtime: { create: { funding: "trial" } }` to use only the trial.
|
|
@@ -51,39 +65,40 @@ machine. An E2B key (`e2b_...`) is never sent anywhere. If one is passed as
|
|
|
51
65
|
|
|
52
66
|
## Mapping
|
|
53
67
|
|
|
54
|
-
| E2B | On Runtime
|
|
55
|
-
| ---------------------------------------------------------------------------------------- |
|
|
56
|
-
| `Sandbox.create()`, `Sandbox.create(template, opts)` | `sandboxes.create`. `base` and `code-interpreter-v1` are Runtime's stock image. Any other name must be a ready Runtime image with that name. A UUID is an image or a snapshot.
|
|
57
|
-
| `timeoutMs` (Python `timeout`, seconds) | `timeoutSeconds`, rounded up. Under 60 s becomes 60 s, with a warning.
|
|
58
|
-
| `metadata` | labels (at most 32).
|
|
59
|
-
| `envs` | Given to every command and code run through this object.
|
|
60
|
-
| `allowInternetAccess: false` | `network: { internet: false }`.
|
|
61
|
-
| `lifecycle.onTimeout` | `onLeaseEnd`: `kill` is `stop`, `pause` is `pause`.
|
|
62
|
-
| `commands.run(cmd, { cwd, envs, timeoutMs, onStdout, onStderr })` | A native process
|
|
63
|
-
| Non-zero exit | Throws `CommandExitError` with `exitCode`, `stdout`, `stderr` and `error` (`exit status N`). A command killed by a signal has `exitCode` -1.
|
|
64
|
-
| Command past its timeout | Disconnects with `TimeoutError` (Python: `TimeoutException`) without killing the command; reconnect by pid to keep reading.
|
|
65
|
-
| `commands.run(cmd, { background: true })` | `spawn`. Returns a `CommandHandle` with `pid`, `wait()`, `kill()` (SIGKILL), `sendStdin`, `closeStdin`, `disconnect`, `stdout`, `stderr`, `exitCode`.
|
|
66
|
-
| `
|
|
67
|
-
| `
|
|
68
|
-
| `
|
|
69
|
-
| `files.
|
|
70
|
-
| `files.
|
|
71
|
-
| `files.
|
|
72
|
-
|
|
|
73
|
-
|
|
|
74
|
-
| `
|
|
75
|
-
| `sandbox.
|
|
76
|
-
| `
|
|
77
|
-
| `
|
|
78
|
-
| `
|
|
79
|
-
| `
|
|
80
|
-
| `
|
|
81
|
-
| `
|
|
82
|
-
| `
|
|
83
|
-
| `
|
|
84
|
-
| `
|
|
85
|
-
| `
|
|
86
|
-
|
|
|
68
|
+
| E2B | On Runtime |
|
|
69
|
+
| ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
70
|
+
| `Sandbox.create()`, `Sandbox.create(template, opts)` | `sandboxes.create`. `base` and `code-interpreter-v1` are Runtime's stock image. Any other name must be a ready Runtime image with that name. A UUID is an image or a snapshot. |
|
|
71
|
+
| `timeoutMs` (Python `timeout`, seconds) | Left out, the sandbox has no time limit: it runs while it works and pauses itself when idle. Given, it is `timeoutSeconds`, rounded up. Under 60 s becomes 60 s, with a warning. Up to 24 hours, as on E2B: a Runtime time limit reaches at most an hour ahead, so while this process runs the adapter extends it every five minutes, never past the end asked for. If the process ends first, the sandbox ends at its last limit, at most an hour later. Over 24 hours throws `InvalidArgumentError`. |
|
|
72
|
+
| `metadata` | labels (at most 32). |
|
|
73
|
+
| `envs` | Given to every command and code run through this object. |
|
|
74
|
+
| `allowInternetAccess: false` | `network: { internet: false }`. |
|
|
75
|
+
| `lifecycle.onTimeout` | `onLeaseEnd`: `kill` is `stop`, `pause` is `pause`. |
|
|
76
|
+
| `commands.run(cmd, { cwd, envs, timeoutMs, onStdout, onStderr })` | A native process started by a streamed exec that reads it from the first byte, so Runtime holds a fast writer back rather than drop output: the result is whole, however long. The default command connection deadline is 60 s; `0` disables it. The process lives up to 24 hours, within the sandbox lease. |
|
|
77
|
+
| Non-zero exit | Throws `CommandExitError` with `exitCode`, `stdout`, `stderr` and `error` (`exit status N`). A command killed by a signal has `exitCode` -1. |
|
|
78
|
+
| Command past its timeout | Disconnects with `TimeoutError` (Python: `TimeoutException`) without killing the command; reconnect by pid to keep reading. |
|
|
79
|
+
| `commands.run(cmd, { background: true })` | `spawn`. Returns a `CommandHandle` with `pid`, `wait()`, `kill()` (SIGKILL), `sendStdin`, `closeStdin`, `disconnect`, `stdout`, `stderr`, `exitCode`. Runtime keeps the last 1 MiB a process printed; anything older that was not read in time is lost, which sets `truncated` and warns. A command with `stdin: true` starts the same way. |
|
|
80
|
+
| `user` (commands, PTY and files) | Runs as that Linux user through `sudo -u`; `root` needs nothing more. A user the sandbox lacks throws `InvalidArgumentError` saying how to add one; none is ever created. `user: "user"` is the sandbox's own user. Watching a directory as another user is refused. |
|
|
81
|
+
| `commands.list`, `kill(pid)`, `sendStdin(pid)`, `closeStdin(pid)`, `connect(pid)` | Runtime's processes. A pid is a number derived from Runtime's process id, not the Linux pid. |
|
|
82
|
+
| `pty.create`, `connect`, `sendInput`, `resize`, `kill` (Python snake_case) | Native PTY processes with lossless byte callbacks. A reader timeout or disconnect detaches without killing the process; reconnect resumes reading. |
|
|
83
|
+
| `files.read(path, { format })` | `files.read`. `text`, `bytes`, `blob` and `stream` (Python: `text`, `bytes`, `stream`). |
|
|
84
|
+
| `files.write(path, data)`, `write([...])`, `writeFiles` | `files.write`. Parent directories are made, and a file that exists is replaced. |
|
|
85
|
+
| `files.list(path, { depth })` | `files.list`, hidden files included. `owner` and `group` come from native metadata, with `""` for older guests that omit them. |
|
|
86
|
+
| `files.makeDir`, `exists`, `getInfo`, `rename`, `remove` | `files.stat`, `mkdir`, `rename` (replacing a file that exists) and `remove` (recursive). A missing file throws `FileNotFoundError`. |
|
|
87
|
+
| Relative paths | Resolved against the home directory, `/workspace` on Runtime. |
|
|
88
|
+
| `/home/user` (E2B's home) | The first time a path, `cwd` or command names it, it becomes a link to `/workspace`, unless something is already there. |
|
|
89
|
+
| `sandbox.kill()`, `Sandbox.kill(id)` | `stop`, without waiting. `false` when the sandbox was not found or had already ended. |
|
|
90
|
+
| `sandbox.setTimeout(ms)`, `Sandbox.setTimeout(id, ms)` | `extend`: the end moves to now + ms, up to 24 hours (past an hour it is carried on as for `timeoutMs`). An earlier end is refused: Runtime cannot end a lease early. A sandbox with no time limit has no end to move, and nothing changes. |
|
|
91
|
+
| `Sandbox.connect(id, { timeoutMs })`, `sandbox.connect()` | `get`. A paused sandbox is woken. A running one's end moves later, never earlier, up to 24 hours. An ended one throws `SandboxNotFoundError`. |
|
|
92
|
+
| `sandbox.pause()`, `betaPause`, `Sandbox.pause(id)` | `pause`, keeping memory and files. `false` when it was already paused. |
|
|
93
|
+
| `getInfo`, `isRunning` | `get`. `templateId` is `base` or the image or snapshot id. `envdVersion` is `runtime`. |
|
|
94
|
+
| `Sandbox.list({ query: { metadata, state }, limit })` | `sandboxes.list` by labels and state, oldest first, with E2B's paginator (`hasNext`, `nextItems()`, `nextToken`). A `template` or `startedAfter` filter, `order: "desc"` and a saved `nextToken` are applied by the adapter, which reads every match once and pages through them. |
|
|
95
|
+
| `fork`, `createSnapshot`, `deleteSnapshot` | Runtime's memory-preserving forks and snapshots; deleting a snapshot removes that saved capture. A fork's `count` is 1 to 20, as E2B checks it. |
|
|
96
|
+
| `getHost(port)` | `<port>-<id>.runtimehost.com` at once, as E2B answers it, and the port is shared as a public Runtime preview beside the caller (the sync Python sandbox shares it before returning). `await sandbox.getPublicHost(port)` returns once the share has landed. On the free trial a shared port is private and a host alone cannot reach it, so both throw `PublicPreviewNotAllowedError` (Python: `PublicPreviewNotAllowedException`, a kind of `NotSupportedError`) at once. Use `(await sandbox.runtime.previews.create(port)).urlWithToken`, or send its token as the `x-runtime-preview-token` header. |
|
|
97
|
+
| `runCode(code, { language, context, onStdout, onStderr, onResult, onError, timeoutMs })` | Runtime's interpreter: Python, JavaScript, TypeScript, R, Java and Bash, plus Go. The sandbox's `envs` reach code through a context made once for them. `onResult` streams each result and waits for asynchronous callbacks. |
|
|
98
|
+
| `Execution`, `Result`, `Logs`, `ExecutionError`, `OutputMessage` | The same shapes. Results that are too large to send inline are fetched and inlined. `logs.stdout` has one entry per line. |
|
|
99
|
+
| `createCodeContext`, `listCodeContexts`, `restartCodeContext`, `removeCodeContext` | Runtime's interpreter contexts. |
|
|
100
|
+
| `getMetrics({ start, end })`, `Sandbox.getMetrics(id)` | Runtime's measured CPU and memory, one entry per host reading. `diskUsed` is null: Runtime does not read disk use inside the sandbox. |
|
|
101
|
+
| Error classes | E2B's names and parents. Each also carries Runtime's `code`, `hint` and `requestId`, with the original error as `cause`. |
|
|
87
102
|
|
|
88
103
|
## Gaps
|
|
89
104
|
|
|
@@ -91,26 +106,23 @@ Each of these throws `NotSupportedError` (Python: `NotSupportedException`)
|
|
|
91
106
|
before anything happens. The error's `feature` names the gap and its
|
|
92
107
|
`alternative` says what to use.
|
|
93
108
|
|
|
94
|
-
| E2B
|
|
95
|
-
|
|
|
96
|
-
| An E2B template name with no Runtime image of that name
|
|
97
|
-
| `Template`, `waitForPort` and the other ready checks
|
|
98
|
-
| `
|
|
99
|
-
| `
|
|
100
|
-
| `
|
|
101
|
-
| `
|
|
102
|
-
| `
|
|
103
|
-
| `
|
|
104
|
-
| `
|
|
105
|
-
| `
|
|
106
|
-
| `
|
|
107
|
-
|
|
|
108
|
-
| `
|
|
109
|
-
|
|
|
110
|
-
| `
|
|
111
|
-
| `Sandbox.list` by `template` or `startedAfter`, `order: "desc"`, or from a saved `nextToken` | Filter by metadata, and keep the paginator. |
|
|
112
|
-
| `runCode(code, { envs })` | A context made with them: `sandbox.runtime.interpreter.contexts.create({ env })`. |
|
|
113
|
-
| `domain`, `apiUrl`, `sandboxUrl`, `headers`, `proxy`, `debug` | Remove them. `RUNTIME_API_URL` sets Runtime's origin, and `HTTPS_PROXY` sets a proxy. |
|
|
109
|
+
| E2B | Use instead |
|
|
110
|
+
| ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
|
|
111
|
+
| An E2B template name with no Runtime image of that name | Build it: `npx withruntime image build --dockerfile e2b.Dockerfile --name <template>`. This throws `TemplateError`. |
|
|
112
|
+
| `Template`, `waitForPort` and the other ready checks | `runtime.images.build(...)` |
|
|
113
|
+
| `setTimeout` to an earlier time | `kill()` when the work is done. |
|
|
114
|
+
| `keepMemory: false` | Runtime's pause keeps memory. |
|
|
115
|
+
| `onResume: "reboot"` | Stop the sandbox and create a new one. |
|
|
116
|
+
| `fork({ timeoutMs })` | Fork without it, then call `setTimeout` on each fork. |
|
|
117
|
+
| `network`, `updateNetwork` | `runtime: { create: { network } }` and `sandbox.runtime.network.set(...)`. |
|
|
118
|
+
| `mcp`, `getMcpUrl`, `getMcpToken` | Runtime's own MCP server, `npx withruntime mcp`. |
|
|
119
|
+
| `iam`, `Secret` | A Runtime secret (`npx withruntime secrets set NAME --host <host>`): the sandbox sees a placeholder. |
|
|
120
|
+
| `volumeMounts`, `Volume` | Runtime volumes: `runtime: { create: { volumes: [{ volumeId, path }] } }`. |
|
|
121
|
+
| `git` | `commands.run("git ...")`. E2B has deprecated its git module too. |
|
|
122
|
+
| File `metadata` | Keep it in a file beside the data. |
|
|
123
|
+
| `uploadUrl`, `downloadUrl` | `files.write` and `files.read`. |
|
|
124
|
+
| `runCode(code, { envs })` | A context made with them: `sandbox.runtime.interpreter.contexts.create({ env })`. |
|
|
125
|
+
| `domain`, `apiUrl`, `sandboxUrl`, `headers`, `proxy`, `debug` | Remove them. `RUNTIME_API_URL` sets Runtime's origin, and `HTTPS_PROXY` sets a proxy. |
|
|
114
126
|
|
|
115
127
|
Directory watches use Runtime's native watch stream. JavaScript uses
|
|
116
128
|
`files.watchDir(path, onEvent, options)`. Python's synchronous `watch_dir(path)`
|
|
@@ -133,7 +145,8 @@ Some differences are not refusals, so code that depends on them should check:
|
|
|
133
145
|
for additional dependencies. Results never carry `chart`. A DataFrame arrives in
|
|
134
146
|
`extra` under `application/vnd.runtime.table+json`, not in E2B's `data`.
|
|
135
147
|
- JavaScript file operations, command creation and reads, stdin/EOF, lookup, kill and reconnect honor `requestTimeoutMs` and `signal`.
|
|
136
|
-
Python file `request_timeout` bounds the request, including streamed reads. `retries`, `logger`, `secure
|
|
148
|
+
Python file `request_timeout` bounds the request, including streamed reads. `retries`, `logger`, `secure`, `validateApiKey` and
|
|
149
|
+
`httpVersion` (Python `http_version`; `'1.1'` or `'2'`, as E2B checks it) are
|
|
137
150
|
accepted without changing the native transport settings.
|
|
138
151
|
- Interpreter deadlines follow the pinned packages: JavaScript defaults to
|
|
139
152
|
sixty seconds and Python to five minutes; zero disables the read deadline.
|
package/README.md
CHANGED
|
@@ -31,8 +31,8 @@ Node 22 call `await sbx.stop()`). With no arguments you get the free
|
|
|
31
31
|
trial while it lasts (100 free hours, up to eight sandboxes running at once), 2 vCPU, 4 GiB of
|
|
32
32
|
memory and a 4 GiB disk. The current default image includes NumPy, pandas and
|
|
33
33
|
matplotlib; see the [sandbox environment](https://withruntime.com/docs/sandbox-environment).
|
|
34
|
-
|
|
35
|
-
`
|
|
34
|
+
The trial's hours are spent first, then prepaid credit, with nothing to
|
|
35
|
+
choose; `funding` is accepted and ignored.
|
|
36
36
|
|
|
37
37
|
The sandbox object does the rest:
|
|
38
38
|
|
|
@@ -45,7 +45,7 @@ The sandbox object does the rest:
|
|
|
45
45
|
directories with `upload` and `download`;
|
|
46
46
|
- `pause`, `wake`, `extend`, `fork` and `snapshot` (a paused sandbox also wakes
|
|
47
47
|
by itself on the next call), `update` for its name, environment, automatic
|
|
48
|
-
wake, idle pause and persistence, `keepAlive` to
|
|
48
|
+
wake, idle pause and persistence, `keepAlive` to move a time limit on while your
|
|
49
49
|
process runs, `switchImage` to move it to a new image keeping /workspace,
|
|
50
50
|
and `delete` to remove it for good;
|
|
51
51
|
- `interpreter`, `network`, `previews`, `desktop`, `mounts` (your S3, R2 or
|
package/README.src.md
CHANGED
|
@@ -33,8 +33,8 @@ Node 22 call `await sbx.stop()`). With no arguments you get the free
|
|
|
33
33
|
trial while it lasts ({{trial-hours}} free hours, up to {{trial-sandboxes}} sandboxes running at once), 2 vCPU, 4 GiB of
|
|
34
34
|
memory and a 4 GiB disk. The current default image includes NumPy, pandas and
|
|
35
35
|
matplotlib; see the [sandbox environment](https://withruntime.com/docs/sandbox-environment).
|
|
36
|
-
|
|
37
|
-
`
|
|
36
|
+
The trial's hours are spent first, then prepaid credit, with nothing to
|
|
37
|
+
choose; `funding` is accepted and ignored.
|
|
38
38
|
|
|
39
39
|
The sandbox object does the rest:
|
|
40
40
|
|
|
@@ -47,7 +47,7 @@ The sandbox object does the rest:
|
|
|
47
47
|
directories with `upload` and `download`;
|
|
48
48
|
- `pause`, `wake`, `extend`, `fork` and `snapshot` (a paused sandbox also wakes
|
|
49
49
|
by itself on the next call), `update` for its name, environment, automatic
|
|
50
|
-
wake, idle pause and persistence, `keepAlive` to
|
|
50
|
+
wake, idle pause and persistence, `keepAlive` to move a time limit on while your
|
|
51
51
|
process runs, `switchImage` to move it to a new image keeping /workspace,
|
|
52
52
|
and `delete` to remove it for good;
|
|
53
53
|
- `interpreter`, `network`, `previews`, `desktop`, `mounts` (your S3, R2 or
|
package/VERCEL.md
CHANGED
|
@@ -33,8 +33,12 @@ are ignored.
|
|
|
33
33
|
|
|
34
34
|
- **Machine:** Vercel's default, 2 vCPUs with 2048 MiB each.
|
|
35
35
|
`resources: { vcpus }` sets another, with 2048 MiB per vCPU.
|
|
36
|
-
- **Timeout:**
|
|
37
|
-
|
|
36
|
+
- **Timeout:** none unless you pass one: the sandbox runs while it works and
|
|
37
|
+
pauses itself when idle. A `timeout` is kept as a Runtime time limit, which
|
|
38
|
+
runs 60 seconds to an hour. A longer `timeout` (Python `execution_time_limit`) starts with an
|
|
39
|
+
hour's lease, and the sandbox object renews it toward the timeout while it
|
|
40
|
+
lives, never past it; once the program ends, the sandbox pauses within an
|
|
41
|
+
hour. `extendTimeout` moves the end later, as often as needed.
|
|
38
42
|
- **Persistence:** persistent by default, as in Vercel. `stop()` and the end of
|
|
39
43
|
the timeout pause the sandbox, keeping its files and also its memory and
|
|
40
44
|
processes. `Sandbox.get({ name })`, or the next command or file call, wakes
|
|
@@ -63,6 +67,8 @@ are ignored.
|
|
|
63
67
|
| `source: { type: "tarball", url }`, `{ type: "snapshot" }` | Downloaded and unpacked into the working directory; a Runtime snapshot, with its own shape. |
|
|
64
68
|
| `networkPolicy`, `updateNetworkPolicy` | Runtime network rules: `allow-all`, `deny-all`, or a list of domains and subnets to allow and deny. |
|
|
65
69
|
| `Sandbox.get({ name })`, `getOrCreate`, `list({ tags })` | The newest live sandbox with that name (or a Runtime id), woken; create when missing; `sandboxes.list` with Vercel's paginator. |
|
|
70
|
+
| `list({ namePrefix, since, until, sortBy, sortOrder, cursor })` | Applied here over every sandbox the key sees; the cursor continues the same order. Python's `query_sandboxes` does the same. |
|
|
71
|
+
| `createUser`, `asUser`, `createGroup`, `addUserToGroup` | `useradd`, `groupadd` and `usermod` with `sudo`, as Vercel does; a user's commands run under `sudo -u` in its home, its files given to it. |
|
|
66
72
|
| `Sandbox.fork({ sourceSandbox, name })` | A Runtime fork, which copies memory and processes too. |
|
|
67
73
|
| `runCommand(cmd, args)`, `runCommand({ cmd, args, cwd, env, sudo })` | `exec` of the argv without a shell. `sudo` runs it under `sudo --preserve-env`. A non-zero exit is a result. Past `timeoutMs` it exits 137. |
|
|
68
74
|
| `stdout`, `stderr` writers, `detached: true`, `logs()`, `wait()` | Output streams to the writers; a detached command is a Runtime process, its logs followed from the start. |
|
|
@@ -72,7 +78,7 @@ are ignored.
|
|
|
72
78
|
| Paths | Relative paths resolve from `/vercel/sandbox`, which is `/workspace`. A command that names `/vercel/sandbox` finds a link to it. |
|
|
73
79
|
| `domain(port)`, `update({ ports })` | The public preview of that port; ports added or removed. |
|
|
74
80
|
| `stop()`, `delete()`, `extendTimeout(ms)` | `pause` (persistent) or `stop`; `stop`; `extend`. |
|
|
75
|
-
| `update({ timeout, networkPolicy, snapshotExpiration })` |
|
|
81
|
+
| `update({ timeout, networkPolicy, snapshotExpiration })` | A new timeout (earlier only while the lease has not reached it), network rules, retention. |
|
|
76
82
|
| `snapshot()`, `Snapshot.get`, `Snapshot.list`, `snapshot.delete()` | A verified disk-only capture, then the source stops; restored snapshots start fresh processes; `snapshots.get`, `list`, `delete`. |
|
|
77
83
|
| Error classes | `APIError` with a `response` whose status is Runtime's and `json` of `{ error: { code, message } }`; also `code`, `hint` and `requestId`. |
|
|
78
84
|
| Python: `create_sandbox`, `run_process`, `create_process`, `box.fs` | The same mapping; operations await or work as context managers, which stop and by default destroy the sandbox; readers iterate by line. |
|
|
@@ -82,21 +88,20 @@ are ignored.
|
|
|
82
88
|
Each of these throws `NotSupportedError` before anything happens. Its
|
|
83
89
|
`feature` names the gap and its `alternative` says what to use.
|
|
84
90
|
|
|
85
|
-
| Vercel Sandbox | Use instead
|
|
86
|
-
| ---------------------------------------------------------- |
|
|
87
|
-
| An `image` with no Runtime image of that name | Build it: `npx withruntime image build --dockerfile Dockerfile --name <image>`.
|
|
88
|
-
| `
|
|
89
|
-
|
|
|
90
|
-
|
|
|
91
|
-
|
|
|
92
|
-
| `
|
|
93
|
-
|
|
|
94
|
-
|
|
|
95
|
-
| `
|
|
96
|
-
|
|
|
97
|
-
| `
|
|
98
|
-
| `
|
|
99
|
-
| Listing by time, prefix or cursor (JavaScript) | List them all and filter the result yourself. (Python applies a name prefix and newest-first order itself.) |
|
|
91
|
+
| Vercel Sandbox | Use instead |
|
|
92
|
+
| ---------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
|
|
93
|
+
| An `image` with no Runtime image of that name | Build it: `npx withruntime image build --dockerfile Dockerfile --name <image>`. |
|
|
94
|
+
| Drives (`mounts`), `networkId` | Runtime volumes through `withruntime: { create: { volumes } }`; network rules. |
|
|
95
|
+
| A region outside the US, `failoverRegions` | Runtime runs in one US region. |
|
|
96
|
+
| Network rules that transform or forward requests | Allow the domain and store the credential as a Runtime secret for it: the sandbox sees a placeholder. |
|
|
97
|
+
| A `timeout` earlier than the current lease's end | Stop the sandbox when you are done with it. |
|
|
98
|
+
| Sessions (`currentSession`, `listSessions`) | A Runtime sandbox is its own session. |
|
|
99
|
+
| `openInteractive` | `sandbox.withruntime.terminal(...)` or `npx withruntime sandbox shell <id>`. |
|
|
100
|
+
| `update` of tags, resources, persistence or region | Create a new sandbox with them. |
|
|
101
|
+
| Overrides on `Sandbox.fork` | Fork, then change what Runtime can change. |
|
|
102
|
+
| `delete({ deleteOrphanSnapshots: true })`, `Snapshot.tree` | Delete snapshots one by one; `Snapshot.list`. |
|
|
103
|
+
| `Drive`, `defineSandboxProxy` | Runtime volumes; `sandbox.withruntime.previews`. |
|
|
104
|
+
| `keepLastSnapshots` | Manage saved snapshots with `Snapshot.list` and `snapshot.delete`. |
|
|
100
105
|
|
|
101
106
|
Explicit snapshots require the released native disk-capture capability; a server
|
|
102
107
|
that does not confirm disk-only capture is refused. If capture succeeds but the
|
|
@@ -116,8 +121,6 @@ Some differences are not refusals:
|
|
|
116
121
|
`pwd` prints `/workspace`.
|
|
117
122
|
- Runtime's stock image is Ubuntu 24.04 with Python 3.12, Node.js 24 and Bun;
|
|
118
123
|
Vercel's `universal` has Python 3.14.
|
|
119
|
-
- `keepLastSnapshots` is accepted: a paused Runtime sandbox keeps exactly its
|
|
120
|
-
latest state.
|
|
121
124
|
- A git source is cloned into the working directory itself.
|
|
122
125
|
|
|
123
126
|
## Tests
|