withruntime 0.8.2 → 0.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/BLAXEL.md CHANGED
@@ -85,54 +85,56 @@ name, or through `getByExternalId`, use the same Runtime key.
85
85
 
86
86
  ## Mapping
87
87
 
88
- | Blaxel | On Runtime |
89
- | ------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
90
- | `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. |
91
- | `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. |
92
- | `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`). |
93
- | `delete` (static and on the sandbox) | `stop`: the sandbox ends at once. Using that object afterwards is a 404. |
94
- | `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. |
95
- | `updateMetadata`, `updateTtl`, `updateLifecycle`, `updateNetwork` | Labels (the display name and `externalId` are labels); the paused retention, as at create; network rules. |
96
- | `archive`, `unarchive` | `pause`, `wake`. Runtime keeps memory and processes too, and the next call wakes it. |
97
- | `network: { allowedDomains, forbiddenDomains, proxy }` | Runtime network rules: `allow` and `deny`. |
98
- | `volumes: [{ name, mountPath }]` | The Runtime volume with that name, mounted read-write. |
99
- | `fetch(port, path, init)` | The request goes to a private Runtime preview of the port (made on first use, then reused) with its token. |
100
- | `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. |
101
- | `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. |
102
- | `onLog`, `onStdout`, `onStderr`, `streamLogs` | The process's output as it comes; `streamLogs` gives whole lines, as Blaxel's does. |
103
- | `process.get`, `wait`, `list`, `logs`, `stop`, `kill`, `writeStdin`, `closeStdin` | Runtime processes by id or name. `wait` follows the output instead of polling. `stop` is SIGTERM, `kill` SIGKILL. |
104
- | `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. |
105
- | `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. |
106
- | `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. |
107
- | `fs.ls`, `find`, `grep`, `search` | One command each, with Blaxel's defaults, limits and excluded directories. `ls` reports owners. |
108
- | `fs.watch(path, callback, { withContent, ignore })`, `fs.download` | A Runtime watch (`path/**` for subdirectories); a download to the local disk. |
109
- | `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. |
110
- | `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. |
111
- | `snapshots.create`, `list`, `get`, `delete`; `Snapshot.create`, `get`, `list`, `fork` | Runtime snapshots, kept 365 days: files, memory and running processes. |
112
- | `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. |
113
- | `CodeInterpreter.create`, `runCode`, `createCodeContext` | Runtime's interpreter, with the same result classes. The sandbox's envs reach every context. |
114
- | `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. |
88
+ | Blaxel | On Runtime |
89
+ | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
90
+ | `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. |
91
+ | `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. |
92
+ | `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`). |
93
+ | `delete` (static and on the sandbox) | `stop`: the sandbox ends at once. Using that object afterwards is a 404. |
94
+ | `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. |
95
+ | `updateMetadata`, `updateTtl`, `updateLifecycle`, `updateNetwork` | Labels (the display name and `externalId` are labels); the paused retention, as at create; network rules. |
96
+ | `archive`, `unarchive` | `pause`, `wake`. Runtime keeps memory and processes too, and the next call wakes it. |
97
+ | `network: { allowedDomains, forbiddenDomains, proxy }` | Runtime network rules: `allow` and `deny`. |
98
+ | `volumes: [{ name, mountPath }]` | The Runtime volume with that name, mounted read-write. |
99
+ | `fetch(port, path, init)` | The request goes to a private Runtime preview of the port (made on first use, then reused) with its token. |
100
+ | `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. |
101
+ | `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. |
102
+ | `onLog`, `onStdout`, `onStderr`, `streamLogs` | The process's output as it comes; `streamLogs` gives whole lines, as Blaxel's does. |
103
+ | `process.get`, `wait`, `list`, `logs`, `stop`, `kill`, `writeStdin`, `closeStdin` | Runtime processes by id or name. `wait` follows the output instead of polling. `stop` is SIGTERM, `kill` SIGKILL. |
104
+ | `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. |
105
+ | `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. |
106
+ | `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. |
107
+ | `fs.ls`, `find`, `grep`, `search` | One command each, with Blaxel's defaults, limits and excluded directories. `ls` reports owners. |
108
+ | `fs.watch(path, callback, { withContent, ignore })`, `fs.download` | A Runtime watch (`path/**` for subdirectories); a download to the local disk. |
109
+ | `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. |
110
+ | `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. |
111
+ | `snapshots.create`, `list`, `get`, `delete`; `Snapshot.create`, `get`, `list`, `fork` | Runtime snapshots, kept 365 days: files, memory and running processes. |
112
+ | `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. |
113
+ | `CodeInterpreter.create`, `runCode`, `createCodeContext` | Runtime's interpreter, with the same result classes. The sandbox's envs reach every context. |
114
+ | `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. |
115
+ | `SandboxInstance.fromSession(session)` | The sandbox, driven with the session's token alone; anything that manages the sandbox is refused. |
116
+ | `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. |
115
117
 
116
118
  ## Gaps
117
119
 
118
120
  Each of these throws `NotSupportedError` before anything happens. Its `feature`
119
121
  names the gap and its `alternative` says what to use.
120
122
 
121
- | Blaxel | Use instead |
122
- | ------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------- |
123
- | An `image` with no ready Runtime image of the name it maps to (Blaxel's other templates too) | Build it: `npx withruntime image build --dockerfile Dockerfile --name ns-name -t ns-name:tag`; the error gives the exact command. |
124
- | A region outside the US | Runtime runs in one US region. |
125
- | `extraArgs` other than `iptables`; network `egress`, `firewall`, `subnet`, and a `proxy` with more than its domain lists | Remove them; `allowedDomains` and `forbiddenDomains` (on the network or its proxy); Runtime secrets. |
126
- | Read-only and ephemeral volumes; a volume with no Runtime volume of that name | Mount read-write; write scratch files under `/workspace`; `runtime.volumes.create`. |
127
- | `snapshots.restore`, `restore` | Fork from the snapshot into a new sandbox. |
128
- | Forking into an application | Fork into a sandbox and share its port. |
129
- | A preview's `prefixUrl`, `customDomain`, `requestHeaders`, `responseHeaders`, `ttl` | Runtime's fixed preview address; set headers (CORS) in your server; delete the preview. |
130
- | `preview.tokens.list()`; a token for over a week | Keep the tokens you create; create a new one when it runs out. |
131
- | `runCode` with `envs` for one run; a language Runtime's interpreter lacks | Sandbox envs at create, or set them in the code; `process.exec`. |
132
- | Listing by `cursor`, `q`, `anchor`, a status other than `DEPLOYED`, or newest first | List and filter the result yourself; `nextPage()` walks the pages. |
133
- | `sandbox.sessions`, `schedules`, `codegen`, `system`, `drives`; `fromSession` | Previews and tokens; your own scheduler; `fs.write`; nothing to upgrade; Runtime volumes. |
134
- | Agents, models, tools, MCP transports, jobs, applications, images, volumes, drives | Your own agent with Runtime sandboxes, `withruntime/tools`, `npx withruntime mcp`, `runtime.images`, `runtime.volumes`. |
135
- | Blaxel's generated API functions (`createSandbox`, `postProcess`, ...) | `SandboxInstance` here, or `import { Runtime } from "withruntime"`. |
123
+ | Blaxel | Use instead |
124
+ | ------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------- |
125
+ | An `image` with no ready Runtime image of the name it maps to (Blaxel's other templates too) | Build it: `npx withruntime image build --dockerfile Dockerfile --name ns-name -t ns-name:tag`; the error gives the exact command. |
126
+ | A region outside the US | Runtime runs in one US region. |
127
+ | `extraArgs` other than `iptables`; network `egress`, `firewall`, `subnet`, and a `proxy` with more than its domain lists | Remove them; `allowedDomains` and `forbiddenDomains` (on the network or its proxy); Runtime secrets. |
128
+ | Read-only and ephemeral volumes; a volume with no Runtime volume of that name | Mount read-write; write scratch files under `/workspace`; `runtime.volumes.create`. |
129
+ | `snapshots.restore`, `restore` | Fork from the snapshot into a new sandbox. |
130
+ | Forking into an application | Fork into a sandbox and share its port. |
131
+ | A preview's `prefixUrl`, `customDomain`, `requestHeaders`, `responseHeaders`, `ttl` | Runtime's fixed preview address; set headers (CORS) in your server; delete the preview. |
132
+ | `preview.tokens.list()`; a token for over a week | Keep the tokens you create; create a new one when it runs out. |
133
+ | `runCode` with `envs` for one run; a language Runtime's interpreter lacks | Sandbox envs at create, or set them in the code; `process.exec`. |
134
+ | Listing by `cursor`, `q`, `anchor`, a status other than `DEPLOYED`, or newest first | List and filter the result yourself; `nextPage()` walks the pages. |
135
+ | `schedules`, `codegen`, `system`, `drives` | A Runtime job (`runtime.jobs.create`, a fresh sandbox each run) or your own scheduler; `fs.write`; nothing to upgrade; Runtime volumes. |
136
+ | Agents, models, tools, MCP transports, jobs, applications, images, volumes, drives | Your own agent with Runtime sandboxes, `withruntime/tools`, `npx withruntime mcp`, `runtime.images`, `runtime.volumes`. |
137
+ | Blaxel's generated API functions (`createSandbox`, `postProcess`, ...) | `SandboxInstance` here, or `import { Runtime } from "withruntime"`. |
136
138
 
137
139
  Some differences are not refusals:
138
140
 
package/DAYTONA.md CHANGED
@@ -85,22 +85,22 @@ package talks only to Runtime.
85
85
  Each of these throws `NotSupportedError` before anything happens. Its
86
86
  `feature` names the gap and its `alternative` says what to use.
87
87
 
88
- | Daytona | Use instead |
89
- | --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
90
- | A snapshot name with no Runtime image or snapshot | `daytona.snapshot.create({ name, image })` here, or `npx withruntime image build`. This throws `DaytonaNotFoundError`. |
91
- | GPUs, `spot`, `linkedSandbox`, `secrets`, `otelEndpointOverride` | Runtime runs Linux on CPUs; pass credentials as `envVars`. |
92
- | A `target` other than `us`, `jwtToken` | Runtime runs in one US region and signs in with keys. |
93
- | `user` other than `daytona` | Commands run as the sandbox owner with passwordless `sudo`. |
94
- | PTY sessions, the entrypoint session, language servers | `sandbox.withruntime.terminal(...)`, and sessions with `runAsync`. |
95
- | `computerUse` | Runtime's desktop, `sandbox.withruntime.desktop`. |
96
- | `setLabels`, `resize`, `recover` | Set labels and resources at create; create a new sandbox. |
97
- | Signed preview URLs, signed upload and download URLs, SSH access | `getPreviewLink`, `fs.uploadFile` and `downloadFile`, `npx withruntime sandbox shell <id>`. |
98
- | `getMetrics` | `npx withruntime usage`. |
99
- | `Image.pipInstallFromPyproject`, snapshot `resources` or `entrypoint` | `pipInstallFromRequirements`; resources at create; a session after create. |
100
- | `volume.create(name)` | Runtime volumes have a size: `runtime.volumes.create({ name, sizeMiB })`. |
101
- | `secret`, `warmPool` | Credentials as `envVars`; Runtime starts from warm templates already. |
102
- | `runCode(code, { envs })` | `envVars` at create, or `os.environ` in the code. |
103
- | Listing by anything but name, labels and states | Filter the result yourself. |
88
+ | Daytona | Use instead |
89
+ | --------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
90
+ | A snapshot name with no Runtime image or snapshot | `daytona.snapshot.create({ name, image })` here, or `npx withruntime image build`. This throws `DaytonaNotFoundError`. |
91
+ | 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()`. |
92
+ | A `target` other than `us`, `jwtToken` | Runtime runs in one US region and signs in with keys. |
93
+ | `user` other than `daytona` | Commands run as the sandbox owner with passwordless `sudo`. |
94
+ | PTY sessions, the entrypoint session, language servers | `sandbox.withruntime.terminal(...)`, and sessions with `runAsync`. |
95
+ | `computerUse` | Runtime's desktop, `sandbox.withruntime.desktop`. |
96
+ | `setLabels`, `resize`, `recover` | Set labels and resources at create; create a new sandbox. |
97
+ | Signed preview URLs, signed upload and download URLs, SSH access | `getPreviewLink`, `fs.uploadFile` and `downloadFile`, `npx withruntime sandbox ssh <id>`. |
98
+ | `getMetrics` | `sandbox.withruntime.metrics()`: its CPU and memory over time. |
99
+ | `Image.pipInstallFromPyproject`, snapshot `resources` or `entrypoint` | `pipInstallFromRequirements`; resources at create; a session after create. |
100
+ | `volume.create(name)` | Runtime volumes have a size: `runtime.volumes.create({ name, sizeMiB })`. |
101
+ | `secret`, `warmPool` | A Runtime secret for credentials; Runtime starts from warm templates already. |
102
+ | `runCode(code, { envs })` | `envVars` at create, or `os.environ` in the code. |
103
+ | Listing by anything but name, labels and states | Filter the result yourself. |
104
104
 
