withruntime 0.12.0 → 0.16.0
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 +97 -32
- package/COMPATIBILITY.md +120 -5
- package/DAYTONA.md +34 -3
- package/E2B.md +34 -5
- package/README.md +36 -3
- package/README.src.md +35 -2
- package/VERCEL.md +52 -5
- package/compatibility-lock.json +71 -111
- package/dist/billing-cli.js +8 -4
- package/dist/blaxel/client.d.ts +11 -0
- package/dist/blaxel/client.js +28 -0
- package/dist/blaxel/errors.d.ts +65 -0
- package/dist/blaxel/errors.js +114 -0
- package/dist/blaxel/index.d.ts +10 -3
- package/dist/blaxel/index.js +23 -4
- package/dist/blaxel/preview.d.ts +29 -4
- package/dist/blaxel/preview.js +79 -5
- package/dist/blaxel/sandbox.d.ts +1 -1
- package/dist/blaxel/sandbox.js +2 -1
- package/dist/blaxel/session.js +4 -2
- package/dist/cli-extras.js +2 -1
- package/dist/cli-words.js +1 -0
- package/dist/cli.d.ts +17 -2
- package/dist/cli.js +291 -85
- package/dist/client.d.ts +1 -1
- package/dist/credentials.d.ts +3 -0
- package/dist/credentials.js +15 -0
- package/dist/daytona/client.d.ts +4 -0
- package/dist/daytona/client.js +8 -3
- package/dist/daytona/daytona.d.ts +4 -1
- package/dist/daytona/daytona.js +3 -2
- package/dist/e2b/sandbox.d.ts +7 -6
- package/dist/e2b/sandbox.js +9 -12
- package/dist/errors.d.ts +1 -1
- package/dist/errors.js +1 -1
- package/dist/freestyle/index.d.ts +77 -5
- package/dist/freestyle/index.js +380 -48
- package/dist/identity.js +36 -18
- package/dist/index.d.ts +4 -3
- package/dist/machine.d.ts +39 -13
- package/dist/machine.js +72 -25
- package/dist/mcp.js +157 -20
- package/dist/modal/index.d.ts +15 -0
- package/dist/modal/index.js +35 -7
- package/dist/morph/index.d.ts +255 -0
- package/dist/morph/index.js +641 -0
- package/dist/network-cli.js +2 -2
- package/dist/product-names.d.ts +2 -2
- package/dist/product-names.js +2 -2
- package/dist/products/api-keys.d.ts +73 -0
- package/dist/products/api-keys.js +23 -0
- package/dist/products/apps.d.ts +12 -31
- package/dist/products/apps.js +8 -113
- package/dist/products/balancers.d.ts +87 -0
- package/dist/products/balancers.js +8 -0
- package/dist/products/builds.d.ts +30 -0
- package/dist/products/builds.js +6 -0
- package/dist/products/index.d.ts +2 -0
- package/dist/products/index.js +2 -0
- package/dist/products/jobs.d.ts +2 -2
- package/dist/products/jobs.js +1 -1
- package/dist/products/limits.d.ts +16 -2
- package/dist/products/limits.js +2 -2
- package/dist/products/mcp.d.ts +5 -0
- package/dist/products/network-products.d.ts +21 -3
- package/dist/products/network-products.js +3 -1
- package/dist/products/observability.d.ts +7 -2
- package/dist/products/previews.d.ts +6 -3
- package/dist/products/previews.js +1 -1
- package/dist/products/resources.d.ts +54 -0
- package/dist/products/resources.js +122 -0
- package/dist/products/secrets.d.ts +22 -0
- package/dist/products/secrets.js +8 -0
- package/dist/products/volumes.d.ts +3 -0
- package/dist/sandbox.d.ts +4 -0
- package/dist/sandbox.js +27 -2
- package/dist/snapshots.d.ts +4 -0
- package/dist/ssh.d.ts +35 -0
- package/dist/ssh.js +93 -1
- package/dist/transport.d.ts +14 -8
- package/dist/transport.js +70 -15
- package/dist/types.d.ts +33 -5
- package/dist/vercel/command.d.ts +48 -1
- package/dist/vercel/command.js +237 -6
- package/dist/vercel/sandbox-user.js +2 -1
- package/dist/vercel/sandbox.d.ts +17 -3
- package/dist/vercel/sandbox.js +46 -3
- package/dist/wallet.d.ts +4 -1
- package/dist/wallet.js +2 -1
- package/package.json +7 -14
- package/dist/cli/logs.test.d.ts +0 -1
- package/dist/cli/logs.test.js +0 -272
- package/dist/products/logs.test.d.ts +0 -1
- package/dist/products/logs.test.js +0 -343
package/BLAXEL.md
CHANGED
|
@@ -11,8 +11,11 @@ import { SandboxInstance } from "withruntime/blaxel"; // was: from "@blaxel/core
|
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
The mapping was written against `@blaxel/core` 0.3.24 and Blaxel's sandbox API
|
|
14
|
-
source, checked 30 September 2026
|
|
15
|
-
|
|
14
|
+
source, checked 30 September 2026, and checked against `@blaxel/core` 0.3.30
|
|
15
|
+
and `blaxel` 0.4.18 on PyPI on 16 October 2026 (below, "0.3.30 and 0.4.18").
|
|
16
|
+
The exact releases and artifact hashes are kept in `compatibility-lock.json`.
|
|
17
|
+
Every name `@blaxel/core` exports can be imported: code that only mentions an
|
|
18
|
+
agent, model or MCP helper still loads.
|
|
16
19
|
|
|
17
20
|
## Keys
|
|
18
21
|
|
|
@@ -84,35 +87,38 @@ name, or through `getByExternalId`, use the same Runtime key.
|
|
|
84
87
|
|
|
85
88
|
## Mapping
|
|
86
89
|
|
|
87
|
-
| Blaxel
|
|
88
|
-
|
|
|
89
|
-
| `SandboxInstance.create({ name, image, memory, labels, ports, envs, ... })`
|
|
90
|
-
| `createIfNotExists`
|
|
91
|
-
| `get(name)`, `getByExternalId`, `list({ limit, externalId, showTerminated })`
|
|
92
|
-
| `delete` (static and on the sandbox)
|
|
93
|
-
| `metadata`, `spec`, `status`, `state`, `lastUsedAt`, `expiresIn`
|
|
94
|
-
| `updateMetadata`, `updateTtl`, `updateLifecycle`, `updateNetwork`
|
|
95
|
-
| `archive`, `unarchive`
|
|
96
|
-
| `network: { allowedDomains, forbiddenDomains, proxy }`
|
|
97
|
-
| `volumes: [{ name, mountPath }]`
|
|
98
|
-
| `fetch(port, path, init)`
|
|
99
|
-
| `process.exec` without `waitForCompletion`
|
|
100
|
-
| `process.exec({ waitForCompletion: true })`
|
|
101
|
-
| `onLog`, `onStdout`, `onStderr`, `streamLogs`
|
|
102
|
-
| `process.get`, `wait`, `list`, `logs`, `stop`, `kill`, `writeStdin`, `closeStdin`
|
|
103
|
-
| `keepAlive`, `timeout`
|
|
104
|
-
| `restartOnFailure`, `maxRestarts`, `waitForPorts`, `workingDir`, `env`, `stdin`
|
|
105
|
-
| `fs.read`, `write`, `readBinary`, `writeBinary`, `writeTree`, `mkdir`, `rm`, `cp`
|
|
106
|
-
| `fs.ls`, `find`, `grep`, `search`
|
|
107
|
-
| `fs.watch(path, callback, { withContent, ignore })`, `fs.download`
|
|
108
|
-
| `previews.create`, `createIfNotExists`, `get`, `list`, `delete`
|
|
109
|
-
| `preview.tokens.
|
|
110
|
-
| `
|
|
111
|
-
| `
|
|
112
|
-
| `
|
|
113
|
-
| `
|
|
114
|
-
| `
|
|
115
|
-
| `
|
|
90
|
+
| Blaxel | On Runtime |
|
|
91
|
+
| ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
92
|
+
| `SandboxInstance.create({ name, image, memory, labels, ports, envs, ... })` | `sandboxes.create`. A name another live sandbox holds is a 409, as in Blaxel; one held by a sandbox still being deleted is waited for. |
|
|
93
|
+
| `createIfNotExists` | `create` with `getOrCreate`: Runtime settles two callers racing for one name, and both get the one sandbox. An existing sandbox is answered as it is. |
|
|
94
|
+
| `get(name)`, `getByExternalId`, `list({ limit, externalId, showTerminated })` | The live sandbox with that name, or with the `externalId` label; Blaxel's paginated list (`data`, `nextPage`, `for await`, `autoPagingToArray`). |
|
|
95
|
+
| `delete` (static and on the sandbox) | `stop`: the sandbox ends at once. Using that object afterwards is a 404. |
|
|
96
|
+
| `metadata`, `spec`, `status`, `state`, `lastUsedAt`, `expiresIn` | From the Runtime sandbox and its `blaxel/` labels (image, memory, ports, region, TTL, expiry, lifecycle, archived), which any client reads; `state` is `STANDBY` while paused. |
|
|
97
|
+
| `updateMetadata`, `updateTtl`, `updateLifecycle`, `updateNetwork` | Labels (the display name and `externalId` are labels); the paused retention, as at create; network rules. |
|
|
98
|
+
| `archive`, `unarchive` | `pause`, `wake`. Runtime keeps memory and processes too, and the next call wakes it. |
|
|
99
|
+
| `network: { allowedDomains, forbiddenDomains, proxy }` | Runtime network rules: `allow` and `deny`. |
|
|
100
|
+
| `volumes: [{ name, mountPath }]` | The Runtime volume with that name, mounted read-write. |
|
|
101
|
+
| `fetch(port, path, init)` | The request goes to a private Runtime preview of the port (made on first use, then reused) with its token. |
|
|
102
|
+
| `process.exec` without `waitForCompletion` | One Runtime process, answered running. Its Blaxel name is kept in its command line, so `get("name")` finds it from any client. |
|
|
103
|
+
| `process.exec({ waitForCompletion: true })` | One streamed call, answered with `status`, `exitCode`, `stdout`, `stderr` and `logs`. Past `timeout` the wait ends with a 422 and the process runs on. |
|
|
104
|
+
| `onLog`, `onStdout`, `onStderr`, `streamLogs` | The process's output as it comes; `streamLogs` gives whole lines, as Blaxel's does. |
|
|
105
|
+
| `process.get`, `wait`, `list`, `logs`, `stop`, `kill`, `writeStdin`, `closeStdin` | Runtime processes by id or name. `wait` follows output with one deadline covering lookup and output. Cancellation leaves the process running. `stop` is SIGTERM, `kill` SIGKILL. |
|
|
106
|
+
| `keepAlive`, `timeout` | The sandbox does not pause for idleness while the process may run (its `timeout`, 600 s by default, 0 for as long as a lease allows); once no `keepAlive` process runs, it gets its idle pause back. |
|
|
107
|
+
| `restartOnFailure`, `maxRestarts`, `waitForPorts`, `workingDir`, `env`, `stdin` | A restart loop in the same process, with Blaxel's note in the output (`restartCount` counts the notes); a wait in the sandbox for the ports; as in Blaxel. |
|
|
108
|
+
| `fs.read`, `write`, `readBinary`, `writeBinary`, `writeTree`, `mkdir`, `rm`, `cp` | Runtime's files API, or one command. A path only root may read or write (outside `/workspace`, or made by a root process) goes through sudo, as Blaxel's root-owned API could. |
|
|
109
|
+
| `fs.ls`, `find`, `grep`, `search` | One command each, with Blaxel's defaults, limits and excluded directories. `ls` reports owners. |
|
|
110
|
+
| `fs.watch(path, callback, { withContent, ignore })`, `fs.download` | A Runtime watch (`path/**` for subdirectories); a download to the local disk. |
|
|
111
|
+
| `previews.create`, `createIfNotExists`, `get`, `list`, `delete` | Runtime previews of `spec.port`, public or private. The Blaxel name is kept in a label, so any client finds it by name. The shorthand `{ port, name?, public? }` is a private `preview-<port>` unless it says otherwise; `createIfNotExists` answers an existing one as it is. |
|
|
112
|
+
| `preview.tokens.createIfExpired(expiresAt?, minValidity?)` | The token this call made last in this process for the sandbox's port, while it lasts `minValidity` more and ends by `expiresAt`; else a new one. Runtime keeps no list of tokens, so a new process makes a new one. |
|
|
113
|
+
| `isBlaxelError`, `getBlaxelErrorCode`, `getBlaxelErrorStatus`, `getBlaxelErrorMessage`, `getBlaxelErrorRequestId` | Blaxel's readers over the errors here. A `ResponseError`'s code is its HTTP status, as its `code` is; its request id is Runtime's. |
|
|
114
|
+
| `settings.integration`, `initialize({ integration })`, `BL_INTEGRATION` | Kept and checked as Blaxel does (`<name>/<semver>`, warned once and `""` otherwise); never sent, as Runtime does not attribute traffic by it. |
|
|
115
|
+
| `preview.tokens.create(expiresAt)` | A token for that long: at least a minute, at most a week. It is read from Blaxel's `X-Blaxel-Preview-Token` header or `?bl_preview_token=` as from Runtime's `x-runtime-preview-token` and `?runtime_preview_token=`, and never passed on to your server. |
|
|
116
|
+
| `snapshots.create`, `list`, `get`, `delete`; `Snapshot.create`, `get`, `list`, `fork` | Runtime snapshots, kept 365 days: files, memory and running processes. |
|
|
117
|
+
| `fork(name)`, `fork(name, { snapshotId, envs })` | A Runtime fork of the running sandbox, or a new sandbox from the snapshot (by id, or by name among this sandbox's); `envs` are added over the source's. |
|
|
118
|
+
| `CodeInterpreter.create`, `runCode`, `createCodeContext` | Runtime's interpreter, with the same result classes. The sandbox's envs reach every context. |
|
|
119
|
+
| `sandbox.sessions.create`, `createIfExpired`, `list`, `get`, `delete` | A Runtime sandbox session: a token for commands, files and previews of this one sandbox, for a day unless `expiresAt` says sooner (a day at most). `responseHeaders["Access-Control-Allow-Origin"]` names the pages that may use it; `*`, other response headers and `requestHeaders` are refused. `createIfExpired` reuses the session this process made last; a token is shown only when made. |
|
|
120
|
+
| `SandboxInstance.fromSession(session)` | The sandbox, driven with the session's token alone; anything that manages the sandbox is refused. |
|
|
121
|
+
| `ResponseError`, `SandboxGatewayError`, `isGatewayError`, `isGatewayTimeout` | Runtime's errors by Blaxel's names: `status` and `code` are the HTTP status; `runtimeCode`, `hint` and `requestId` are Runtime's. |
|
|
116
122
|
|
|
117
123
|
## Gaps
|
|
118
124
|
|
|
@@ -184,6 +190,65 @@ Some differences are not refusals:
|
|
|
184
190
|
- A preview token shorter than a minute lasts a minute. Deleting one token
|
|
185
191
|
revokes every token of that preview.
|
|
186
192
|
|
|
193
|
+
## 0.3.30 and 0.4.18, 16 October 2026
|
|
194
|
+
|
|
195
|
+
Reviewed the published npm tarball of `@blaxel/core` 0.3.29 → 0.3.30 and the
|
|
196
|
+
PyPI wheel and sdist of `blaxel` 0.4.17 → 0.4.18, each its registry's latest
|
|
197
|
+
when checked. The pinned files matched `compatibility-lock.json`, the new ones
|
|
198
|
+
their registry's SHA-512 integrity or SHA-256 digest, and the wheel's source is
|
|
199
|
+
byte for byte its sdist's. They were compared file by file; nothing was
|
|
200
|
+
installed or run outside the oracle. The npm package's dependencies did not
|
|
201
|
+
change.
|
|
202
|
+
|
|
203
|
+
| Upstream change | Drop-in disposition |
|
|
204
|
+
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
205
|
+
| Workspace secrets, which Blaxel's proxy puts into a sandbox's routing as `{{SECRET:name}}`: the generated API calls `listSecrets`, `upsertSecret`, `deleteSecret`, `deleteSecretByQuery`; Python `SecretInstance`, `SyncSecretInstance` (`set`, `list`, `delete`), `SecretAPIError` and `blaxel.core.secret`. | Importable and refused with `NotSupportedError` naming Runtime secrets, `runtime.secrets.set(name, { value, hosts })`: a Runtime secret names the hosts it may reach, which Blaxel's calls do not, and the drop-in already refuses Blaxel's proxy routing. `SecretAPIError` is a `BlaxelError`, never raised. Before, the imports failed. |
|
|
206
|
+
| `deleteDriveFolder` in the generated API. | Importable and refused, as every drive call is. |
|
|
207
|
+
| The SDK sends an "Installed SDK" event to PostHog once per version (internal `common/posthog`, not exported). | Nothing to follow: the drop-in sends nothing to Blaxel or its analytics. |
|
|
208
|
+
| Custom domains' `validationMethod`, the `kernelExtensions` extra argument, and doc text (the 60 s floor of `ttl-idle`). | Nothing new to do: custom domains are refused, an extra argument other than `iptables` is refused, and the drop-in has no `ttl-idle` floor (a paused sandbox is kept whole days). |
|
|
209
|
+
|
|
210
|
+
`tests/blaxel/blaxel-0-3-30.test.ts` (2) and
|
|
211
|
+
`sdks/python/tests/test_blaxel_0_4_18.py` (2) fail without this change; the
|
|
212
|
+
export list moves to 0.3.30's 275 names. `compat-inventory.json`: blaxel 611
|
|
213
|
+
present, 123 refused, 31 missing of 765 before; 616, 123, 31 of 770 now.
|
|
214
|
+
blaxel-python 375, 11, 652 of 1038 before; 388, 11, 672 of 1071 now (the
|
|
215
|
+
inventory counts the Python stand-ins, as `ImageInstance` before them, as
|
|
216
|
+
missing).
|
|
217
|
+
|
|
218
|
+
## 0.3.29 and 0.4.17, 15 October 2026
|
|
219
|
+
|
|
220
|
+
Reviewed the published npm tarball of `@blaxel/core` 0.3.25 → 0.3.29 and the
|
|
221
|
+
PyPI wheel and sdist of `blaxel` 0.4.13 → 0.4.17 (0.3.26 to 0.3.28 and 0.4.14
|
|
222
|
+
to 0.4.16 came out between, all on 13 October). Each was its registry's latest
|
|
223
|
+
when checked. The pinned files matched the hashes already in
|
|
224
|
+
`compatibility-lock.json`, the new ones their registry's SHA-512 integrity or
|
|
225
|
+
SHA-256 digest, and each wheel's Python source is byte for byte its sdist's.
|
|
226
|
+
They were compared file by file; nothing was installed or run outside the
|
|
227
|
+
oracle, which runs 0.3.29 and passes. The npm package's dependencies did not
|
|
228
|
+
change. Python's `withruntime.blaxel` follows the same changes under Python's
|
|
229
|
+
names: `BlaxelError`, `is_blaxel_error(err, code=None)`,
|
|
230
|
+
`SandboxPreviewCreateConfiguration`, `create_if_expired(expires_at=None,
|
|
231
|
+
min_validity=timedelta(hours=1))`, `settings.integration`.
|
|
232
|
+
|
|
233
|
+
| Upstream change | Drop-in disposition |
|
|
234
|
+
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
235
|
+
| Error helpers `isBlaxelError`, `getBlaxelErrorCode`, `getBlaxelErrorStatus`, `getBlaxelErrorMessage`, `getBlaxelErrorRequestId` and the error code and body types. Python: `BlaxelError` becomes the base of `ResponseError` and every `*APIError`, with `status`, `code`, `request_id`, `retryable` and the rest, and `is_blaxel_error`. | Followed. The helpers read the drop-in's errors with Blaxel's rules; a request id with no Blaxel header is Runtime's. In Python every API error the drop-in raises is a `BlaxelError`: `status` is the HTTP status, `code` Runtime's code, `request_id` Runtime's, `retryable` Runtime's own judgement; Blaxel's gateway fields are None. `VolumeAPIError` and `blaxel.core.errors` import. |
|
|
236
|
+
| `previews.create` and `createIfNotExists` take `{ port, name?, public? }` (Python: a dict or `SandboxPreviewCreateConfiguration`): a private `preview-<port>` by default, checked with `RangeError` (Python `ValueError`); an existing preview is answered as it is. | Followed, with Blaxel's checks and messages, before anything is shared. Before, the shorthand failed (`spec.port is required`, or a TypeError in `createIfNotExists`). |
|
|
237
|
+
| `preview.tokens.createIfExpired(expiresAt?, minValidity?)` reuses the latest listed token that lasts `minValidity` (an hour) more and ends by `expiresAt` (a day), else makes one; a public preview is refused. | Followed. Runtime keeps no list of the tokens it signs, so the token reused is the one this call made last in this process for the sandbox's port; arguments and the public refusal are Blaxel's, checked before any request. Revoking the preview's tokens (`tokens.delete`) forgets it. |
|
|
238
|
+
| `SandboxPreview.url`, `SandboxPreviewToken.name`. | Followed. |
|
|
239
|
+
| `settings.integration`, `Config.integration` and `BL_INTEGRATION`: a `<name>/<semver>` token appended to Blaxel's User-Agent. | Kept and checked as Blaxel does, warned once when invalid, never sent: it only attributes traffic to Blaxel. Before, `settings.integration` threw `NotSupportedError`. Python's `settings.user_agent` and other settings still raise `NotSupportedError`. |
|
|
240
|
+
| `fs.search` now sends its query (it was dropped). | Nothing to do: the drop-in's search always used it. |
|
|
241
|
+
| `ImageInstance` takes `buildMemory`, `buildVolume`, `buildRegion`; generated API clients gain `headFilesystemByPath`, service-account `role`, and doc text; Python's resource errors keep the response. | Nothing to follow: `ImageInstance` and the generated API calls stay refused with Runtime's alternative (`runtime.images`, `SandboxInstance`). Python's `ResponseError.from_api_response`, which wraps a generated-client response, now raises `NotSupportedError` saying so. |
|
|
242
|
+
|
|
243
|
+
`tests/blaxel/blaxel-0-3-29.test.ts` (9) and
|
|
244
|
+
`sdks/python/tests/test_blaxel_0_4_17.py` (9) fail without this change. The
|
|
245
|
+
export list moves to 0.3.29's 270 names. `compat-inventory.json`, regenerated
|
|
246
|
+
from the verified packages: blaxel 596 present, 123 refused, 31 missing before
|
|
247
|
+
(of 750); 611, 123, 31 now (of 765). blaxel-python 252, 9, 642 before (of
|
|
248
|
+
903, 0.4.13 exported fewer names from `blaxel.core`); 375, 11, 652 now (of
|
|
249
|
+
1038). The pinned-official Python tests (`RUNTIME_COMPAT_OFFICIAL=1`) were not
|
|
250
|
+
run against 0.4.17.
|
|
251
|
+
|
|
187
252
|
## The process line
|
|
188
253
|
|
|
189
254
|
A process's command line, which both this package and the Python one write
|
|
@@ -207,7 +272,7 @@ leaves those names alone.
|
|
|
207
272
|
|
|
208
273
|
`bun run test` in `packages/cloud-sdk` runs the unit tests against a fake of
|
|
209
274
|
Runtime's SDK: `tests/blaxel`, including a check that every name
|
|
210
|
-
`@blaxel/core` 0.3.
|
|
275
|
+
`@blaxel/core` 0.3.30 exports is exported here.
|
|
211
276
|
|
|
212
277
|
The end-to-end test runs Blaxel's guides, unmodified but for the import,
|
|
213
278
|
against the real API: `tests/fixtures/blaxel-quickstart.mjs` (create, processes,
|
package/COMPATIBILITY.md
CHANGED
|
@@ -14,19 +14,134 @@ interface for it. Python coverage is in the Python SDK's compatibility documents
|
|
|
14
14
|
The Cloudflare module implements the 0.x `@cloudflare/sandbox` API. Version 1.0.0,
|
|
15
15
|
published 30 September 2026, is a different package: it removes `getSandbox`, the
|
|
16
16
|
`Sandbox` class, `exec`, processes, sessions and preview proxying, and keeps only
|
|
17
|
-
`Files`, `S3Mount` and `DirectoryBackup` for the caller's own Durable Object.
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
`Files`, `S3Mount` and `DirectoryBackup` for the caller's own Durable Object.
|
|
18
|
+
Version 1.0.1 (13 October 2026) is the same API: its `dist/index.mjs` is byte for
|
|
19
|
+
byte 1.0.0's, its declarations export the same names inline instead of in one
|
|
20
|
+
list, its `zod` dependency moves from 4.5.4 to 4.6.5, and README example links
|
|
21
|
+
change. The pin stays 0.12.10; `compatibility-lock.json` records 1.0.0 and 1.0.1
|
|
22
|
+
as reviewed and unsupported, and `bun run compat:upstream` flags any other release.
|
|
20
23
|
|
|
21
24
|
| Provider | Published package inspected | Runtime import | Implemented sandbox surface |
|
|
22
25
|
| ----------- | --------------------------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
23
26
|
| Runloop | `@runloop/api-client` 2.0.0 | `withruntime/runloop` | `Runloop`, basic `RunloopSDK` command handles, devbox create/get/list/suspend/resume/shutdown, disk snapshots; synchronous and asynchronous commands, resident named shells with variables, functions, aliases, options and working directory, execution completion/output/stdin/signals, text files |
|
|
24
27
|
| CodeSandbox | `@codesandbox/sdk` 2.4.2 | `withruntime/codesandbox` | `CodeSandbox`, `VMTier`, create/fork/resume/shutdown/restart/hibernate/delete/list/get; connected command and file clients; output/status subscriptions and same-client command restart; configured tasks and setup steps; public preview ports and readiness checks |
|
|
25
28
|
| Fly Sprites | `@fly/sprites` 0.2.3 | `withruntime/sprites` | `SpritesClient`, create/lookup/list/delete/restart; `exec`, `execFile`, Node streams and event-based `spawn`; attachable native processes; binary/text/JSON files, directory traversal, append, chmod, chown and `asRoot` through sudo, file watches; preview access settings; checkpoints as disk snapshots; domain network policy; session kill; port watcher and port proxy; `APIError` with the vendor's limit codes |
|
|
26
|
-
| Freestyle | `freestyle` 0.2.
|
|
27
|
-
|
|
|
29
|
+
| Freestyle | `freestyle` 0.2.20 | `withruntime/freestyle` | `Freestyle`, VM create/ref/get/list/start/pause/delete/update; command execution, binary/text files and streams, filesystem metadata; native snapshots; explicit deny-all or outbound-public firewall intent |
|
|
30
|
+
| Morph | `morphcloud` 0.0.20 | `withruntime/morph` | `MorphCloudClient`, images list, snapshot create/get/list/delete/metadata and cached `setup` chains, instance start/boot/get/list/stop/pause/resume/branch/snapshot, metadata, wake-on, TTL at start, streamed exec, HTTP services as previews, file `sync` |
|
|
31
|
+
| Modal | `modal` 0.11.1 | `withruntime/modal` | `ModalClient`, app-name grouping, registry images and Dockerfile layers, CPU sandbox create/get/list/name lookup, text/binary process streams and stdin, command completion, filesystem transfer and metadata, tags, encrypted public previews, outbound allowlists, memory snapshot capture |
|
|
28
32
|
| Cloudflare | `@cloudflare/sandbox` 0.12.10 (0.x API) | `withruntime/cloudflare` | `getSandbox`, named Runtime sandboxes, explicit execution sessions, text exec and SSE output, background processes, logs/signals/waits, binary/text files, recursive listings, environment updates, signed Runtime previews, conditional Worker Durable Object entry, Worker preview proxy, destruction |
|
|
29
33
|
|
|
34
|
+
### Modal 0.11.1 review (16 October 2026)
|
|
35
|
+
|
|
36
|
+
The pin advances from 0.11.0 to 0.11.1; support remains partial. Both npm
|
|
37
|
+
tarballs were fetched into an empty directory, matched the lock (0.11.0) and
|
|
38
|
+
the registry (0.11.1), and were compared file by file without installing or
|
|
39
|
+
executing them. Only `package.json`, `README.md` and the four `dist` files
|
|
40
|
+
change; most of the declaration diff is generated protobuf types. The public
|
|
41
|
+
changes, and what `withruntime/modal` does with each:
|
|
42
|
+
|
|
43
|
+
- `sandboxes.fromName` and `experimentalFromName` take `includeTerminated`:
|
|
44
|
+
when no sandbox of that name runs, the most recent terminated one is
|
|
45
|
+
returned. Followed: a running sandbox of the name still wins, otherwise the
|
|
46
|
+
stopped one with the latest end time. Before, the option was refused as
|
|
47
|
+
unknown.
|
|
48
|
+
- `client.environments` (`EnvironmentService`, `EnvironmentObjectsService`,
|
|
49
|
+
`Environment`, `EnvironmentAppsService`) looks up, creates, lists and
|
|
50
|
+
deletes Modal Environments. Refused before any request, as the
|
|
51
|
+
`environment` options already are: a Runtime account's sandboxes share one
|
|
52
|
+
namespace, grouped by app name and tags.
|
|
53
|
+
- `App.info()` returns an App's lifecycle and its Functions and Servers.
|
|
54
|
+
Refused, naming `client.sandboxes.list({ appId })`: a Runtime app is a label
|
|
55
|
+
on its sandboxes, with no lifecycle, Functions or Servers.
|
|
56
|
+
- `volumes.fromName` takes a VolumeFS `version` (1 or 2). Refused when given:
|
|
57
|
+
a Runtime volume has one format.
|
|
58
|
+
- Sidecars take `includeOidcIdentityToken` and `proxy`; sidecars were already
|
|
59
|
+
refused as a whole. `functions.fromId`, `Function_.stats()`,
|
|
60
|
+
`Function_.metrics` (`FunctionMetricsManager`) and the deprecation of
|
|
61
|
+
`FunctionTimeoutError` for `FunctionCall.get` timeouts are Functions, outside
|
|
62
|
+
the CPU sandbox scope (`FunctionMetricsManager` joins the inventory's
|
|
63
|
+
outside list). Not followed, with nothing to follow: an internal `keys`
|
|
64
|
+
argument leaves `Secret`'s constructor, `execWait` and `Sandbox._wait` take
|
|
65
|
+
an internal abort signal, `smol-toml` moves from ^1.3.3 to ^1.9.0, and the
|
|
66
|
+
README links a sidecar identity-token example.
|
|
67
|
+
|
|
68
|
+
`tests/compat/modal-0-11-1.test.ts` fails on the old adapter;
|
|
69
|
+
`compat-inventory.json` records 221 present, 168 refused and 0 missing of 389.
|
|
70
|
+
`tests/compat/reference.bun.lock` records the new `smol-toml` range; it
|
|
71
|
+
already resolved 1.9.0, so the opt-in reference install is unchanged (not
|
|
72
|
+
rerun here).
|
|
73
|
+
|
|
74
|
+
### Morph 0.0.20 (15 October 2026)
|
|
75
|
+
|
|
76
|
+
`morphcloud` 0.0.20 (npm, 6 October 2025, the latest) is the TypeScript SDK;
|
|
77
|
+
all 73 inventory items are present or refused, none missing. How it maps:
|
|
78
|
+
|
|
79
|
+
- An instance is a sandbox; a snapshot is a Runtime snapshot; metadata are
|
|
80
|
+
labels (`compat.provider` and `morph.*` stay the adapter's). `stop` deletes
|
|
81
|
+
the sandbox, as Morph's stop deletes the instance; snapshots stay.
|
|
82
|
+
- `snapshots.create` boots the image at its size, keeps its disk and deletes
|
|
83
|
+
the sandbox. `morphvm-minimal` is Runtime's default image; another id must
|
|
84
|
+
be a Runtime image. A digest becomes the snapshot's name (`morph-` and its
|
|
85
|
+
SHA-256), so `setup` caches by Morph's chain hash.
|
|
86
|
+
- `branch(n)` is one fork with the snapshot kept: copies keep memory and
|
|
87
|
+
running processes.
|
|
88
|
+
- `ttlSeconds` is the time limit (60 to 86400); `ttlAction` stop deletes,
|
|
89
|
+
pause pauses. Runtime also pauses an idle sandbox after a minute and wakes
|
|
90
|
+
it on the next request, which Morph does not.
|
|
91
|
+
- `exposeHttpService` is a preview: public with no `auth_mode` (needs a kept
|
|
92
|
+
top-up), private with `api_key` (send its token as `x-runtime-preview-token`).
|
|
93
|
+
- `exec` of a string or one-item array runs in a shell, a longer array as
|
|
94
|
+
arguments; 24 hours by default; a timeout throws as Morph's does.
|
|
95
|
+
- Refused, naming the alternative: `ssh`, `sshKey`, `sshKeyRotate` (use
|
|
96
|
+
`runtime sandboxes ssh`), `reboot`, `setTTL` after start, `sync` with
|
|
97
|
+
delete/dry run/.gitignore, and the raw `GET`/`POST`/`DELETE` verbs.
|
|
98
|
+
- `bun scripts/compatibility-morph-live.ts --run` runs the quickstart, setup
|
|
99
|
+
cache, HTTP service, pause and resume, branch and snapshot calls against the
|
|
100
|
+
real API.
|
|
101
|
+
- Morph's richer Python SDK (`morphcloud` 0.1.115, PyPI) has its own adapter,
|
|
102
|
+
`withruntime.morph`, inventoried as `morph-python`; see
|
|
103
|
+
[the Python document](../../sdks/python/COMPATIBILITY.md).
|
|
104
|
+
|
|
105
|
+
### Freestyle 0.2.18, 0.2.19 and 0.2.20 review (15 October 2026)
|
|
106
|
+
|
|
107
|
+
The pin advances from 0.2.17 to 0.2.20; support remains partial. The four npm
|
|
108
|
+
tarballs were fetched into an empty directory, matched the lock (0.2.17) and
|
|
109
|
+
the registry (the rest), and were compared file by file without installing or
|
|
110
|
+
executing them.
|
|
111
|
+
|
|
112
|
+
- 0.2.18, PTY connections. `open` and `attach` take `reconnect` (`true` or
|
|
113
|
+
`timeoutMs`, `initialDelayMs`, `maxDelayMs`), `connectTimeoutMs`,
|
|
114
|
+
`onStateChange`, `onReplayStart` and `onReplayEnd`, and check the timers
|
|
115
|
+
with a `RangeError`; `PtySession` gains `ready`, `state` and `reconnect()`;
|
|
116
|
+
`write` and `signal` throw `PTY is not connected` while disconnected and
|
|
117
|
+
`resize` is remembered and applied again after a reattachment; `detach`
|
|
118
|
+
cancels recovery and reports `Detached` once. Before, the adapter refused
|
|
119
|
+
each new option with `CompatibilityError`. Now a dropped connection is
|
|
120
|
+
reattached to the same Runtime process with Freestyle's backoff, after
|
|
121
|
+
checking the process still exists (a 4xx other than 409 or 429 ends the
|
|
122
|
+
session), and nothing typed is replayed. A Runtime terminal replays the
|
|
123
|
+
session's output from its start on each connection without marking where
|
|
124
|
+
the replay ends, as Freestyle's older guest agents do, so the replay
|
|
125
|
+
callbacks never fire and a replay begins at the `connected` state. Runtime
|
|
126
|
+
terminals send no keepalive, so a silent connection is not timed out; the
|
|
127
|
+
browser's online and visibility events retry a closed session. A first
|
|
128
|
+
connection waits `connectTimeoutMs` only when given (no wait limit before).
|
|
129
|
+
- 0.2.18, new `connectXterm({ pty, terminal, slug, ... })` and the
|
|
130
|
+
`XtermTerminal` and `ConnectXtermOptions` types: implemented on the same
|
|
131
|
+
sessions, with reconnect on by default, the screen reset at each
|
|
132
|
+
connection, and the replay's terminal queries muted until it is written.
|
|
133
|
+
- 0.2.18, browser PTYs now need an identity access token (a WebSocket
|
|
134
|
+
subprotocol). Identity tokens are refused here; Runtime terminals
|
|
135
|
+
authenticate with the Runtime key. `@xterm/xterm` is a new dev dependency
|
|
136
|
+
only, so the reference install is unchanged.
|
|
137
|
+
- 0.2.18, `PtySessionInfo.slug` is now documented as kept after the shell
|
|
138
|
+
exits, until the session is closed (`open`'s get-or-create doc already
|
|
139
|
+
said so). Not followed: Runtime keeps exited processes and cannot remove
|
|
140
|
+
one, so a slug kept after exit could never be opened afresh. A slug is
|
|
141
|
+
still released when its shell exits.
|
|
142
|
+
- 0.2.19 changes only its version. 0.2.20 adds `expiresAt` to identity access
|
|
143
|
+
tokens, in the identities product this adapter does not provide.
|
|
144
|
+
|
|
30
145
|
### Freestyle 0.2.17 review (11 October 2026)
|
|
31
146
|
|
|
32
147
|
The pin advances from 0.2.16; support remains partial. The exact npm tarballs
|
package/DAYTONA.md
CHANGED
|
@@ -17,8 +17,8 @@ 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, and checked against `@daytona/sdk` and `daytona` 0.
|
|
21
|
-
|
|
20
|
+
on PyPI, and checked against `@daytona/sdk` and `daytona` 0.224.1 on
|
|
21
|
+
15 October 2026 (below, "0.224.1"). The exact releases and artifact hashes
|
|
22
22
|
are kept in `compatibility-lock.json`.
|
|
23
23
|
|
|
24
24
|
## Keys
|
|
@@ -97,7 +97,7 @@ Each of these throws `NotSupportedError` before anything happens. Its
|
|
|
97
97
|
| --------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
98
98
|
| A snapshot name with no Runtime image or snapshot | `daytona.snapshot.create({ name, image })` here, or `npx withruntime images build`. This throws `DaytonaNotFoundError`. |
|
|
99
99
|
| 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()`. |
|
|
100
|
-
| A `target` other than `us
|
|
100
|
+
| A `target` other than `us` (the client's or a create's), `jwtToken` | Runtime runs in one US region and signs in with keys. |
|
|
101
101
|
| The entrypoint session, language servers | Sessions with `runAsync`. |
|
|
102
102
|
| Screenshots of a region, with the cursor, scaled, or as WebP | The whole screen as PNG or JPEG; crop and scale it yourself. |
|
|
103
103
|
| `computerUse.accessibility`, the desktop's processes one by one | Screenshots with the mouse and keyboard; `computerUse.getStatus()`, `stop()` and `start()`. |
|
|
@@ -126,6 +126,37 @@ Some differences are not refusals:
|
|
|
126
126
|
- `autoArchiveInterval` is recorded only: Runtime has no archive tier.
|
|
127
127
|
- Runtime's stock image is Ubuntu 24.04 with Python 3.12, Node.js 24 and Bun.
|
|
128
128
|
|
|
129
|
+
## 0.224.1, 15 October 2026
|
|
130
|
+
|
|
131
|
+
Reviewed the published npm tarballs for `@daytona/sdk`, `@daytona/api-client`,
|
|
132
|
+
`@daytona/toolbox-api-client` and `@daytona/analytics-api-client` 0.223.1 →
|
|
133
|
+
0.224.1, and the PyPI wheel and sdist for `daytona` 0.223.1 → 0.224.1 (0.224.0,
|
|
134
|
+
published between them, was also fetched: on npm, 0.224.1 adds only the stream
|
|
135
|
+
decoder change and the dependency floors below; on PyPI it is the same source
|
|
136
|
+
with a new version). Each was its registry's latest when checked. Every pinned
|
|
137
|
+
file matched the hash already in `compatibility-lock.json`, and every new file
|
|
138
|
+
matched its registry's SHA-512 integrity or SHA-256 digest; the wheel's Python
|
|
139
|
+
source is byte for byte its sdist's. Nothing was installed, imported or run.
|
|
140
|
+
The three API clients changed only their version. `@daytona/sdk` changed
|
|
141
|
+
`Daytona` (create params and the client's `target` docs), `Snapshot` (docs),
|
|
142
|
+
and its output stream decoder, ESM and CommonJS alike; `daytona` changed the
|
|
143
|
+
same, sync and async, plus the async PTY handle.
|
|
144
|
+
|
|
145
|
+
| Upstream change | Drop-in disposition |
|
|
146
|
+
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
147
|
+
| `daytona.create({ target })` (Python `target` on `CreateSandboxFromSnapshotParams` and `CreateSandboxFromImageParams`) picks the region for that create, over the client's `target`. | Followed, in both languages. `"us"` or none creates the sandbox in Runtime's one region; any other is refused with the same `NotSupportedError` as a client `target`, before anything is built or made. Before, TypeScript dropped it without a word and Python raised `TypeError`. |
|
|
148
|
+
| The client's `target` (and `DAYTONA_TARGET`) and a snapshot's `regionId` (Python `region_id`) are documented as the default region, overridden per call. | Documentation only; the client's `target` is checked as before. TypeScript already refused a snapshot `regionId`; Python accepted `region_id` and dropped it, and now refuses it the same way (`""` still means the default). |
|
|
149
|
+
| The output stream decoder finds an stdout or stderr marker that ends exactly at the end of a message, which it held back before, and buffers in linear time. | Not applicable: the drop-in takes output from Runtime's exec, which keeps stdout and stderr apart, and never parses Daytona's markers. |
|
|
150
|
+
| Python `AsyncPtyHandle.wait()` shields its reader, so cancelling a caller's wait (for example `asyncio.wait_for`) leaves the PTY connected. | Already so: the drop-in's `wait()` awaits `asyncio.shield` of its reader task. |
|
|
151
|
+
| `@daytona/sdk` requires `ws` exactly 8.22.0 (was ^8.22.0), `@aws-sdk/client-s3` and `lib-storage` ^3.1146.0 and `shell-quote` ^1.12.0. | The oracle's `bun.lock` moves with them (ws stays 8.22.0). |
|
|
152
|
+
|
|
153
|
+
`tests/daytona/daytona-0-224-1.test.ts` and
|
|
154
|
+
`sdks/python/tests/test_daytona_0_224_1.py` check a create's `target` both
|
|
155
|
+
ways, that it overrides the client's, and (Python) that a snapshot's
|
|
156
|
+
`region_id` is refused; they fail without this change. The oracle was not run
|
|
157
|
+
against the new release, since it executes Daytona's code; the provider
|
|
158
|
+
remains marked `partial`.
|
|
159
|
+
|
|
129
160
|
## 0.223.1, 9 October 2026
|
|
130
161
|
|
|
131
162
|
Reviewed the published npm tarballs for `@daytona/sdk`, `@daytona/api-client`,
|
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.
|
|
24
|
-
and `@e2b/code-interpreter` 2.
|
|
25
|
-
against `e2b` 2.
|
|
23
|
+
The mapping was written against `e2b` 2.51.0 and checked against `e2b` 2.56.0
|
|
24
|
+
and `@e2b/code-interpreter` 2.9.0 on 15 October 2026. Python was checked
|
|
25
|
+
against `e2b` 2.56.0 and `e2b-code-interpreter` 2.11.0 the same day. The exact
|
|
26
26
|
package releases and artifact hashes are kept in `compatibility-lock.json`.
|
|
27
27
|
|
|
28
28
|
## Keys
|
|
@@ -111,7 +111,7 @@ account the key belongs to and where the key came from.
|
|
|
111
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`. |
|
|
112
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. |
|
|
113
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)` |
|
|
114
|
+
| `sandbox.setTimeout(ms)`, `Sandbox.setTimeout(id, ms)` | The sandbox's time limit becomes now + ms, sooner or later than before, up to 24 hours (an update's `timeoutSeconds`; under a minute is a minute), and its end still does what it was created to. A sandbox with no time limit gets one; a persistent one (a pilot's) has none to set, and nothing changes. |
|
|
115
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`. |
|
|
116
116
|
| `sandbox.pause()`, `betaPause`, `Sandbox.pause(id)` | `pause`, keeping memory and files. `false` when it was already paused. |
|
|
117
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. |
|
|
@@ -134,7 +134,6 @@ before anything happens. The error's `feature` names the gap and its
|
|
|
134
134
|
| ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
|
|
135
135
|
| An E2B template name with no Runtime image of that name | Build it: `npx withruntime images build --dockerfile e2b.Dockerfile --name <template>`. This throws `TemplateError`. |
|
|
136
136
|
| `Template`, `waitForPort` and the other ready checks | `runtime.images.build(...)` |
|
|
137
|
-
| `setTimeout` to an earlier time | `kill()` when the work is done. |
|
|
138
137
|
| A pause with `mode: "filesystem"` or `keepMemory: false` | Runtime's pause keeps memory. For the files alone, `createSnapshot({ mode: "filesystem" })`. |
|
|
139
138
|
| `onResume: "reboot"` | Stop the sandbox and create a new one. |
|
|
140
139
|
| `fork({ timeoutMs })` | Fork without it, then call `setTimeout` on each fork. |
|
|
@@ -260,3 +259,33 @@ source files changed, one was removed, and one interpreter file changed.
|
|
|
260
259
|
modes, the refusals, their messages and the new exports; they fail without
|
|
261
260
|
this change. The official differential contracts were not run against the new
|
|
262
261
|
releases, since they execute E2B's code; the provider remains marked `partial`.
|
|
262
|
+
|
|
263
|
+
## e2b 2.56.0, 15 October 2026
|
|
264
|
+
|
|
265
|
+
Reviewed the published npm tarballs for `e2b` 2.55.0 → 2.56.0 and
|
|
266
|
+
`@e2b/code-interpreter` 2.8.3 → 2.9.0, and the PyPI wheels and sdists for
|
|
267
|
+
`e2b` 2.55.1 → 2.56.0 and `e2b-code-interpreter` 2.10.5 → 2.11.0. Each was
|
|
268
|
+
npm's or PyPI's latest when checked. Every pinned file matched the hash already
|
|
269
|
+
in `compatibility-lock.json`, and every new file matched its registry's SHA-512
|
|
270
|
+
integrity or SHA-256 digest; each wheel's Python source is byte for byte its
|
|
271
|
+
sdist's. Nothing was installed, imported or run for the review. JavaScript
|
|
272
|
+
sources were read from the source maps. The declarations (`index.d.ts`) of
|
|
273
|
+
both npm packages and the `__init__.py` of both Python packages are byte for
|
|
274
|
+
byte unchanged, so the public surface is the same: the recomputed
|
|
275
|
+
`compat-inventory.json` has the same items, only the upstream paths move.
|
|
276
|
+
|
|
277
|
+
| Upstream change | Drop-in disposition |
|
|
278
|
+
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
279
|
+
| JavaScript: the process-wide in-flight request caps are removed (`src/api/inflight.ts` and the `E2B_API_INFLIGHT_REQUESTS`, `E2B_ENVD_INFLIGHT_REQUESTS`, `E2B_ENVD_RPC_INFLIGHT_REQUESTS` variables, which threw on a negative value). Requests are bounded by undici's connections only. | No change: the drop-in never read these variables. Its own connection cap (`E2B_MAX_CONNECTIONS` in `src/e2b/client.ts`, 4096) is Runtime's and unchanged. |
|
|
280
|
+
| JavaScript: `undici` 8.11.2 becomes the only undici (the `undici8` alias and the undici 7 fallback are gone); below Node 22.19 the global `fetch` is used. `engines.node` is now `>=22.19.0`, `@e2b/dockerfile-utils` `^0.1.1` (0.1.1 changes only its own version and engines). | Not mirrored: the drop-in uses Runtime's transport and keeps `node >=22.12`. The oracle lock moves to `e2b` 2.56.0 with `undici` 8.11.2 and `@e2b/dockerfile-utils` 0.1.1. |
|
|
281
|
+
| Python: the per-origin `ConnectionBalancer` over several pyqwest pools is replaced by one pool with `max_connections_per_address` (pyqwest `>=0.12,<0.13`); `E2B_STREAMS_PER_CONNECTION` is no longer read, and `E2B_MAX_CONNECTIONS` caps connections per resolved address. | No change: `e2b.api` and its clients are E2B's HTTP internals, which the drop-in leaves out; its connection limit is Runtime's own. |
|
|
282
|
+
| Python: `e2b` and `e2b-code-interpreter` require Python 3.11 (`sandbox/mcp.py` imports `NotRequired` from `typing`). | Not followed: `withruntime` keeps Python 3.10, so code moved off E2B on 3.10 keeps working. The official contracts install the new wheels, so that step runs on Python 3.11 (`prepare_compatibility.py` moves to a Python 3.11 or newer on the PATH when run under 3.10, as in CI). |
|
|
283
|
+
| `@e2b/code-interpreter` 2.9.0 and `e2b-code-interpreter` 2.11.0 change only their versions, dependency floors (`e2b ^2.56.0`) and engines. | Note only. |
|
|
284
|
+
|
|
285
|
+
No behaviour changed that the drop-ins mirror, so there is no new behaviour
|
|
286
|
+
test; `tests/e2b/exports.test.ts` and `sdks/python/tests/test_e2b_exports.py`
|
|
287
|
+
now name the new releases, whose export lists are the same. The oracle
|
|
288
|
+
(`oracle/check.mjs`, 37 passed) ran against `e2b` 2.56.0 and
|
|
289
|
+
`@e2b/code-interpreter` 2.9.0, and the Python official contracts (18 passed)
|
|
290
|
+
against the new wheels in an isolated virtualenv on Python 3.11 and 3.12. The
|
|
291
|
+
provider remains marked `partial`.
|
package/README.md
CHANGED
|
@@ -29,11 +29,11 @@ console.log(result.exitCode, result.stdout);
|
|
|
29
29
|
`await using` deletes it when the block ends (Node 24, Bun or TypeScript; on
|
|
30
30
|
Node 22 call `await sbx.delete()`), and `keep: true` stops it instead, keeping
|
|
31
31
|
its disk. With no arguments you get the
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
free usage, with no card (up to
|
|
33
|
+
four sandboxes running at once without credit), 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
|
-
The
|
|
36
|
+
The free usage is spent first, then prepaid credit, with nothing to
|
|
37
37
|
choose; `funding` is accepted and ignored.
|
|
38
38
|
|
|
39
39
|
The sandbox object does the rest:
|
|
@@ -147,6 +147,21 @@ with its token. A Blaxel key is never sent anywhere. Drives, codegen, schedules
|
|
|
147
147
|
`NotSupportedError` before anything happens, naming what to use instead.
|
|
148
148
|
`BLAXEL.md` in this package lists every mapping and gap.
|
|
149
149
|
|
|
150
|
+
## Code written for Morph Cloud
|
|
151
|
+
|
|
152
|
+
`withruntime/morph` translates Morph's TypeScript client (`morphcloud`).
|
|
153
|
+
Change the import:
|
|
154
|
+
|
|
155
|
+
```ts no-run
|
|
156
|
+
import { MorphCloudClient } from "withruntime/morph"; // was: from "morphcloud"
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Instances become sandboxes, snapshots Runtime snapshots, metadata labels and
|
|
160
|
+
HTTP services previews; `setup` caches by Morph's chain hash and `branch`
|
|
161
|
+
copies memory and processes. `stop` deletes the sandbox, as Morph's does.
|
|
162
|
+
SSH, reboot and a time limit set after start throw `CompatibilityError`
|
|
163
|
+
naming the alternative. `COMPATIBILITY.md` lists every mapping.
|
|
164
|
+
|
|
150
165
|
## Agent frameworks
|
|
151
166
|
|
|
152
167
|
`withruntime/openai-agents` is a sandbox client for the OpenAI Agents SDK's
|
|
@@ -183,6 +198,24 @@ connected yet, it offers `runtime_connect`, which walks you through the browser
|
|
|
183
198
|
approval. Remote clients add `https://api.withruntime.com/mcp` and sign in through
|
|
184
199
|
the browser, or send a bearer key.
|
|
185
200
|
|
|
201
|
+
## How Runtime compares
|
|
202
|
+
|
|
203
|
+
For typical agent work, Runtime costs 42% to 88% less than fourteen other
|
|
204
|
+
sandbox providers at their published rates. These pages show the arithmetic,
|
|
205
|
+
each with the rates it used and the date they were read:
|
|
206
|
+
|
|
207
|
+
- [Best sandbox for AI agents](https://withruntime.com/compare/best-sandbox-for-ai-agents)
|
|
208
|
+
- Alternatives to [E2B](https://withruntime.com/compare/e2b-alternatives),
|
|
209
|
+
[Daytona](https://withruntime.com/compare/daytona-alternatives),
|
|
210
|
+
[Modal](https://withruntime.com/compare/modal-alternatives) and
|
|
211
|
+
[Vercel Sandbox](https://withruntime.com/compare/vercel-sandbox-alternatives)
|
|
212
|
+
- [E2B vs Daytona](https://withruntime.com/compare/e2b-vs-daytona), and
|
|
213
|
+
[every comparison](https://withruntime.com/compare)
|
|
214
|
+
- [The agent sandbox price index](https://withruntime.com/pricing/agent-sandbox-price-index):
|
|
215
|
+
every provider's rates, also as CSV and JSON
|
|
216
|
+
- [Sandbox cost calculator](https://withruntime.com/calculators/sandbox-cost-calculator)
|
|
217
|
+
and [Runtime's pricing](https://withruntime.com/pricing)
|
|
218
|
+
|
|
186
219
|
## Reliability and support
|
|
187
220
|
|
|
188
221
|
- **Status:** https://withruntime.com/status checks the API from outside every
|