|
| 1 | +# Example Usage Walkthrough |
| 2 | + |
| 3 | +This page shows what the examples expect Anthropic to send and how the E2B worker responds. |
| 4 | + |
| 5 | +## Orchestrator Flow |
| 6 | + |
| 7 | +In the orchestrator example, your app starts the worker before sending user messages. |
| 8 | + |
| 9 | +```mermaid |
| 10 | +sequenceDiagram |
| 11 | + participant App |
| 12 | + participant Anthropic |
| 13 | + participant E2B |
| 14 | + participant Worker as EnvironmentWorker |
| 15 | +
|
| 16 | + App->>E2B: make start-worker |
| 17 | + E2B->>Worker: run client.beta.environments.work.worker(...).run() |
| 18 | + App->>Anthropic: update environment metadata with worker sandbox id |
| 19 | + Worker->>Anthropic: poll self-hosted environment work queue |
| 20 | + App->>Anthropic: create session |
| 21 | + App->>Anthropic: send user.message |
| 22 | + Anthropic-->>Worker: session work item |
| 23 | + Worker->>E2B: execute bash/read/write tools in /mnt/session |
| 24 | + Worker-->>Anthropic: user.tool_result events |
| 25 | + Anthropic-->>App: stream agent.message and status events |
| 26 | +``` |
| 27 | + |
| 28 | +### What Your App Sends |
| 29 | + |
| 30 | +`make send` creates a Managed Agents session and sends one user event: |
| 31 | + |
| 32 | +```ts |
| 33 | +const session = await client.beta.sessions.create({ |
| 34 | + agent: process.env.ANTHROPIC_AGENT_ID, |
| 35 | + environment_id: process.env.ANTHROPIC_ENVIRONMENT_ID, |
| 36 | +}); |
| 37 | + |
| 38 | +await client.beta.sessions.events.send(session.id, { |
| 39 | + events: [ |
| 40 | + { |
| 41 | + type: "user.message", |
| 42 | + content: [{ type: "text", text: "Run pwd, then echo hello from E2B" }], |
| 43 | + }, |
| 44 | + ], |
| 45 | +}); |
| 46 | +``` |
| 47 | + |
| 48 | +### What Anthropic Streams Back |
| 49 | + |
| 50 | +The exact IDs and timestamps differ, but a successful run has this shape: |
| 51 | + |
| 52 | +```jsonl |
| 53 | +{"type":"session.status_running","id":"sevt_..."} |
| 54 | +{"type":"user.message","content":[{"type":"text","text":"Run pwd, then echo hello from E2B"}]} |
| 55 | +{"type":"agent.tool_use","name":"bash","input":{"command":"pwd"}} |
| 56 | +{"type":"session.status_idle","stop_reason":{"type":"requires_action","event_ids":["sevt_..."]}} |
| 57 | +{"type":"user.tool_result","is_error":false,"content":[{"type":"text","text":"/mnt/session"}]} |
| 58 | +{"type":"session.status_running","id":"sevt_..."} |
| 59 | +{"type":"agent.tool_use","name":"bash","input":{"command":"echo hello from E2B"}} |
| 60 | +{"type":"user.tool_result","is_error":false,"content":[{"type":"text","text":"hello from E2B"}]} |
| 61 | +{"type":"agent.message","content":[{"type":"text","text":"..."}]} |
| 62 | +{"type":"session.status_idle","stop_reason":{"type":"end_turn"}} |
| 63 | +``` |
| 64 | + |
| 65 | +The `agent.tool_use` events come from Anthropic. The SDK worker running inside E2B executes those |
| 66 | +tool calls and sends matching `user.tool_result` events back to Anthropic. |
| 67 | + |
| 68 | +## Webhook Flow |
| 69 | + |
| 70 | +In the webhook example, Anthropic wakes the E2B sandbox when a session needs work. |
| 71 | + |
| 72 | +```mermaid |
| 73 | +sequenceDiagram |
| 74 | + participant Anthropic |
| 75 | + participant E2B as E2B auto-resume sandbox |
| 76 | + participant Webhook as webhook-runtime.ts |
| 77 | + participant Worker as EnvironmentWorker |
| 78 | +
|
| 79 | + Anthropic->>E2B: POST /webhook |
| 80 | + E2B->>Webhook: resume sandbox and deliver request |
| 81 | + Webhook->>Webhook: verify signature with ANTHROPIC_WEBHOOK_SIGNING_KEY |
| 82 | + Webhook->>Worker: start worker if not already running |
| 83 | + Worker->>Anthropic: poll and service session work |
| 84 | +``` |
| 85 | + |
| 86 | +### What Anthropic Sends to `/webhook` |
| 87 | + |
| 88 | +Anthropic signs the raw body and sends Standard Webhooks-style headers. The receiver passes the |
| 89 | +raw body and headers to `client.beta.webhooks.unwrap(...)`. |
| 90 | + |
| 91 | +Representative request: |
| 92 | + |
| 93 | +```http |
| 94 | +POST /webhook HTTP/1.1 |
| 95 | +content-type: application/json |
| 96 | +webhook-id: whmsg_... |
| 97 | +webhook-timestamp: 1760000000 |
| 98 | +webhook-signature: v1,... |
| 99 | +``` |
| 100 | + |
| 101 | +Representative body: |
| 102 | + |
| 103 | +```json |
| 104 | +{ |
| 105 | + "id": "event_...", |
| 106 | + "type": "event", |
| 107 | + "created_at": "2026-05-20T09:44:28.000000Z", |
| 108 | + "data": { |
| 109 | + "type": "session.status_run_started", |
| 110 | + "id": "sesn_...", |
| 111 | + "workspace_id": "wrkspc_...", |
| 112 | + "organization_id": "org_..." |
| 113 | + } |
| 114 | +} |
| 115 | +``` |
| 116 | + |
| 117 | +The JavaScript webhook handler only uses the event type: |
| 118 | + |
| 119 | +```ts |
| 120 | +const event = client.beta.webhooks.unwrap(body, { |
| 121 | + headers, |
| 122 | + key: process.env.ANTHROPIC_WEBHOOK_SIGNING_KEY, |
| 123 | +}); |
| 124 | + |
| 125 | +if (event.data.type === "session.status_run_started") { |
| 126 | + startWorkerIfNeeded(); |
| 127 | +} |
| 128 | +``` |
| 129 | + |
| 130 | +If `ANTHROPIC_WEBHOOK_SIGNING_KEY` is missing, `/webhook` returns `503` so you can start the |
| 131 | +sandbox once to get its public URL before creating the Anthropic webhook endpoint. |
| 132 | + |
| 133 | +## Worker Contract |
| 134 | + |
| 135 | +Both flows use the same worker contract: |
| 136 | + |
| 137 | +| Value | Meaning | |
| 138 | +| --- | --- | |
| 139 | +| `ANTHROPIC_ENVIRONMENT_ID` | The self-hosted environment the worker polls. | |
| 140 | +| `ANTHROPIC_ENVIRONMENT_KEY` | Bearer credential for the environment worker. | |
| 141 | +| `/mnt/session` | This example's E2B workdir. | |
| 142 | +| `/mnt/session/outputs` | Suggested artifact output directory. | |
| 143 | +| `e2b_worker_sandbox_id` | Compatibility metadata key for the most recent worker sandbox. | |
| 144 | +| `e2b_worker_sandbox_ids` | JSON metadata list of known worker sandboxes. | |
| 145 | +| `e2b_webhook_sandbox_id` | Compatibility metadata key for the most recent auto-resumable webhook sandbox. | |
| 146 | +| `e2b_webhook_sandbox_ids` | JSON metadata list of known auto-resumable webhook sandboxes. | |
| 147 | + |
| 148 | +The worker polls work at the Anthropic environment level. Multiple E2B sandboxes can be tracked and |
| 149 | +started by these examples, but strict per-session isolation needs a production routing primitive or |
| 150 | +an app-level design that scopes work to a specific worker. |
0 commit comments