105
105
  Some differences are not refusals:
106
106
 
package/E2B.md CHANGED
@@ -101,7 +101,7 @@ before anything happens. The error's `feature` names the gap and its
101
101
  | `user: "root"` (commands and files) | Prefix the command with `sudo`, which needs no password. |
102
102
  | `network`, `updateNetwork` | `runtime: { create: { network } }` and `sandbox.runtime.network.set(...)`. |
103
103
  | `mcp`, `getMcpUrl`, `getMcpToken` | Runtime's own MCP server, `npx withruntime mcp`. |
104
- | `iam`, `Secret` | Pass credentials as `envs`. |
104
+ | `iam`, `Secret` | A Runtime secret (`npx withruntime secrets set NAME --host <host>`): the sandbox sees a placeholder. |
105
105
  | `volumeMounts`, `Volume` | Runtime volumes: `runtime: { create: { volumes: [{ volumeId, path }] } }`. |
106
106
  | `pty` | `sandbox.runtime.terminal(...)`. |
107
107
  | `git` | `commands.run("git ...")`. E2B has deprecated its git module too. |
package/README.md CHANGED
@@ -43,7 +43,9 @@ The sandbox object does the rest:
43
43
  - `pause`, `wake`, `extend`, `fork` and `snapshot` (a paused sandbox also wakes
44
44
  by itself on the next call), `update` for its name, automatic wake, idle pause
