withruntime 0.11.1 → 0.11.2
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 +1 -1
- package/DAYTONA.md +1 -1
- package/E2B.md +57 -29
- package/README.md +4 -3
- package/README.src.md +4 -3
- package/compatibility-lock.json +14 -14
- package/dist/blaxel/errors.js +4 -4
- package/dist/blaxel/sandbox.d.ts +1 -2
- package/dist/blaxel/sandbox.js +1 -2
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +63 -15
- package/dist/client.d.ts +11 -59
- package/dist/client.js +8 -113
- package/dist/daytona/daytona.d.ts +1 -2
- package/dist/daytona/daytona.js +1 -2
- package/dist/daytona/sandbox.d.ts +1 -1
- package/dist/daytona/sandbox.js +1 -1
- package/dist/e2b/client.d.ts +15 -2
- package/dist/e2b/client.js +61 -7
- package/dist/e2b/commands.d.ts +3 -0
- package/dist/e2b/commands.js +16 -5
- package/dist/e2b/errors.d.ts +26 -2
- package/dist/e2b/errors.js +38 -5
- package/dist/e2b/filesystem.d.ts +1 -1
- package/dist/e2b/filesystem.js +82 -16
- package/dist/e2b/index.d.ts +2 -2
- package/dist/e2b/index.js +2 -2
- package/dist/e2b/sandbox.d.ts +23 -14
- package/dist/e2b/sandbox.js +195 -178
- package/dist/e2b/unsupported.d.ts +19 -0
- package/dist/e2b/unsupported.js +21 -0
- package/dist/e2b/users.d.ts +9 -0
- package/dist/e2b/users.js +22 -0
- package/dist/errors.d.ts +4 -4
- package/dist/errors.js +12 -10
- package/dist/machine.d.ts +180 -0
- package/dist/machine.js +504 -0
- package/dist/openai-agents/index.d.ts +1 -1
- package/dist/openai-agents/index.js +1 -1
- package/dist/products/jobs.d.ts +2 -3
- package/dist/products/jobs.js +1 -2
- package/dist/products/limits.d.ts +4 -10
- package/dist/products/network.d.ts +1 -1
- package/dist/products/secrets.d.ts +1 -1
- package/dist/products/switching.d.ts +2 -3
- package/dist/sandbox.d.ts +7 -92
- package/dist/sandbox.js +8 -362
- package/dist/transport.d.ts +4 -2
- package/dist/transport.js +6 -4
- package/dist/types.d.ts +53 -8
- package/dist/vercel/sandbox.d.ts +1 -2
- package/dist/vercel/sandbox.js +1 -2
- package/package.json +1 -1
package/BLAXEL.md
CHANGED
|
@@ -34,7 +34,7 @@ name, or through `getByExternalId`, use the same Runtime key.
|
|
|
34
34
|
- **Machine:** Blaxel's default of 4096 MB. vCPUs follow Blaxel's rule of one
|
|
35
35
|
per 2048 MB (at least one, at most 16): 2 for the default, 4 for 8192 MB. A
|
|
36
36
|
trial sandbox has at most 4096 MB (2 vCPUs); `memory: 8192` or more needs
|
|
37
|
-
prepaid credit, and on the trial is refused with a 400 (`
|
|
37
|
+
prepaid credit, and on the trial is refused with a 400 (`no_credit_size_limit`)
|
|
38
38
|
saying so.
|
|
39
39
|
- **Image:** Blaxel's `base-image`, `py-app`, `ts-app`, `node`,
|
|
40
40
|
`docker-in-sandbox` and `jupyter-server` are Runtime's stock image (Ubuntu
|
package/DAYTONA.md
CHANGED
|
@@ -17,7 +17,7 @@ from withruntime.daytona import AsyncDaytona # was: from daytona import AsyncDa
|
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
The mapping was written against `@daytona/sdk` 0.220.0 and `daytona` 0.220.0
|
|
20
|
-
on PyPI, checked
|
|
20
|
+
on PyPI, and checked against `@daytona/sdk` 0.222.0 on 5 October 2026. The exact releases and artifact hashes
|
|
21
21
|
are kept in `compatibility-lock.json`.
|
|
22
22
|
|
|
23
23
|
## Keys
|
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 checked against `e2b` 2.52.
|
|
24
|
-
and `@e2b/code-interpreter` 2.8.0 (Python: `e2b` 2.52.
|
|
25
|
-
2.10.1) on
|
|
23
|
+
The mapping was written against `e2b` 2.51.0 and checked against `e2b` 2.52.1
|
|
24
|
+
and `@e2b/code-interpreter` 2.8.0 (Python: `e2b` 2.52.1, `e2b-code-interpreter`
|
|
25
|
+
2.10.1) on 5 October 2026. The exact package releases and artifact hashes are kept in
|
|
26
26
|
`compatibility-lock.json`.
|
|
27
27
|
|
|
28
28
|
## Keys
|
|
@@ -30,30 +30,54 @@ and `@e2b/code-interpreter` 2.8.0 (Python: `e2b` 2.52.0, `e2b-code-interpreter`
|
|
|
30
30
|
The package uses, in order: an `apiKey` you pass, `RUNTIME_API_KEY`, a Runtime
|
|
31
31
|
key left in `E2B_API_KEY`, and the key `npx withruntime login` saved on this
|
|
32
32
|
machine. An E2B key (`e2b_...`) is never sent anywhere. If one is passed as
|
|
33
|
-
`apiKey` and `RUNTIME_API_KEY` is not set, the call
|
|
34
|
-
`AuthenticationError
|
|
33
|
+
`apiKey`, or left in `E2B_API_KEY`, and `RUNTIME_API_KEY` is not set, the call
|
|
34
|
+
fails with `AuthenticationError` (Python: `AuthenticationException`) saying
|
|
35
|
+
so, rather than fall back to a saved login that may be another account's.
|
|
36
|
+
When `RUNTIME_API_KEY` and `E2B_API_KEY` hold two different Runtime keys, which
|
|
37
|
+
may be two accounts, a warning says so once (`RUNTIME_E2B_TWO_KEYS`; Python: a
|
|
38
|
+
`RuntimeWarning`). A template with no image of its name fails naming the
|
|
39
|
+
account the key belongs to and where the key came from.
|
|
35
40
|
|
|
36
41
|
## What a sandbox gets
|
|
37
42
|
|
|
38
43
|
- **Machine:** E2B's default, 2 vCPU and 512 MiB. For another, pass
|
|
39
44
|
`runtime: { create: { memoryMiB: 4096 } }` (Python:
|
|
40
45
|
`runtime_create={"memory_mib": 4096}`).
|
|
41
|
-
- **Timeout:**
|
|
42
|
-
|
|
43
|
-
|
|
46
|
+
- **Timeout:** kept by Runtime's server, never by a timer in your process,
|
|
47
|
+
so it holds after the process that made the sandbox exits. A `timeoutMs`
|
|
48
|
+
you give (Python `timeout`, seconds), up to 24 hours, deletes the sandbox
|
|
49
|
+
when it runs out, as E2B kills it; so does `lifecycle: { onTimeout: "kill" }`.
|
|
50
|
+
With no timeout, E2B's default of 300 seconds applies, and when it runs out
|
|
51
|
+
the sandbox **pauses** instead: nobody asked for it to end, so nothing is
|
|
52
|
+
lost, and the next call wakes it. E2B deletes it at that point.
|
|
53
|
+
`lifecycle: { onTimeout: "pause" }` pauses at any timeout.
|
|
54
|
+
- **What a pause keeps, and costs:** memory, files and running processes, for
|
|
55
|
+
as long as the account has credit, billed as paused storage by the GB a
|
|
56
|
+
month for what the sandbox alone holds (`pricing.md`, "Paused storage").
|
|
57
|
+
Sandboxes created with no timeout and never killed pile up as paused
|
|
58
|
+
storage: call `kill()` when the work is done, or give a `timeoutMs`.
|
|
59
|
+
- **On a pilot account:** the server keeps every sandbox running until you
|
|
60
|
+
end it, with no idle pause, whatever `timeoutMs` says, and machine size is
|
|
61
|
+
the pilot's. `kill()` deletes it.
|
|
62
|
+
- **Kill:** `kill()` deletes the sandbox for good, as E2B's does: its disk,
|
|
63
|
+
memory and shared ports go, and it no longer counts against the account's
|
|
64
|
+
sandboxes.
|
|
44
65
|
- **Idle pause:** Runtime's default, which E2B does not have. After 60
|
|
45
66
|
seconds with nothing happening in it (no request, running command, open
|
|
46
67
|
connection, traffic or CPU use) the sandbox pauses with its memory kept, and
|
|
47
|
-
the next command or file call wakes it.
|
|
48
|
-
|
|
49
|
-
|
|
68
|
+
the next command or file call wakes it. To code written for E2B it is still
|
|
69
|
+
running: `isRunning()` is `true`, `getInfo()` says `running` and
|
|
70
|
+
`list({ query: { state: ["running"] } })` includes it. Pass
|
|
50
71
|
`runtime: { create: { idlePauseSeconds: 0 } }` (Python:
|
|
51
72
|
`runtime_create={"idle_pause_seconds": 0}`) to keep it running, as on E2B.
|
|
52
|
-
- **Connections:** one client per key, holding
|
|
53
|
-
API at once,
|
|
54
|
-
|
|
55
|
-
commands at once from one process
|
|
56
|
-
|
|
73
|
+
- **Connections:** one client per key, holding up to 4,096 connections to
|
|
74
|
+
the API at once, the most Runtime's edge gives an address that has used a
|
|
75
|
+
valid key. E2B's SDK holds no call back, and neither does this one: a
|
|
76
|
+
thousand commands at once from one process all run at once. Past an
|
|
77
|
+
account's room the API answers with a retry, which the client waits out. If
|
|
78
|
+
calls ever wait for a connection, a warning says so once
|
|
79
|
+
(`RUNTIME_E2B_QUEUED`). Runtime's own SDK keeps 48; pass your own client
|
|
80
|
+
with `runtime: { client: new Runtime({ maxConnections }) }` (Python:
|
|
57
81
|
`client=Runtime(max_connections=...)`).
|
|
58
82
|
- **Funding:** left to Runtime, as `withruntime`'s own `create()` does. The
|
|
59
83
|
free trial is used while the account has trial time, then prepaid credit.
|
|
@@ -67,30 +91,30 @@ machine. An E2B key (`e2b_...`) is never sent anywhere. If one is passed as
|
|
|
67
91
|
|
|
68
92
|
| E2B | On Runtime |
|
|
69
93
|
| ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
70
|
-
| `Sandbox.create()`, `Sandbox.create(template, opts)` | `sandboxes.create`. `base` and `code-interpreter-v1` are Runtime's stock image. Any other name
|
|
71
|
-
| `timeoutMs` (Python `timeout`, seconds) |
|
|
94
|
+
| `Sandbox.create()`, `Sandbox.create(template, opts)` | `sandboxes.create`. `base` and `code-interpreter-v1` are Runtime's stock image. Any other name, with its `:tag`, is a Runtime image of that name, resolved by the create itself; E2B's `team/` prefix is dropped, since an account's images are its own. A UUID is an image or a snapshot. A name no image has throws `TemplateError` saying how to build it. |
|
|
95
|
+
| `timeoutMs` (Python `timeout`, seconds) | `timeoutSeconds`, rounded up, kept by the server, with `onTimeout: "delete"`. Left out, 300 s with `onTimeout: "pause"`. Under 60 s becomes 60 s, with a warning. Up to 24 hours, as on E2B; over throws `InvalidArgumentError`. |
|
|
72
96
|
| `metadata` | labels (at most 32). |
|
|
73
97
|
| `envs` | Given to every command and code run through this object. |
|
|
74
98
|
| `allowInternetAccess: false` | `network: { internet: false }`. |
|
|
75
|
-
| `lifecycle.onTimeout` | `
|
|
99
|
+
| `lifecycle.onTimeout` | `onTimeout`: `kill` is `delete`, `pause` is `pause`. |
|
|
76
100
|
| `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
101
|
| 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.
|
|
102
|
+
| Command past its timeout | Disconnects with `TimeoutError` (Python: `TimeoutException`) without killing the command; reconnect by pid to keep reading. A command whose sandbox is killed under it ends with `TimeoutError` too, saying the sandbox was killed or reached its end of life. |
|
|
79
103
|
| `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
104
|
| `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.
|
|
105
|
+
| `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. `commands.list` shows each command as E2B starts it: `cmd` `/bin/bash`, `args` `["-l", "-c", "<your command>"]` (a PTY: `["-i", "-l"]`), the command cut at 256 characters, `envs` empty. |
|
|
82
106
|
| `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
107
|
| `files.read(path, { format })` | `files.read`. `text`, `bytes`, `blob` and `stream` (Python: `text`, `bytes`, `stream`). |
|
|
84
108
|
| `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.
|
|
109
|
+
| `files.list(path, { depth })` | `files.list`, hidden files included. `owner` and `group` come from native metadata, with `""` for older guests that omit them. `depth` below one throws `InvalidArgumentError` "depth should be at least one". |
|
|
110
|
+
| `files.makeDir`, `exists`, `getInfo`, `rename`, `remove` | `files.stat`, `mkdir`, `rename` (replacing a file that exists) and `remove` (recursive). A missing file throws `FileNotFoundError`. Entries read as envd gives them: `permissions` begins with the kind's letter (`-rw-r--r--`, `drwxr-xr-x`, `L` for a link), the sandbox user is `user`, and a link's `symlinkTarget` is absolute. |
|
|
111
|
+
| Relative paths | Resolved against the home directory, `/workspace` on Runtime, and given back under `/home/user`, as E2B gives them: `write("a.txt")` returns `/home/user/a.txt`. A path given in full comes back as given. `pwd` in a command prints `/workspace`. |
|
|
88
112
|
| `/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)` | `
|
|
90
|
-
| `sandbox.setTimeout(ms)`, `Sandbox.setTimeout(id, ms)` | `extend`: the end moves to now + ms, up to 24 hours
|
|
113
|
+
| `sandbox.kill()`, `Sandbox.kill(id)` | `delete`: gone for good. `false` when the sandbox was not found or was already deleted. |
|
|
114
|
+
| `sandbox.setTimeout(ms)`, `Sandbox.setTimeout(id, ms)` | `extend`: the end moves to now + ms, up to 24 hours. An earlier end is refused: Runtime cannot bring a time limit forward. A sandbox with no time limit (a pilot's) has no end to move, and nothing changes. |
|
|
91
115
|
| `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
116
|
| `sandbox.pause()`, `betaPause`, `Sandbox.pause(id)` | `pause`, keeping memory and files. `false` when it was already paused. |
|
|
93
|
-
| `getInfo`, `isRunning` | `get`. `templateId` is
|
|
117
|
+
| `getInfo`, `isRunning` | `get`. `templateId` is the template the sandbox was created from, as you named it (kept in the label `e2b-template`, which `metadata` leaves out), or `base`. `envdVersion` is `runtime`. A sandbox Runtime paused for being idle is `running`. `endAt` is when it ends by itself; one that never will (no time limit, as a pilot's) reads 24 hours ahead, the furthest E2B allows. |
|
|
94
118
|
| `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
119
|
| `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
120
|
| `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. |
|
|
@@ -98,7 +122,7 @@ machine. An E2B key (`e2b_...`) is never sent anywhere. If one is passed as
|
|
|
98
122
|
| `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
123
|
| `createCodeContext`, `listCodeContexts`, `restartCodeContext`, `removeCodeContext` | Runtime's interpreter contexts. |
|
|
100
124
|
| `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
|
|
125
|
+
| Error classes and other exports | Every name `e2b` and the code interpreter export imports, errors with E2B's names and parents. Python also imports each from the module E2B defines it in, so `from e2b.exceptions import TimeoutException` becomes `from withruntime.e2b.exceptions import TimeoutException`, and `WriteEntry` comes from `withruntime.e2b.sandbox.filesystem.filesystem`. Each error also carries Runtime's `code`, `hint` and `requestId`, with the original error as `cause`. |
|
|
102
126
|
|
|
103
127
|
## Gaps
|
|
104
128
|
|
|
@@ -131,6 +155,10 @@ returns a handle with `get_new_events()` and `stop()`; asynchronous
|
|
|
131
155
|
a callback. Stream failures and lost events are reported, never treated as a
|
|
132
156
|
successful empty watch. A positive watch timeout bounds the client subscription and stops its owned watch;
|
|
133
157
|
zero leaves the subscription unlimited. The sandbox lease still applies. Both languages refuse watching network mounts.
|
|
158
|
+
As on envd, a path that is a file is refused with `InvalidArgumentError`
|
|
159
|
+
(Python: `InvalidArgumentException`). Runtime writes a file whole, by a rename
|
|
160
|
+
into place, which its watch sees as a create; a file's create is therefore
|
|
161
|
+
followed by a write event, which E2B code waiting for the write receives.
|
|
134
162
|
|
|
135
163
|
PTY `timeoutMs` (Python `timeout`, seconds) defaults to sixty seconds, including
|
|
136
164
|
the opening handshake; zero leaves the reader unlimited. Callbacks receive raw
|
|
@@ -161,7 +189,7 @@ every refusal: `tests/e2b` here and `sdks/python/tests/test_e2b_*.py`.
|
|
|
161
189
|
|
|
162
190
|
The end-to-end tests run an unmodified E2B program against the real API with
|
|
163
191
|
its one import changed. They create six sandboxes on the key's account. Each
|
|
164
|
-
has 2 vCPU and 512 MiB, lasts at most five minutes and is
|
|
192
|
+
has 2 vCPU and 512 MiB, lasts at most five minutes and is deleted when its
|
|
165
193
|
case ends. They are not part of `bun run test`.
|
|
166
194
|
|
|
167
195
|
```bash no-run
|
package/README.md
CHANGED
|
@@ -27,11 +27,12 @@ console.log(result.exitCode, result.stdout);
|
|
|
27
27
|
|
|
28
28
|
`Sandbox.create()` needs no arguments and returns once the sandbox is running;
|
|
29
29
|
`await using` stops it when the block ends (Node 24, Bun or TypeScript; on
|
|
30
|
-
Node 22 call `await sbx.stop()`). With no arguments you get the
|
|
31
|
-
|
|
30
|
+
Node 22 call `await sbx.stop()`). With no arguments you get the
|
|
31
|
+
included usage, a 1 GB machine running all month every month with no card (up to
|
|
32
|
+
eight sandboxes running at once without credit), 2 vCPU, 4 GiB of
|
|
32
33
|
memory and a 4 GiB disk. The current default image includes NumPy, pandas and
|
|
33
34
|
matplotlib; see the [sandbox environment](https://withruntime.com/docs/sandbox-environment).
|
|
34
|
-
The
|
|
35
|
+
The included usage is spent first, then prepaid credit, with nothing to
|
|
35
36
|
choose; `funding` is accepted and ignored.
|
|
36
37
|
|
|
37
38
|
The sandbox object does the rest:
|
package/README.src.md
CHANGED
|
@@ -29,11 +29,12 @@ console.log(result.exitCode, result.stdout);
|
|
|
29
29
|
|
|
30
30
|
`Sandbox.create()` needs no arguments and returns once the sandbox is running;
|
|
31
31
|
`await using` stops it when the block ends (Node 24, Bun or TypeScript; on
|
|
32
|
-
Node 22 call `await sbx.stop()`). With no arguments you get the
|
|
33
|
-
|
|
32
|
+
Node 22 call `await sbx.stop()`). With no arguments you get the
|
|
33
|
+
included usage, {{included-machine}} every month with no card (up to
|
|
34
|
+
{{trial-sandboxes}} sandboxes running at once without credit), 2 vCPU, 4 GiB of
|
|
34
35
|
memory and a 4 GiB disk. The current default image includes NumPy, pandas and
|
|
35
36
|
matplotlib; see the [sandbox environment](https://withruntime.com/docs/sandbox-environment).
|
|
36
|
-
The
|
|
37
|
+
The included usage is spent first, then prepaid credit, with nothing to
|
|
37
38
|
choose; `funding` is accepted and ignored.
|
|
38
39
|
|
|
39
40
|
The sandbox object does the rest:
|
package/compatibility-lock.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"checkedAt": "2026-
|
|
3
|
+
"checkedAt": "2026-10-05",
|
|
4
4
|
"providers": [
|
|
5
5
|
{
|
|
6
6
|
"id": "e2b",
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
{
|
|
10
10
|
"registry": "npm",
|
|
11
11
|
"name": "e2b",
|
|
12
|
-
"version": "2.52.
|
|
12
|
+
"version": "2.52.1",
|
|
13
13
|
"artifacts": {
|
|
14
|
-
"2.52.
|
|
14
|
+
"2.52.1": "sha512-qbX0s6qV2gfN4/+NBTIli1hkztfH/1kL4AEAYTaP4wjx7dp2m2wnXcN35iz+8Gug0q4TPN9w4xbdw/TGJr/Bpw=="
|
|
15
15
|
}
|
|
16
16
|
},
|
|
17
17
|
{
|
|
@@ -25,10 +25,10 @@
|
|
|
25
25
|
{
|
|
26
26
|
"registry": "pypi",
|
|
27
27
|
"name": "e2b",
|
|
28
|
-
"version": "2.52.
|
|
28
|
+
"version": "2.52.1",
|
|
29
29
|
"artifacts": {
|
|
30
|
-
"e2b-2.52.
|
|
31
|
-
"e2b-2.52.
|
|
30
|
+
"e2b-2.52.1-py3-none-any.whl": "sha256-708583a37c9b797b0044bd92fa407c21aec65f101f2fd4c4a0ccd842dbe33de1",
|
|
31
|
+
"e2b-2.52.1.tar.gz": "sha256-3af5c037b971ebc89a1ef0e5ced0e1c9ecbf3d65f2c23df5db7ad9faef8f68fa"
|
|
32
32
|
}
|
|
33
33
|
},
|
|
34
34
|
{
|
|
@@ -49,9 +49,9 @@
|
|
|
49
49
|
{
|
|
50
50
|
"registry": "npm",
|
|
51
51
|
"name": "@daytona/sdk",
|
|
52
|
-
"version": "0.
|
|
52
|
+
"version": "0.222.0",
|
|
53
53
|
"artifacts": {
|
|
54
|
-
"0.
|
|
54
|
+
"0.222.0": "sha512-N0hjbprttUcAQE3eBegzRNIhQTzbPOGAuS2LJvl4a6bLp3rjCY1R7G9HbE9STepiBQDAs5B08Vv1rpRTXw9PaA=="
|
|
55
55
|
}
|
|
56
56
|
},
|
|
57
57
|
{
|
|
@@ -66,25 +66,25 @@
|
|
|
66
66
|
{
|
|
67
67
|
"registry": "npm",
|
|
68
68
|
"name": "@daytona/api-client",
|
|
69
|
-
"version": "0.
|
|
69
|
+
"version": "0.222.0",
|
|
70
70
|
"artifacts": {
|
|
71
|
-
"0.
|
|
71
|
+
"0.222.0": "sha512-KvD+k6LMaqauQBedbMPTZG3UK3oITwmI5onfqbQJOdEG3xD6Occ3dJRphPlXqfF7tdtmDiXv3yrbyyOusqjvdA=="
|
|
72
72
|
}
|
|
73
73
|
},
|
|
74
74
|
{
|
|
75
75
|
"registry": "npm",
|
|
76
76
|
"name": "@daytona/toolbox-api-client",
|
|
77
|
-
"version": "0.
|
|
77
|
+
"version": "0.222.0",
|
|
78
78
|
"artifacts": {
|
|
79
|
-
"0.
|
|
79
|
+
"0.222.0": "sha512-crdx4Zoxjtd7sGoURS3Dwd0xEQ+6lW6e+tu45TgUx85BpDAoTEr0z7i13HgXcEfAYMIcj8o70FOlI5JlkEJ5dw=="
|
|
80
80
|
}
|
|
81
81
|
},
|
|
82
82
|
{
|
|
83
83
|
"registry": "npm",
|
|
84
84
|
"name": "@daytona/analytics-api-client",
|
|
85
|
-
"version": "0.
|
|
85
|
+
"version": "0.222.0",
|
|
86
86
|
"artifacts": {
|
|
87
|
-
"0.
|
|
87
|
+
"0.222.0": "sha512-KNIk2b21pLzKMdKPnz+7cOXE9Qjvlfe9hwfiIdAatxa9jYbwJQTmbxs7BpdDB7I9GtdUionpdskxJWL+rVcWvA=="
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
]
|
package/dist/blaxel/errors.js
CHANGED
|
@@ -94,15 +94,15 @@ const BLAXEL_HINTS = {
|
|
|
94
94
|
cwd_not_found: "Make the directory with sandbox.fs.mkdir(path), or pass an existing workingDir to sandbox.process.exec.",
|
|
95
95
|
sandbox_paused: "Call sandbox.unarchive(), then try again.",
|
|
96
96
|
not_running: "The sandbox is not running: call sandbox.unarchive() if it was archived, or make a new one with SandboxInstance.create if it was deleted.",
|
|
97
|
-
|
|
98
|
-
public_preview_not_allowed: "
|
|
97
|
+
no_credit_running_limit: "The sandboxes an account without credit runs at once are all in use: delete one you no longer need (sandbox.delete()) or archive it (sandbox.archive()), then try again. Moving to paid credit is the account owner's decision.",
|
|
98
|
+
public_preview_not_allowed: "Without credit, share the port privately: sandbox.previews.create({ metadata: { name }, spec: { port, public: false } }) and a token from preview.tokens.create(expiresAt) on a server supporting absolute preview deadlines. A public preview needs a paid sandbox, which is the account owner's decision.",
|
|
99
99
|
busy: AGAIN,
|
|
100
100
|
guest_busy: AGAIN,
|
|
101
101
|
rate_limited: AGAIN,
|
|
102
102
|
unauthorized: "Set RUNTIME_API_KEY to a Runtime key (https://withruntime.com/account/keys), or run `npx withruntime login` once. A Blaxel key (BL_API_KEY) is never sent.",
|
|
103
103
|
};
|
|
104
104
|
/** A trial create over the trial's size, in Blaxel's field. */
|
|
105
|
-
const TRIAL_CAP = "
|
|
105
|
+
const TRIAL_CAP = "Without credit, a sandbox has at most 4096 MB of memory (2 vCPUs); pass memory 4096 or add credit.";
|
|
106
106
|
/** A Runtime SDK error as Blaxel's: ResponseError (SandboxGatewayError for a
|
|
107
107
|
* 502, 503 or 504), NotSupportedError for a product Runtime has switched off,
|
|
108
108
|
* CredentialsError when there is no Runtime key. Anything else passes through
|
|
@@ -118,7 +118,7 @@ export function translate(error) {
|
|
|
118
118
|
return new NotSupportedError(error.code.replace(/_unavailable$/, ""), error.hint ?? "", error.message);
|
|
119
119
|
if (error.status < 200 || error.status > 599)
|
|
120
120
|
return error;
|
|
121
|
-
const trialCap = error.code === "
|
|
121
|
+
const trialCap = error.code === "no_credit_size_limit";
|
|
122
122
|
const hint = trialCap ? undefined : (BLAXEL_HINTS[error.code] ?? error.hint);
|
|
123
123
|
const message = [
|
|
124
124
|
trialCap ? TRIAL_CAP : error.message,
|
package/dist/blaxel/sandbox.d.ts
CHANGED
|
@@ -127,8 +127,7 @@ export declare class SandboxInstance {
|
|
|
127
127
|
get expiresIn(): number | undefined;
|
|
128
128
|
/** Creates a sandbox and answers once it runs. Blaxel's defaults: the base
|
|
129
129
|
* image (Runtime's stock image) and 4096 MB, with vCPUs at one per 2048 MB.
|
|
130
|
-
* Funding is left to Runtime: the
|
|
131
|
-
* time, then prepaid credit. A name another live sandbox holds is refused
|
|
130
|
+
* Funding is left to Runtime: the included usage first, then prepaid credit. A name another live sandbox holds is refused
|
|
132
131
|
* with a 409, as in Blaxel. */
|
|
133
132
|
static create<T extends typeof SandboxInstance>(this: T, sandbox?: SandboxCreateConfiguration | SandboxModel, { createIfNotExist }?: {
|
|
134
133
|
safe?: boolean;
|
package/dist/blaxel/sandbox.js
CHANGED
|
@@ -523,8 +523,7 @@ export class SandboxInstance {
|
|
|
523
523
|
// ---- create, get, list ---------------------------------------------------
|
|
524
524
|
/** Creates a sandbox and answers once it runs. Blaxel's defaults: the base
|
|
525
525
|
* image (Runtime's stock image) and 4096 MB, with vCPUs at one per 2048 MB.
|
|
526
|
-
* Funding is left to Runtime: the
|
|
527
|
-
* time, then prepaid credit. A name another live sandbox holds is refused
|
|
526
|
+
* Funding is left to Runtime: the included usage first, then prepaid credit. A name another live sandbox holds is refused
|
|
528
527
|
* with a 409, as in Blaxel. */
|
|
529
528
|
static async create(sandbox, { createIfNotExist = false } = {}) {
|
|
530
529
|
const config = configOf(sandbox);
|
package/dist/cli.d.ts
CHANGED
|
@@ -30,7 +30,7 @@ declare const kit: {
|
|
|
30
30
|
};
|
|
31
31
|
export type CliKit = typeof kit;
|
|
32
32
|
export declare function run(argv: string[], env?: NodeJS.ProcessEnv, out?: Out): Promise<number>;
|
|
33
|
-
/** `runtime usage` for a person: the balance, the
|
|
33
|
+
/** `runtime usage` for a person: the balance, the included usage and what each kind
|
|
34
34
|
* of resource was charged, in dollars. --json keeps every figure, and each
|
|
35
35
|
* resource with its rates and CPU time. */
|
|
36
36
|
/** One row per resource, for a spreadsheet: when it ran, how big it was, how
|
package/dist/cli.js
CHANGED
|
@@ -36,7 +36,7 @@ Account
|
|
|
36
36
|
The account's audit log (owner or admin keys)
|
|
37
37
|
sso Single sign-on and SCIM directory sync (owner or
|
|
38
38
|
admin keys); an owner changes it on the website
|
|
39
|
-
usage [--csv] Balance,
|
|
39
|
+
usage [--csv] Balance, included usage and charges; --csv, each resource
|
|
40
40
|
usage export --since <UTC time> --until <UTC time>
|
|
41
41
|
Every settlement in the range as CSV; --json, each page
|
|
42
42
|
limits Whether this key is read-only, and its daily spending limit
|
|
@@ -695,16 +695,18 @@ export async function run(argv, env = process.env, out = defaultOut(argv)) {
|
|
|
695
695
|
const [who, spend] = await Promise.all([rt.me(), rt.usage().catch(() => undefined)]);
|
|
696
696
|
const trialLeft = spend?.trial ? spend.trial.availableMs / 3_600_000 : 0;
|
|
697
697
|
const credit = spend ? BigInt(spend.available) : 0n;
|
|
698
|
+
// A pilot's sandboxes run on the pilot, before anything else and free.
|
|
698
699
|
const funding = !spend
|
|
699
700
|
? undefined
|
|
700
701
|
: [
|
|
702
|
+
...(spend.pilot ? [pilotFunding(spend.pilot)] : []),
|
|
701
703
|
...(trialLeft > 0
|
|
702
704
|
? [
|
|
703
|
-
`
|
|
705
|
+
`included usage, ${trialLeft.toLocaleString("en-US", { maximumFractionDigits: 1 })} hours left without credit`,
|
|
704
706
|
]
|
|
705
707
|
: []),
|
|
706
708
|
...(credit > 0n ? [`${dollars(credit)} of credit`] : []),
|
|
707
|
-
].join("; ") || "no
|
|
709
|
+
].join("; ") || "no included usage or credit left: runtime billing";
|
|
708
710
|
print(table([
|
|
709
711
|
["organization", who.orgName ? `${who.orgName} (${who.orgId})` : who.orgId],
|
|
710
712
|
...(who.role ? [["role", who.role]] : []),
|
|
@@ -765,7 +767,10 @@ export async function run(argv, env = process.env, out = defaultOut(argv)) {
|
|
|
765
767
|
return 0;
|
|
766
768
|
}
|
|
767
769
|
if (command === "limits") {
|
|
768
|
-
const
|
|
770
|
+
const rt = await client(env);
|
|
771
|
+
// The usage call only adds the pilot's line: a key that cannot read it
|
|
772
|
+
// still gets its limits.
|
|
773
|
+
const [l, spend] = await Promise.all([rt.limits.get(), rt.usage().catch(() => undefined)]);
|
|
769
774
|
// As `usage` shows money: $0.0014 of spend read $0.00 until 30 September 2026.
|
|
770
775
|
const usd = (micros) => dollars(micros);
|
|
771
776
|
const access = l.access === "read"
|
|
@@ -783,7 +788,13 @@ export async function run(argv, env = process.env, out = defaultOut(argv)) {
|
|
|
783
788
|
],
|
|
784
789
|
["used, last 24 hours", usd(l.daily.usedMicros)],
|
|
785
790
|
...(l.daily.remainingMicros === null ? [] : [["left", usd(l.daily.remainingMicros)]]),
|
|
786
|
-
...(l.trial ? [["free
|
|
791
|
+
...(l.trial ? [["free time", trialLeft(l.trial)]] : []),
|
|
792
|
+
...(spend?.pilot
|
|
793
|
+
? [
|
|
794
|
+
["pilot", pilotFunding(spend.pilot)],
|
|
795
|
+
["pilot sandbox hours", pilotLeft(spend.pilot)],
|
|
796
|
+
]
|
|
797
|
+
: []),
|
|
787
798
|
]), l);
|
|
788
799
|
return 0;
|
|
789
800
|
}
|
|
@@ -1029,7 +1040,7 @@ export async function run(argv, env = process.env, out = defaultOut(argv)) {
|
|
|
1029
1040
|
}
|
|
1030
1041
|
throw unknown("command", command, COMMANDS);
|
|
1031
1042
|
}
|
|
1032
|
-
/** `runtime usage` for a person: the balance, the
|
|
1043
|
+
/** `runtime usage` for a person: the balance, the included usage and what each kind
|
|
1033
1044
|
* of resource was charged, in dollars. --json keeps every figure, and each
|
|
1034
1045
|
* resource with its rates and CPU time. */
|
|
1035
1046
|
/** One row per resource, for a spreadsheet: when it ran, how big it was, how
|
|
@@ -1083,15 +1094,42 @@ export function usageCsv(u) {
|
|
|
1083
1094
|
}
|
|
1084
1095
|
/** Milliseconds as hours, to a tenth: "8,731.2". */
|
|
1085
1096
|
const hours = (ms) => (ms / 3_600_000).toLocaleString("en-US", { maximumFractionDigits: 1 });
|
|
1086
|
-
/** The
|
|
1097
|
+
/** The machine time left without credit, as `runtime usage` and `runtime
|
|
1098
|
+
* limits` say it: this month's included usage, as hours at 2 vCPU and 4 GiB,
|
|
1099
|
+
* or for an account given free hours before 5 October 2026, those hours too. */
|
|
1087
1100
|
function trialLeft(trial) {
|
|
1088
|
-
|
|
1101
|
+
const renews = trial.renewsAt ? `, renews ${trial.renewsAt.slice(0, 10)}` : "";
|
|
1102
|
+
return trial.totalMs > 0
|
|
1103
|
+
? `${hours(trial.availableMs)} hours left (${hours(trial.totalMs)} free hours given before 5 October 2026, and the included usage${renews})`
|
|
1104
|
+
: `${hours(trial.availableMs)} hours at 2 vCPU and 4 GiB left this month${renews}`;
|
|
1105
|
+
}
|
|
1106
|
+
/** This month's included usage, one row per product, as `runtime usage`
|
|
1107
|
+
* says it. */
|
|
1108
|
+
function allowanceRows(allowances) {
|
|
1109
|
+
const amount = (n) => n.toLocaleString("en-US", { maximumFractionDigits: 1 });
|
|
1110
|
+
return allowances.map((a) => [
|
|
1111
|
+
`included ${a.pool.replace(/-/g, " ")}`,
|
|
1112
|
+
`${amount(a.left)} of ${amount(a.quantity)} ${a.unit}s left`,
|
|
1113
|
+
]);
|
|
1114
|
+
}
|
|
1115
|
+
/** What a pilot gives, as `runtime whoami` and `runtime limits` say it: the
|
|
1116
|
+
* sandboxes it runs free and until when, past which credit does not run
|
|
1117
|
+
* them. */
|
|
1118
|
+
function pilotFunding(pilot) {
|
|
1119
|
+
const at = (iso) => `${iso.slice(0, 16).replace("T", " ")} UTC`;
|
|
1120
|
+
return `a pilot: up to ${pilot.sandboxes.toLocaleString("en-US")} sandboxes free, running until ${at(pilot.graceEndsAt)}; credit does not run it; to extend it, write to support`;
|
|
1089
1121
|
}
|
|
1090
1122
|
/** A pilot's sandbox hours left, as `runtime usage` says them. */
|
|
1091
1123
|
function pilotLeft(pilot) {
|
|
1092
1124
|
const left = `${hours(pilot.leftMs)} of ${pilot.hours.toLocaleString("en-US")} left`;
|
|
1125
|
+
// How long they last at the rate its sandboxes run now (an API before
|
|
1126
|
+
// 0414 does not say how many run).
|
|
1127
|
+
const running = pilot.running ?? 0;
|
|
1128
|
+
const pace = running > 0
|
|
1129
|
+
? `; at ${running.toLocaleString("en-US")} running, about ${hours(pilot.leftMs / running)} hours`
|
|
1130
|
+
: "";
|
|
1093
1131
|
return pilot.leftMs > 0
|
|
1094
|
-
? `${left}; new pilot sandboxes until ${pilot.endsAt.slice(0, 16).replace("T", " ")} UTC`
|
|
1132
|
+
? `${left}${pace}; new pilot sandboxes until ${pilot.endsAt.slice(0, 16).replace("T", " ")} UTC`
|
|
1095
1133
|
: "This pilot's sandbox hours are used.";
|
|
1096
1134
|
}
|
|
1097
1135
|
function usageSummary(u) {
|
|
@@ -1114,7 +1152,9 @@ function usageSummary(u) {
|
|
|
1114
1152
|
if (micros(u.expired) > 0n)
|
|
1115
1153
|
rows.push(["expired or taken back", dollars(micros(u.expired))]);
|
|
1116
1154
|
if (u.trial)
|
|
1117
|
-
rows.push(["free
|
|
1155
|
+
rows.push(["free time", trialLeft(u.trial)]);
|
|
1156
|
+
if (u.allowances)
|
|
1157
|
+
rows.push(...allowanceRows(u.allowances));
|
|
1118
1158
|
if (u.pilot)
|
|
1119
1159
|
rows.push(["pilot sandbox hours", pilotLeft(u.pilot)]);
|
|
1120
1160
|
if (u.outbound) {
|
|
@@ -1126,7 +1166,15 @@ function usageSummary(u) {
|
|
|
1126
1166
|
]);
|
|
1127
1167
|
}
|
|
1128
1168
|
const kinds = new Map();
|
|
1129
|
-
|
|
1169
|
+
// Every resource, by kind, from an API that totals them (6 October 2026);
|
|
1170
|
+
// an older one sends only its hundred newest, counted here.
|
|
1171
|
+
for (const k of u.kinds ?? [])
|
|
1172
|
+
kinds.set(k.kind, {
|
|
1173
|
+
count: k.resources,
|
|
1174
|
+
charged: micros(k.chargedMicros),
|
|
1175
|
+
held: micros(k.heldMicros),
|
|
1176
|
+
});
|
|
1177
|
+
for (const resource of u.kinds ? [] : (u.resources ?? [])) {
|
|
1130
1178
|
const kind = typeof resource.kind === "string" ? resource.kind : "other";
|
|
1131
1179
|
const entry = kinds.get(kind) ?? { count: 0, charged: 0n, held: 0n };
|
|
1132
1180
|
entry.count++;
|
|
@@ -1305,7 +1353,7 @@ function runningTime(seconds) {
|
|
|
1305
1353
|
});
|
|
1306
1354
|
return `${shown} ${unit}${shown === "1" ? "" : "s"}`;
|
|
1307
1355
|
}
|
|
1308
|
-
/** The sandboxes
|
|
1356
|
+
/** The sandboxes free usage paid for, said beside what was priced. */
|
|
1309
1357
|
function trialNote(trial, all, trialSeconds) {
|
|
1310
1358
|
if (!trial)
|
|
1311
1359
|
return "";
|
|
@@ -1314,7 +1362,7 @@ function trialNote(trial, all, trialSeconds) {
|
|
|
1314
1362
|
? "It"
|
|
1315
1363
|
: "All of them"
|
|
1316
1364
|
: `${trial} of them, ${runningTime(trialSeconds)} of that time,`;
|
|
1317
|
-
return ` ${which} ran on
|
|
1365
|
+
return ` ${which} ran on free usage, which charged nothing; Runtime's side prices ${trial === 1 ? "it" : "them"} at the standard rates, what the same work costs on paid credit.`;
|
|
1318
1366
|
}
|
|
1319
1367
|
async function switching(command, argv, env, out) {
|
|
1320
1368
|
const args = parse(argv, [], command === "compare" ? ["from", "days"] : ["from"]);
|
|
@@ -2808,7 +2856,7 @@ read = readSecret) {
|
|
|
2808
2856
|
const JOB_HELP = `runtime job <command>
|
|
2809
2857
|
|
|
2810
2858
|
A job runs a command in a fresh sandbox, once or on a schedule. Each run spends
|
|
2811
|
-
the
|
|
2859
|
+
the included usage first, then credit at the sandbox rates.
|
|
2812
2860
|
|
|
2813
2861
|
create <name> (--cron "<min hour day month weekday>" [--timezone Europe/Berlin] | --at <time|now>)
|
|
2814
2862
|
[--vcpu 2] [--memory 4096] [--disk 4096] [--cpu shared|reserved] [--cpu-floor <thousandths>]
|
|
@@ -3254,7 +3302,7 @@ const CREATE_FLAGS = [
|
|
|
3254
3302
|
"get-or-create",
|
|
3255
3303
|
];
|
|
3256
3304
|
/** Says on standard error, once for each reason, why a create has not
|
|
3257
|
-
* answered yet: it is waiting for a
|
|
3305
|
+
* answered yet: it is waiting for a slot without credit or room, which can take up to
|
|
3258
3306
|
* two minutes, and silence reads as a hang. */
|
|
3259
3307
|
function waiting(out) {
|
|
3260
3308
|
const said = new Set();
|