Skip to content

Commit 72ffb42

Browse files
author
Roy Lin
committed
feat(e2b): prepare production-tested SDK release
1 parent 91d04fa commit 72ffb42

15 files changed

Lines changed: 277 additions & 195 deletions

File tree

.github/workflows/ci.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ jobs:
106106
- uses: dtolnay/rust-toolchain@stable
107107
- name: Build Rust lifecycle fixture server
108108
run: cd src && cargo build -p a3s-box-compat --bin a3s-box-e2b-fixture-server
109+
- name: Test production client harness
110+
run: python3 compat/e2b/fixtures/official-clients/test_run_production.py -v
109111
- name: Verify official client lifecycle requests
110112
run: >-
111113
python3 compat/e2b/fixtures/official-clients/run_fixtures.py verify
@@ -184,6 +186,7 @@ jobs:
184186
cargo check --release -p a3s-box-cli -p a3s-box-shim
185187
if [ "${{ runner.os }}" = "Linux" ]; then
186188
cargo check --release -p a3s-box-cri
189+
cargo check --release -p a3s-box-compat --bin a3s-box-e2b
187190
fi
188191
189192
# ── Windows native WHPX build check ────────────────────────────

.github/workflows/release.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ jobs:
133133
cargo build --release -p a3s-box-cli -p a3s-box-shim
134134
if [ "${{ matrix.build_cri }}" = "true" ]; then
135135
cargo build --release -p a3s-box-cri
136+
cargo build --release -p a3s-box-compat --bin a3s-box-e2b
136137
fi
137138
138139
- name: Build guest binaries
@@ -159,6 +160,7 @@ jobs:
159160
160161
if [ "${{ matrix.build_cri }}" = "true" ]; then
161162
cp src/target/release/a3s-box-cri "$DIR/"
163+
cp src/target/release/a3s-box-e2b "$DIR/"
162164
fi
163165
164166
cp "src/target/${{ matrix.guest_target }}/release/a3s-box-guest-init" "$DIR/"
@@ -185,6 +187,7 @@ jobs:
185187
done
186188
if [ "${{ matrix.build_cri }}" = "true" ]; then
187189
patchelf --set-rpath '$ORIGIN/lib' "$DIR/a3s-box-cri" 2>/dev/null || true
190+
patchelf --set-rpath '$ORIGIN/lib' "$DIR/a3s-box-e2b" 2>/dev/null || true
188191
fi
189192
fi
190193
@@ -357,6 +360,7 @@ jobs:
357360
bin.install "a3s-box-shim"
358361
bin.install "a3s-box-guest-init"
359362
bin.install "a3s-box-cri" if File.exist?("a3s-box-cri")
363+
bin.install "a3s-box-e2b" if File.exist?("a3s-box-e2b")
360364
lib.install Dir["lib/*"] if Dir.exist?("lib")
361365
end
362366

README.md

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,13 @@ a3s-box run --rm alpine:latest -- uname -a
5353
a3s-box run --rm --isolation sandbox alpine:latest -- id
5454
```
5555

56-
### E2B-compatible Python and TypeScript SDKs
56+
### A3S SDKs with E2B-compatible APIs
5757

58-
The A3S Python and TypeScript packages re-export the pinned official E2B
59-
objects and add typed A3S endpoint configuration. Applications keep the
60-
familiar `Sandbox`, `AsyncSandbox`, Commands, Filesystem, PTY, and Code
61-
Interpreter surfaces while `a3s-box-e2b` owns the remote runtime and isolation
62-
policy. No E2B-hosted service is involved.
58+
A3S Box implements the remote runtime and protocol service. The A3S Python and
59+
TypeScript packages re-export the pinned official E2B objects and add typed A3S
60+
endpoint configuration, so applications keep the familiar `Sandbox`,
61+
`AsyncSandbox`, Commands, Filesystem, PTY, and Code Interpreter surfaces. No
62+
E2B-hosted service is involved.
6363

6464
Point the native SDK at the deployed A3S Box service. A conventional
6565
`https://api.<domain>` endpoint automatically derives `<domain>` for Sandbox
@@ -74,8 +74,10 @@ Set `A3S_BOX_DOMAIN` only when the control endpoint does not follow the
7474
conventional `api.<domain>` form. The service advertises the direct Sandbox
7575
authority, including a non-standard public TLS port, so normal deployments do
7676
not need a client-side Sandbox URL override. `A3S_BOX_SANDBOX_URL` remains a
77-
single-Sandbox fixture escape hatch. The `E2B_*` variables are needed only
78-
when an unchanged official E2B SDK is used directly for protocol compatibility.
77+
single-Sandbox fixture escape hatch. `E2B_API_URL` is not an A3S SDK setting.
78+
It is used only when an unchanged official E2B SDK is connected directly to
79+
A3S Box, because that is the endpoint variable exposed by the official client;
80+
its value still points to A3S Box.
7981