45
45
  and persistence, and `keepAlive` to extend its lease while your process runs;
46
- - `interpreter`, `network`, `previews` and `desktop` for the other products.
46
+ - `interpreter`, `network`, `previews`, `desktop`, `mounts` (your S3, R2 or
47
+ Google Cloud Storage bucket as a folder), `metrics` and `mcp` (servers from
48
+ the MCP catalog, run in the sandbox) for the other products.
47
49
 
48
50
  A sandbox pauses itself after 60 seconds with nothing happening in it, keeping
49
51
  its memory and processes, and the next call wakes it, so an idle sandbox costs
@@ -52,8 +54,11 @@ no compute; `idlePauseSeconds` sets 10 to 86,400, or 0 for never.
52
54
  `Sandbox.getOrCreate(name)` returns the sandbox with that name, woken if it is
53
55
  paused, or creates it.
54
56
 
55
- The client has `sandboxes`, `images`, `volumes`, `snapshots`, `limits`,
56
- `feedback` and `support`. `runtime.limits.get()` (0.3.1 and later) says whether
57
+ The client has `sandboxes`, `images`, `volumes`, `snapshots`, `secrets`,
58
+ `limits`, `feedback` and `support`; `webhooks`, `events`, `otel` and `audit`
59
+ to watch the account; `domains`, `ports`, `addresses`, `tunnel` and `network`
60
+ to connect sandboxes to your own world (paid accounts); and `mcp`, `sso`,
61
+ `billing`, `referrals` and `switching`. `runtime.limits.get()` (0.3.1 and later) says whether
57
62
  the key is read-only and what its agent may still spend today. Every write carries an idempotency key, made for you, so the SDK's
