Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@ Open the Worker URL, sign in with Google, claim the first owner account using `C

## Sandbox provider

Codevil runs each session in either an E2B sandbox or a Cloudflare Sandbox container. The shipped `wrangler.toml` pins `SANDBOX_PROVIDER = "cloudflare"` so a deploy never switches to E2B before it is ready. To move to E2B: (1) add `E2B_API_KEY` both as a Worker secret and as a GitHub Actions secret in the `production` environment, (2) pass the manual end-to-end check, (3) set `SANDBOX_PROVIDER = "e2b"` and merge to `main`. CI then publishes the template on every deploy (see below). The Worker's code default (no var set) is `e2b`. Configure the provider with Worker vars in `packages/worker/wrangler.toml` (or an untracked `wrangler.operator.toml` overlay):
Codevil runs each session in either an E2B sandbox or a Cloudflare Sandbox container. The shipped `wrangler.toml` sets `SANDBOX_PROVIDER = "e2b"`, which needs `E2B_API_KEY` both as a Worker secret and as a GitHub Actions secret in the `production` environment. CI publishes the template on every deploy (see below). To run sessions on Cloudflare containers instead, set `SANDBOX_PROVIDER = "cloudflare"`; existing sessions keep the provider they started on. The Worker's code default (no var set) is `e2b`. Configure the provider with Worker vars in `packages/worker/wrangler.toml` (or an untracked `wrangler.operator.toml` overlay):

| Name | Kind | Default | Purpose |
| --- | --- | --- | --- |
| `SANDBOX_PROVIDER` | var | `e2b` in code; `cloudflare` in the shipped `wrangler.toml` | `e2b` or `cloudflare`. |
| `SANDBOX_PROVIDER` | var | `e2b` | `e2b` or `cloudflare`. Deploys require it to be set explicitly. |
| `E2B_API_KEY` | secret | none | Required when `SANDBOX_PROVIDER=e2b`. Upload with `pnpm exec wrangler secret put E2B_API_KEY`; never put it in `wrangler.toml`. |
| `E2B_TEMPLATE_ID` | var | `codevil-sandbox` | E2B template the sandboxes start from, without a tag. CI deploys pin it to `<template>:<commit sha>`. |
| `E2B_MAX_SANDBOX_SECONDS` | var | `3600` | Maximum continuous sandbox runtime; the default matches the E2B Hobby limit. |
Expand Down
13 changes: 7 additions & 6 deletions packages/worker/test/deployment-config.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,18 @@ test("checked-in Worker config is portable and defaults to workers.dev", async (
assert.match(config, /binding = "BACKUP_BUCKET"/);
});

test("checked-in Worker config keeps production on the Cloudflare sandbox until E2B is ready", async () => {
test("checked-in Worker config runs production sessions on E2B", async () => {
const [config, envExample] = await Promise.all([
readFile(resolve(workerRoot, "wrangler.toml"), "utf8"),
readFile(resolve(workerRoot, ".env.example"), "utf8"),
]);
assert.match(config, /^SANDBOX_PROVIDER = "cloudflare"$/m);
assert.match(config, /^SANDBOX_PROVIDER = "e2b"$/m);
// The deploy pipeline must read the same answer, or every deploy fails.
assert.deepEqual(sandboxDeploymentSettings(config), { provider: "cloudflare" });
assert.deepEqual(sandboxDeploymentSettings(config), { provider: "e2b", templateId: "codevil-sandbox" });
// Rolling back is a one-line change the pipeline must also accept.
assert.deepEqual(
sandboxDeploymentSettings(config.replace(/^SANDBOX_PROVIDER = "cloudflare"$/m, 'SANDBOX_PROVIDER = "e2b"')),
{ provider: "e2b", templateId: "codevil-sandbox" },
sandboxDeploymentSettings(config.replace(/^SANDBOX_PROVIDER = "e2b"$/m, 'SANDBOX_PROVIDER = "cloudflare"')),
{ provider: "cloudflare" },
);
assert.doesNotMatch(config, /^E2B_API_KEY\s*=/m);
assert.match(envExample, /^E2B_API_KEY=/m);
Expand Down Expand Up @@ -253,7 +254,7 @@ test("sandbox-deploy-settings writes the provider outputs for the CI publish job
encoding: "utf8",
});
assert.equal(result.status, 0, result.stderr);
assert.equal(await readFile(outputFile, "utf8"), "sandbox_provider=cloudflare\n");
assert.equal(await readFile(outputFile, "utf8"), "sandbox_provider=e2b\ne2b_template_id=codevil-sandbox\n");
} finally {
await rm(dir, { recursive: true, force: true });
}
Expand Down
11 changes: 6 additions & 5 deletions packages/worker/wrangler.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ upload_source_maps = true

[vars]
EMAIL_PROVIDER = "none"
# Production stays on Cloudflare until E2B is ready. Switch to "e2b" only after
# setting E2B_API_KEY as a Worker secret and a GitHub Actions secret and passing
# the manual E2B end-to-end check. With "e2b", the CI deploy publishes this
# commit's template and pins E2B_TEMPLATE_ID to "<id>:<commit sha>".
# New sessions run on E2B. This needs E2B_API_KEY as a Worker secret and as a
# GitHub Actions secret in the production environment; the CI deploy publishes
# this commit's template and pins E2B_TEMPLATE_ID to "<id>:<commit sha>".
# Set "cloudflare" to roll back: new sessions return to Cloudflare containers,
# and existing sessions keep the provider they started on.
# (Code default with no var at all is "e2b"; deploys require this to be explicit.)
SANDBOX_PROVIDER = "cloudflare"
SANDBOX_PROVIDER = "e2b"
E2B_TEMPLATE_ID = "codevil-sandbox"
CODEVIL_WEB_ORIGIN = "http://localhost:5173,http://localhost:8787"
# Leaving CODEVIL_PREVIEW_ORIGIN unset keeps preview URLs on the portable
Expand Down
Loading