8082
Python uses async lifecycle management so the remote Sandbox is always cleaned
8183
up:
@@ -120,10 +122,10 @@ try {
120122
}
121123
```
122124

123-
Both packages are source-tree previews until the complete official and native
124-
client matrix passes and the packages are published. The current verified
125-
surface and remaining compatibility gates are stated under
126-
[SDKs and Compatibility](#sdks-and-compatibility).
125+
Both packages pass the production matrix described below. The release workflow
126+
builds wheel and npm tarball artifacts, but the packages are not yet published
127+
to PyPI or npm. The verified subset and remaining full-compatibility gates are
128+
stated under [SDKs and Compatibility](#sdks-and-compatibility).
127129

128130
## Features
129131

@@ -146,8 +148,8 @@ surface and remaining compatibility gates are stated under
146148
resource and syscall controls, audit records, AMD SEV-SNP-oriented
147149
attestation, RA-TLS, sealing, and secret injection
148150
- **Typed SDKs and protocols**: Direct runtime-backed Rust management APIs,
149-
an optional programmable pipeline runner, and an E2B protocol compatibility
150-
preview with official-client fixtures plus Python and TypeScript source packages
151+
an optional programmable pipeline runner, and a production-tested E2B
152+
protocol subset with Python and TypeScript packages
151153
- **Operations and cluster integration**: Structured logs, stats, events,
152154
Prometheus endpoints, health monitoring, CRI, and containerd RuntimeClass
153155

@@ -164,7 +166,7 @@ surface and remaining compatibility gates are stated under
164166
| Networking and Compose | TSI, bridge networks, TCP publishing, peer discovery, and Compose lifecycle/config/logs | Implemented subset for MicroVM workloads. UDP publishing, host-IP binds, ranges, and live network hot-plug are not implemented. |
165167
| Warm pool and snapshot-fork | Pre-booted MicroVMs, one-shot runs, build leases, metrics, and CoW memory restore | Implemented. Native snapshot-fork is Linux/KVM-only and disabled by default. |
166168
| Rust SDK | Typed, direct runtime-backed management and guest-control APIs | Implemented in `a3s-box-sdk`. The optional `pipeline-cli` feature retains the CLI-driven programmable pipeline. |
167-
| E2B protocol and language SDKs | Pinned contracts, durable lifecycle, TLS routing, runtime envd initialization, foreground Process commands, and core Filesystem operations | Preview only. Production evidence covers lifecycle and foreground commands across the pinned base clients, plus environment propagation and core Filesystem operations through the official Python sync client. Concurrent Process/PTY, the extended async Python and TypeScript matrix, Code Interpreter execution, MCP, signed files, and full unchanged-client conformance remain release gates. Python/npm packages are not published. |
169+
| E2B protocol and language SDKs | Pinned contracts, durable lifecycle, TLS routing, envd initialization, Filesystem, foreground/background Process, stdin, PTY, and Python Code Interpreter contexts | Production-tested preview subset on A3S OS with certified `crun`: pinned official Python sync/async and TypeScript clients, plus A3S Python sync/async and TypeScript packages, pass the same matrix. Templates, snapshots, volumes, signed files, public-port breadth, MCP, cancellation/backpressure, and the rest of the pinned contract remain gates; `full_compatibility=false`. PyPI/npm publication is also pending. |
168170
| TEE | SEV-SNP-oriented attestation, RA-TLS, sealing, secret injection, and simulation | Host-specific. Hardware claims require a supported SEV-SNP host and real attestation evidence. Simulation is development-only; TDX is not productized. |
169171
| Kubernetes | CRI server plus a containerd runtime-v2 shim and `runtimeClassName: a3s-box` | Preview. Core lifecycle, streaming, logs, resources, and RuntimeClass paths exist; complete CRI conformance is not claimed. |
170172
| Windows | Native x86_64 WHPX/libkrun code paths | Integration surface requiring host-specific validation. Current standard release automation focuses on Linux and macOS; Windows CRI is out of scope. |
@@ -519,7 +521,7 @@ The historical programmable CI pipeline remains behind the optional
519521
yet exposed by its pipeline abstraction. See
520522
[the SDK README](src/sdk/README.md) for the current API coverage.
521523

522-
### E2B protocol preview
524+
### E2B-compatible protocol preview
523525

524526
A3S Box pins the public control, envd, volume-content, Process, Filesystem, MCP,
525527
Python, TypeScript, and Code Interpreter contracts under
@@ -535,18 +537,18 @@ The current pin targets:
535537
| Python `e2b-code-interpreter` | 2.8.1 |
536538
| TypeScript `@e2b/code-interpreter` | 2.6.1 |
537539

538-
Current implementation evidence is intentionally narrower than full
540+
The production-tested subset remains intentionally narrower than full
539541
compatibility:
540542

541543
| Surface | Implemented preview | Not yet a release claim |
542544
| --- | --- | --- |
543-
| Control plane | Owner-scoped create, connect, get, list, timeout replacement, and kill with SQLite WAL persistence and reconciliation | Complete template, snapshot, volume, metrics, pagination, and recovery semantics |
544-
| Credentials and routing | PBKDF2 account-key hashes, encrypted scope-bound Sandbox tokens, generation-fenced leases, wildcard TLS, direct/shared routes, CORS, and PID-fenced Sandbox network access | Complete certificate rotation and every streaming/upgrade/public-port route |
545-
| envd | Authenticated `GET /health` has running and terminal behavior. Runtime templates receive a fail-closed `POST /init` with the lifecycle ID, merged environment, timestamp, and default user before create succeeds. | `/metrics`, `/envs`, HTTP file transfer, volume-content endpoints, and the complete envd semantic matrix |
546-
| Process | Start/connect/list/input/close/SIGKILL and PTY primitives exist. Pinned Python sync/async and TypeScript clients pass a foreground non-PTY command on production; the extended Python sync path also proves environment propagation and background Start. | Concurrent streaming plus unary Process calls, full signals, binary framing, stdin/close completion, PTY, reconnect, cancellation, ordering, and backpressure |
547-
| Filesystem | Runtime-backed remove, make-directory, write, read, stat, list, rename, exists, and cleanup operations pass through the production TLS route with the pinned official Python sync client. | Async Python and TypeScript evidence, watch and edge-case semantics, signed URLs, and HTTP file transfer |
548-
| Code Interpreter and MCP | Contracts, generated inventories, official package artifacts, and black-box fixtures are pinned. | Code execution, context lifecycle, rich results, MCP execution, and the complete unchanged-client matrix |
549-
| Python and TypeScript packages | Typed source packages re-export the pinned official SDK surfaces, add endpoint configuration helpers, and are included in the native-package production harness. | PyPI/npm publication and a passing complete native-package conformance matrix |
545+
| Control plane | Owner-scoped create, connect, get, list, timeout replacement, and kill with SQLite WAL persistence, restart reconciliation, and cleanup | Template, snapshot, volume, metrics, full pagination/recovery semantics, and cold-start lifetime handling tracked by #112 |
546+
| Credentials and routing | PBKDF2 account-key hashes, encrypted scope-bound Sandbox tokens, generation-fenced leases, wildcard TLS, direct/shared routes, CORS, HTTP/2, and PID-fenced Sandbox access | Certificate rotation and the complete streaming, upgrade, signed-file, and public-port route matrix |
547+
| envd | Authenticated running/terminal health plus fail-closed runtime initialization with lifecycle ID, environment, timestamp, and default user | `/metrics`, `/envs`, HTTP content transfer, volume-content endpoints, and the remaining envd semantic matrix |
548+
| Process and PTY | Official and A3S Python sync/async and TypeScript clients pass foreground and background commands, list, stdin send/close, wait, PTY create/resize/input/wait, and ordered output on real Sandboxes | Additional signals, binary framing, reconnect, cancellation, backpressure, and adversarial concurrent-stream coverage |
549+
| Filesystem | The same six clients pass remove, make-directory, write, read, stat, list, rename, exists, and cleanup through production TLS routing | Watch, multi-file and ownership edge cases, signed URLs, HTTP content transfer, and negative-path breadth |
550+
| Code Interpreter and MCP | Official and A3S Python sync/async and TypeScript clients execute Python, validate stdout/results, and pass context create/list/run/restart/remove | Other languages, rich MIME/error/cancellation breadth, MCP execution, and the rest of the pinned interpreter contract |
551+
| Python and TypeScript packages | Typed packages re-export the pinned official surfaces, use `A3S_BOX_*` connection configuration, and pass the production matrix with all `E2B_*` connection variables removed | PyPI/npm publication and conformance for the unimplemented protocol surfaces above |
550552

551553
The production `a3s-box-e2b` process accepts only `.acl` configuration parsed
552554
by `a3s-acl`. For runtime-envd templates, create does not become visible until
@@ -561,10 +563,11 @@ cargo run --locked -p a3s-box-compat --bin a3s-box-e2b -- \
561563
```
562564