58
63
  own retries (timeouts, 429, 503) never do anything twice. Errors are typed and
59
64
  carry a `code`, a `hint` and a `requestId`.
@@ -124,8 +129,9 @@ Sandboxes get Blaxel's default of 4096 MB, with one vCPU for every 2048 MB.
124
129
  Standby becomes Runtime's pause: after 60 seconds without a call a sandbox
125
130
  pauses with its memory and processes, and the next call wakes it. Envs,
126
131
  processes by name, files, previews, snapshots, forks and the code interpreter
127
- work as they do on Blaxel. A Blaxel key is never sent anywhere. Sessions,
128
- drives, codegen, schedules and Blaxel's agent, model and MCP hosting throw
132
+ work as they do on Blaxel, and so do sessions: `sandbox.sessions` makes a
133
+ Runtime sandbox session and `SandboxInstance.fromSession` drives the sandbox
134
+ with its token. A Blaxel key is never sent anywhere. Drives, codegen, schedules and Blaxel's agent, model and MCP hosting throw
129
135
  `NotSupportedError` before anything happens, naming what to use instead.
130
136
  `BLAXEL.md` in this package lists every mapping and gap.
131
137
 
@@ -164,6 +170,21 @@ connected yet, it offers `runtime_connect`, which walks you through the browser
164
170
  approval. Remote clients add `https://api.withruntime.com/mcp` and sign in through
