feat(sandbox): E2B sandbox provider with idle pause/resume - #72
Merged
Merged
Conversation
Co-Authored-By: Claude <noreply@anthropic.com>
…vider plumbing Co-Authored-By: Claude <noreply@anthropic.com>
Deviation from the original plan, per feasibility findings: create uses network.allowPublicTraffic=false (secure and a top-level allowPublicTraffic are ignored by e2b 2.x and left the sandbox public).
…files on transport failure
…B template Adds SANDBOX_BASE build arg (default cloudflare/sandbox:0.12.7), installs bun when missing, prepares /var/log/codevil and /run/codevil, and an e2b:template script (docker build -> push -> Template.build via fromImage). Template was not published and no image was built or pushed (Docker daemon unavailable; publishing is deferred).
…troy, and Cloudflare production default - background agent start passes timeoutMs: 0 so the SDK's 60s deadline cannot kill it - retry E2B create on 429/5xx/network errors; stop forwarding inbound request.cf - token parent directory via install -d -m 0755 - optional SandboxProvider.destroyByRef (E2B static kill) - wrangler.toml pins SANDBOX_PROVIDER=cloudflare until E2B is ready; README and env example document E2B_API_KEY
…iately, and build the E2B image in CI - worker passes CODEVIL_SANDBOX_PROVIDER; preview manager sets __VITE_ADDITIONAL_SERVER_ALLOWED_HOSTS=.e2b.app on e2b - agent polls the ws-token file every 2s and reconnects at once when a new token is adopted - readTokenFile non-ENOENT WARN branch is tested - CI sandbox-image job also builds and smoke-tests the E2B variant
…ng reasons, and clean up on failure - createSession/handleCreateSession resolve the provider before the D1 insert (missing E2B_API_KEY fails clearly, no row) - provisioning failure broadcasts the redacted reason and destroys an already-created sandbox - agent error outside a run destroys the sandbox - warn when max_time exceeds the E2B continuous runtime limit - answering a question counts as activity
…nce, and recover from mid-pause eviction - per-Orchestrator handle cache invalidated on pause, resume, terminate, loss, ref change and SandboxNotFoundError - terminate/destroy use destroyByRef for paused or unconnectable sandboxes; failed resume kills by reference - assume paused after a DO eviction between provider pause and the paused marker - remove the never-shipped pending_preview_start legacy field and migration
# Conflicts: # pnpm-lock.yaml
When wrangler.toml selects SANDBOX_PROVIDER = "e2b", a new e2b-template job builds this commit's sandbox image, pushes it to GHCR with GITHUB_TOKEN, and publishes it as the E2B template tagged with the commit SHA (plus "default", so the untagged name follows the latest publish). The deploy job waits for it and pins the Worker to E2B_TEMPLATE_ID = "<id>:<sha>". Cloudflare deploys skip the publish. Publishing runs in its own job so the GITHUB_TOKEN E2B receives as pull credentials expires once the publish finishes, and the job that holds Cloudflare credentials never has packages: write. The deploy pipeline reads SANDBOX_PROVIDER and E2B_TEMPLATE_ID from the top-level [vars] table only, and requires SANDBOX_PROVIDER to be explicit because the Worker otherwise defaults to E2B.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a provider-neutral sandbox layer and an E2B sandbox provider, with pause-when-idle. The goal is to fix CPU-starved installs and previews, flaky R2 workspace snapshots, and the long preview path on Cloudflare
standard-1(½ vCPU).packages/worker/src/sandbox-provider/):SandboxProvider/SandboxHandle, modeled on Flue's adapter pattern. The Cloudflare adapter wraps the existing code with no behavior change.network: { allowPublicTraffic: false }. Preview requests go to E2B port URLs with the traffic token injected by the Worker, and the client never sees it.max_idle_time(default 10m) with no agent input or preview traffic. E2B pause keeps the filesystem, memory and running processes./run/codevil/ws-token, and the agent adopts it within about 2s.Dockerfile.sandboxtakes aSANDBOX_BASEarg (default unchanged), and CI builds both variants.pnpm --filter @codevil/sandbox-image e2b:templatepublishes the E2B template (supports--dry-run).e2b, butwrangler.tomlpinsSANDBOX_PROVIDER = "cloudflare"until the template, secret and E2E are in place (see Deploy below).Design:
docs/superpowers/specs/2026-10-01-e2b-sandbox-provider-design.md(includes live E2B feasibility findings). Plan:docs/superpowers/plans/2026-10-01-e2b-sandbox-provider.md.Deploy (to switch production to E2B)
wrangler secret put E2B_API_KEYSANDBOX_PROVIDER = "e2b"inpackages/worker/wrangler.toml(or your operator config), then deploy.Test plan
pnpm verifypasses (worker 699, shared 212, sandbox-image 140, admin-cli 34, cli 28; web/site green)node:22-slim(first real build)max_idle_timeto2mto save time):npm install