563565
The Python package under [`sdk/python`](sdk/python/README.md) and the TypeScript
564-
package under [`sdk/typescript`](sdk/typescript/README.md) are source-tree
565-
previews and are not published to PyPI or npm. Their existence is not evidence
566-
of full protocol compatibility. Until the complete black-box matrix passes,
567-
the generated manifest must continue to report `full_compatibility=false`.
566+
package under [`sdk/typescript`](sdk/typescript/README.md) pass the production
567+
matrix and are built as GitHub Release assets. They are not yet published to
568+
PyPI or npm. Passing this subset is not evidence for unimplemented protocol
569+
surfaces, so the generated manifest continues to report
570+
`full_compatibility=false`.
568571

569572
See [E2B Protocol Compatibility and SDK Design](docs/e2b-compatible-sdk-design.md)
570573
for the release definition, architecture, ACL schema, and remaining gates.
@@ -681,7 +684,7 @@ Main components:
681684
| `containerd-shim` | containerd runtime-v2 adapter for RuntimeClass |
682685
| `src/sdk` | Direct runtime-backed Rust SDK and optional pipeline runner |
683686
| `src/lambda` | Workload-execution integration retained for higher-level runtimes |
684-
| `sdk/python`, `sdk/typescript` | Unpublished E2B-oriented language SDK previews |
687+
| `sdk/python`, `sdk/typescript` | Production-tested A3S language SDK packages; public registry publication pending |
685688