165
171
  the browser, or send a bearer key.
166
172
 
173
+ ## Reliability and support
174
+
175
+ - **Status:** https://withruntime.com/status checks the API from outside every
176
+ two minutes and starts a real sandbox every ten, with every day's record
177
+ kept; also as https://withruntime.com/status.md and
178
+ https://withruntime.com/status.json.
179
+ - **Uptime Promise:** paid accounts are promised 99% API uptime
180
+ each calendar month, and a month below it pays 10% of that
181
+ month's charges back as credit, automatically
182
+ (https://withruntime.com/legal/sla).
183
+ - **Security and compliance:** https://withruntime.com/docs/trust.
184
+ - **What changed:** https://withruntime.com/changelog.
185
+ - **Help:** `runtime support "<question>"`, or `runtime feedback "<text>"` for
186
+ anything that got in your way.
187
+
167
188
  Docs: https://withruntime.com/docs/javascript and https://withruntime.com/docs/cli.
168
189
 
169
190
  The package was called `@withruntime/cloud` until 0.3.0. That name, and
package/README.src.md CHANGED
@@ -45,7 +45,9 @@ The sandbox object does the rest:
45
45
  - `pause`, `wake`, `extend`, `fork` and `snapshot` (a paused sandbox also wakes
46
46
  by itself on the next call), `update` for its name, automatic wake, idle pause
47
47
  and persistence, and `keepAlive` to extend its lease while your process runs;
48
- - `interpreter`, `network`, `previews` and `desktop` for the other products.
48
+ - `interpreter`, `network`, `previews`, `desktop`, `mounts` (your S3, R2 or
49
+ Google Cloud Storage bucket as a folder), `metrics` and `mcp` (servers from
50
+ the MCP catalog, run in the sandbox) for the other products.
49
51
 
50
52
  A sandbox pauses itself after {{idle-pause}} with nothing happening in it, keeping
51
53
  its memory and processes, and the next call wakes it, so an idle sandbox costs
@@ -54,8 +56,11 @@ no compute; `idlePauseSeconds` sets {{idle-pause-min}} to {{idle-pause-max}}, or
54
56
  `Sandbox.getOrCreate(name)` returns the sandbox with that name, woken if it is
55
57
  paused, or creates it.
56
58
 
57
- The client has `sandboxes`, `images`, `volumes`, `snapshots`, `limits`,
58
- `feedback` and `support`. `runtime.limits.get()` (0.3.1 and later) says whether
59
+ The client has `sandboxes`, `images`, `volumes`, `snapshots`, `secrets`,
60
+ `limits`, `feedback` and `support`; `webhooks`, `events`, `otel` and `audit`
61
+ to watch the account; `domains`, `ports`, `addresses`, `tunnel` and `network`
62
+ to connect sandboxes to your own world (paid accounts); and `mcp`, `sso`,
63
+ `billing`, `referrals` and `switching`. `runtime.limits.get()` (0.3.1 and later) says whether
59
64
  the key is read-only and what its agent may still spend today. Every write carries an idempotency key, made for you, so the SDK's
60
65
  own retries (timeouts, 429, 503) never do anything twice. Errors are typed and
61
66
  carry a `code`, a `hint` and a `requestId`.
@@ -126,8 +131,9 @@ Sandboxes get Blaxel's default of 4096 MB, with one vCPU for every 2048 MB.
126
131
  Standby becomes Runtime's pause: after 60 seconds without a call a sandbox
127
132
  pauses with its memory and processes, and the next call wakes it. Envs,
128
133
  processes by name, files, previews, snapshots, forks and the code interpreter
129
- work as they do on Blaxel. A Blaxel key is never sent anywhere. Sessions,
130
- drives, codegen, schedules and Blaxel's agent, model and MCP hosting throw
134
+ work as they do on Blaxel, and so do sessions: `sandbox.sessions` makes a
135
+ Runtime sandbox session and `SandboxInstance.fromSession` drives the sandbox
136
+ with its token. A Blaxel key is never sent anywhere. Drives, codegen, schedules and Blaxel's agent, model and MCP hosting throw
131
137
  `NotSupportedError` before anything happens, naming what to use instead.
132
138
  `BLAXEL.md` in this package lists every mapping and gap.
133
139
 
@@ -166,6 +172,21 @@ connected yet, it offers `runtime_connect`, which walks you through the browser
166
172
  approval. Remote clients add `https://api.withruntime.com/mcp` and sign in through
167
173
  the browser, or send a bearer key.
168
174
 
175
+ ## Reliability and support
176
+
177
+ - **Status:** https://withruntime.com/status checks the API from outside every
178
+ two minutes and starts a real sandbox every ten, with every day's record
179
+ kept; also as https://withruntime.com/status.md and
180
+ https://withruntime.com/status.json.
181
+ - **Uptime Promise:** paid accounts are promised {{uptime-promise}} API uptime
182
+ each calendar month, and a month below it pays {{uptime-credit}} of that
183
+ month's charges back as credit, automatically
184
+ (https://withruntime.com/legal/sla).
185
+ - **Security and compliance:** https://withruntime.com/docs/trust.
186
+ - **What changed:** https://withruntime.com/changelog.
187
+ - **Help:** `runtime support "<question>"`, or `runtime feedback "<text>"` for
188
+ anything that got in your way.
189
+
169
190
  Docs: https://withruntime.com/docs/javascript and https://withruntime.com/docs/cli.
170
191
 
171
192
  The package was called `@withruntime/cloud` until 0.3.0. That name, and
package/VERCEL.md CHANGED
@@ -88,7 +88,7 @@ Each of these throws `NotSupportedError` before anything happens. Its
88
88
  | `timeout` over one hour | Create with up to an hour, then `extendTimeout` before it ends. |
89
89
  | Drives (`mounts`), `networkId` | Runtime volumes through `withruntime: { create: { volumes } }`; network rules. |
90
90
  | A region outside the US, `failoverRegions` | Runtime runs in one US region. |
91
- | Network rules that transform or forward requests | Allow the domain and pass credentials as `env`. |
91
+ | Network rules that transform or forward requests | Allow the domain and store the credential as a Runtime secret for it: the sandbox sees a placeholder. |
92
92
  | `openInteractive` | `sandbox.withruntime.terminal(...)` or `npx withruntime sandbox shell <id>`. |
93
93
  | Extra users and groups (`createUser`, `asUser`) | `sudo useradd` and `sudo -u` through `runCommand`. |
94
94
  | Sessions (`currentSession`, `listSessions`) | A Runtime sandbox is its own session. |
@@ -44,7 +44,7 @@ export declare const settings: {
44
44
  authenticate(): Promise<void>;
45
45
  readonly [key: string]: unknown;
46
46
  };
47
- export declare const SandboxSessions: import("./unsupported.js").Unsupported;
47
+ export { SandboxSessions } from "./session.js";
48
48
  export declare const SandboxSchedules: import("./unsupported.js").Unsupported;
49
49
  export declare const SandboxCodegen: import("./unsupported.js").Unsupported;
50
50
  export declare const SandboxSystem: import("./unsupported.js").Unsupported;
@@ -10,7 +10,7 @@
10
10
  import { RuntimeError } from "../errors.js";
11
11
  import { initialize } from "./client.js";
12
12
  import { NotSupportedError } from "./errors.js";
13
- import { CODEGEN, DRIVES, SCHEDULES, SESSIONS, SYSTEM, unsupportedExport } from "./unsupported.js";
13
+ import { CODEGEN, DRIVES, SCHEDULES, SYSTEM, unsupportedExport } from "./unsupported.js";
14
14
  export { SandboxInstance, DEFAULT_IMAGE, DEFAULT_MEMORY, MEMORY_PER_VCPU, durationMs, imageRef, lifetimeOf, networkRules, } from "./sandbox.js";
15
15
  export { CodeInterpreter } from "./interpreter.js";
16
16
  export { SandboxFileSystem, retryOnTransient, } from "./filesystem.js";
@@ -74,9 +74,9 @@ export const settings = new Proxy({
74
74
  throw new NotSupportedError(`Blaxel's settings.${property}`, "Runtime's SDK is configured by RUNTIME_API_KEY (or `npx withruntime login`) and RUNTIME_API_URL.");
75
75
  },
76
76
  });
77
+ export { SandboxSessions } from "./session.js";
77
78
  /* The sandbox parts Runtime has no counterpart for. On a sandbox they are
78
79
  objects whose methods reject; as exports, stand-ins. */
79
- export const SandboxSessions = unsupportedExport("SandboxSessions", SESSIONS);
80
80
  export const SandboxSchedules = unsupportedExport("SandboxSchedules", SCHEDULES);
81
81
  export const SandboxCodegen = unsupportedExport("SandboxCodegen", CODEGEN);
82
82
  export const SandboxSystem = unsupportedExport("SandboxSystem", SYSTEM);
@@ -4,6 +4,7 @@ import { SandboxFileSystem } from "./filesystem.js";
4
4
  import { type PaginatedList } from "./pagination.js";
5
5
  import { SandboxPreviews } from "./preview.js";
6
6
  import { SandboxProcess } from "./process.js";
7
+ import { SandboxSessions } from "./session.js";
7
8
  import { SandboxSnapshotsResource, type Env, type SandboxForkResponse, type SandboxRestoreResponse, type SandboxSnapshot } from "./snapshot.js";
8
9
  import { type Metadata, type Sandbox as SandboxModel, type SandboxCreateConfiguration, type SandboxLifecycle, type SandboxNetwork, type SandboxSpec, type SandboxUpdateMetadata, type SandboxUpdateNetwork, type SessionWithToken, type Status, type VolumeAttachment } from "./types.js";
9
10
  import { type UnsupportedPart } from "./unsupported.js";
@@ -90,7 +91,9 @@ export declare class SandboxInstance {
90
91
  readonly process: SandboxProcess;
91
92
  readonly previews: SandboxPreviews;
92
93
  readonly snapshots: SandboxSnapshotsResource;
93
- readonly sessions: UnsupportedPart;
94
+ /** Tokens a frontend uses to reach this sandbox directly (Runtime's
95
+ * sandbox sessions). */
96
+ readonly sessions: SandboxSessions;
94
97
  readonly schedules: UnsupportedPart;
95
98
  readonly codegen: UnsupportedPart;
96
99
  readonly system: UnsupportedPart;
@@ -175,6 +178,9 @@ export declare class SandboxInstance {
175
178
  * (files, memory and running processes), or started from a snapshot with
176
179
  * `snapshotId`. `envs` are added over this sandbox's. */
177
180
  fork(targetName: string, options?: SandboxForkOptions): Promise<SandboxForkResponse>;
178
- static fromSession(_session: SessionWithToken): Promise<never>;
181
+ /** A sandbox reached with a session instead of a key: what a frontend
182
+ * does with the session its backend made. Commands, processes, files and
183
+ * previews work; anything that manages the sandbox is refused by Runtime. */
184
+ static fromSession<T extends typeof SandboxInstance>(this: T, session: SessionWithToken): Promise<InstanceType<T>>;
179
185
  }
180
186
  export {};
@@ -7,9 +7,10 @@ import { ARCHIVED, DISPLAY_NAME, EXTERNAL_ID, IDLE_PAUSE, LABEL, findByExternalI
7
7
  import { paginate } from "./pagination.js";
8
8
  import { portAccess, SandboxPreviews } from "./preview.js";
9
9
  import { SandboxProcess } from "./process.js";
10
+ import { SandboxSessions, sessionSandbox } from "./session.js";
10
11
  import { appendEnvs, envRecord, KEEP_DAYS, refuseApplication, SandboxSnapshotsResource, startFromSnapshot, } from "./snapshot.js";
11
12
  import { normalizeEnvs, normalizePorts, normalizeVolumes, } from "./types.js";
12
- import { CODEGEN, DRIVES, SCHEDULES, SESSIONS, SYSTEM, unsupportedPart, } from "./unsupported.js";
13
+ import { CODEGEN, DRIVES, SCHEDULES, SYSTEM, unsupportedPart, } from "./unsupported.js";
13
14
  /* Blaxel's SandboxInstance over a Runtime sandbox. Every call is one or a few
14
15
  calls of the withruntime SDK; nothing here speaks HTTP. What Runtime cannot
15
16
  do the way Blaxel does throws NotSupportedError before anything happens.
@@ -249,7 +250,9 @@ export class SandboxInstance {
249
250
  process;
250
251
  previews;
251
252
  snapshots;
252
- sessions = unsupportedPart("sandbox.sessions", SESSIONS);
253
+ /** Tokens a frontend uses to reach this sandbox directly (Runtime's
254
+ * sandbox sessions). */
255
+ sessions;
253
256
  schedules = unsupportedPart("sandbox.schedules", SCHEDULES);
254
257
  codegen = unsupportedPart("sandbox.codegen", CODEGEN);
255
258
  system = unsupportedPart("sandbox.system", SYSTEM);
@@ -288,6 +291,11 @@ export class SandboxInstance {
288
291
  run,
289
292
  labels: () => this.#rt.info.labels,
290
293
  });
294
+ this.sessions = new SandboxSessions({
295
+ id: this.#rt.id,
296
+ run,
297
+ apiUrl: () => this.#client.transport.baseUrl,
298
+ });
291
299
  this.network = { fetch: (port, path, init) => this.fetch(port, path, init) };
292
300
  }
293
301
  /** The Runtime sandbox underneath: metrics, network rules, desktop,
@@ -764,8 +772,12 @@ export class SandboxInstance {
764
772
  }
765
773
  return { name: targetName, snapshotId: "", type: "sandbox" };
766
774
  }
767
- static fromSession(_session) {
768
- return Promise.reject(new NotSupportedError("Blaxel sessions (SandboxInstance.fromSession)", "Use SandboxInstance.get(name) with a Runtime key; to reach a port from a browser, share it with sandbox.previews.create and a token."));
775
+ /** A sandbox reached with a session instead of a key: what a frontend
776
+ * does with the session its backend made. Commands, processes, files and
777
+ * previews work; anything that manages the sandbox is refused by Runtime. */
778
+ static async fromSession(session) {
779
+ const { client, runtime } = await sessionSandbox(session);
780
+ return new this({ runtime, client });
769
781
  }
770
782
  }
771
783
  function modelOfSnapshot(snapshot) {
@@ -0,0 +1,31 @@
1
+ import { Runtime } from "../client.js";
2
+ import type { RuntimeSandbox } from "./client.js";
3
+ import type { SessionCreateOptions, SessionWithToken } from "./types.js";
4
+ /** Blaxel's `sandbox.sessions`. */
5
+ export declare class SandboxSessions {
6
+ #private;
7
+ constructor(sandbox: {
8
+ id: string;
9
+ run: <T>(work: (runtime: RuntimeSandbox) => Promise<T>) => Promise<T>;
10
+ apiUrl: () => string;
11
+ });
12
+ /** A new session, for a day unless `expiresAt` says sooner. */
13
+ create(options?: SessionCreateOptions): Promise<SessionWithToken>;
14
+ /** Blaxel's: the session made last, if it lasts at least `delta` ms more
15
+ * (an hour unless given), else a new one, and the old one ends. A token is
16
+ * shown only when its session is made, so "the session made last" is the
17
+ * one this process made for this sandbox; a new process makes a new one. */
18
+ createIfExpired(options?: SessionCreateOptions, delta?: number): Promise<SessionWithToken>;
19
+ /** Active sessions, newest first. A token is shown only when its session is
20
+ * made, so these carry an empty `token`: keep the one `create` gave. */
21
+ list(): Promise<SessionWithToken[]>;
22
+ get(name: string): Promise<Omit<SessionWithToken, "name">>;
23
+ /** Blaxel's delete: the session ends at once. */
24
+ delete(name: string): Promise<SessionWithToken>;
25
+ }
26
+ /** The client and sandbox a session reaches, for `SandboxInstance.fromSession`.
27
+ * The sandbox is read once with the session, which may read it. */
28
+ export declare function sessionSandbox(session: SessionWithToken): Promise<{
29
+ client: Runtime;
30
+ runtime: RuntimeSandbox;
31
+ }>;