686689
MicroVM guest control uses vsock-backed channels for control/health, exec, PTY,
687690
attestation, and optional sidecars. These are guest-to-host control channels,

compat/e2b/README.md

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,15 @@ restart recovery, host envd health, a traffic-scoped workload service on port
101101
unchanged Python sync, Python async, TypeScript, and Code Interpreter packages
102102
through the production lifecycle listener, calls their official running-state
103103
health methods through the TLS gateway before and after kill, and verifies
104-
cleanup of every real `crun` execution. The three base clients also execute and
105-
validate one foreground non-PTY `commands.run` through the ConnectRPC JSON
106-
transport. This does not establish full Process compatibility, and the matrix
107-
does not exercise Filesystem, the complete PTY/input/signal/reconnect surface,
108-
or Code Interpreter execution.
104+
cleanup of every real `crun` execution. The clients exercise foreground and
105+
background commands, process listing, stdin send/close, wait, PTY
106+
create/resize/input/wait, Filesystem remove/mkdir/write/read/stat/list/rename,
107+
and Python Code Interpreter execution plus context create/list/run/restart/remove.
108+
109+
With `A3S_BOX_E2B_NATIVE_SDKS=1`, the harness repeats that matrix through the
110+
A3S Python sync/async and TypeScript packages after removing every `E2B_*`
111+
connection variable and configuring only `A3S_BOX_*`. This production subset
112+
passes on A3S OS with certified `crun`, but it does not establish full protocol
113+
compatibility. Templates, snapshots, volumes, signed files, MCP, additional
114+
signals, reconnect, cancellation, backpressure, and other pinned edge cases
115+
remain outside the matrix, so `full_compatibility=false` remains mandatory.

compat/e2b/manifests/v1.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,5 @@
2323
"typescript-code-interpreter-tarball": "sha256:df9350312e46f6f6c4f62004da528fd15176078b3027b4507f7358a6eab0fe57",
2424
"typescript-e2b-tarball": "sha256:53581eae5f11efb4b1020b64c05d7e8fc46fe3e14b5172322b5feb35c262e579"
2525
},
26-
"a3s_compat_version": "0.1.0-preview.1"
26+
"a3s_compat_version": "3.0.10-preview.1"
2727
}

compat/e2b/upstream.lock.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"schema_version": 1,
33
"compatibility": {
44
"id": "e2b-2026-07-14",
5-
"version": "0.1.0-preview.1",
5+
"version": "3.0.10-preview.1",
66
"control_plane_tags": [
77
"auth",
88
"sandboxes",

0 commit comments

Comments
 (0)