> ## Documentation Index
> Fetch the complete documentation index at: https://docs.agentium.in/llms.txt
> Use this file to discover all available pages before exploring further.

# Cloud Sandbox Toolkits (E2B, Daytona)

> Execute agent-generated code in isolated cloud VMs

# Cloud Sandbox Toolkits

## Why cloud sandboxes?

Most "code interpreter" agents execute model-generated code locally. That's fine for trusted personal use but a problem in production:

* A bug or prompt injection can read your filesystem, hit your internal network, or shell-fork-bomb the process.
* Multiple concurrent sessions step on each other's state.
* You can't enforce CPU/memory/network limits cleanly across platforms.

Cloud sandboxes (E2B, Daytona, others) give each session a fresh, hardened, network-restricted VM. The agent reads/writes inside the VM, and you tear it down between sessions.

Agentium ships two adapter toolkits, both implementing the same `CloudSandbox` interface so they're interchangeable.

## `CloudSandbox` interface

```typescript theme={null}
interface CloudSandbox {
  readonly providerId: string;
  start(): Promise<void>;
  run(code: string, options?: SandboxRunOptions): Promise<SandboxRunResult>;
  shell(command: string, options?: { timeoutSeconds?: number }): Promise<SandboxRunResult>;
  writeFile(path: string, contents: string, encoding?: "utf8" | "base64"): Promise<void>;
  readFile(path: string, encoding?: "utf8" | "base64"): Promise<string | null>;
  close(): Promise<void>;
}

interface SandboxRunOptions {
  language?: "python" | "node" | "shell";  // default "python"
  timeoutSeconds?: number;                  // default 30
  env?: Record<string, string>;
}

interface SandboxRunResult {
  output: string;            // combined stdout + stderr
  exitCode?: number;         // 0 on success
  timedOut?: boolean;        // true when killed by timeout
}
```

## `E2BSandboxToolkit`

```typescript theme={null}
import { Agent, E2BSandboxToolkit, openai } from "@agentium/core";

const sandbox = new E2BSandboxToolkit({
  apiKey: process.env.E2B_API_KEY,    // defaults to E2B_API_KEY env
  template: "base",                   // E2B sandbox template; default "base"
  defaultTimeoutSeconds: 30,
});

const agent = new Agent({
  name: "data-analyst",
  model: openai("gpt-4o"),
  tools: sandbox.getTools(),
  instructions: "Write Python code to answer the user's question. Run it in the sandbox.",
});

const result = await agent.run("What are the first 20 prime numbers?");
console.log(result.text);

await sandbox.close();
```

**Requires:** `npm install @e2b/sdk`. Get an API key at [e2b.dev](https://e2b.dev).

### Tools exposed

`E2BSandboxToolkit.getTools()` returns four tools:

| Tool                     | Parameters                             | Returns                                  |
| ------------------------ | -------------------------------------- | ---------------------------------------- |
| `sandbox_e2b_run`        | `{ code, language?, timeoutSeconds? }` | JSON `{ output, exitCode }`              |
| `sandbox_e2b_shell`      | `{ command, timeoutSeconds? }`         | JSON `{ output, exitCode }`              |
| `sandbox_e2b_write_file` | `{ path, contents, encoding? }`        | `"ok"`                                   |
| `sandbox_e2b_read_file`  | `{ path, encoding? }`                  | The file content or `"[file not found]"` |

### Direct access

`toolkit.getSandbox()` returns the underlying `E2BSandbox` if you need to call it programmatically (e.g. seed files before the first agent call):

```typescript theme={null}
const e2b = sandbox.getSandbox();
await e2b.writeFile("input.csv", csvData);
await e2b.run("import pandas; df = pandas.read_csv('input.csv'); print(df.head())");
```

### Templates

E2B sandbox templates control which language runtimes, libs, and tools are preinstalled. Pass the template ID via `template`:

| Template           | Includes                                                         |
| ------------------ | ---------------------------------------------------------------- |
| `"base"` (default) | Python 3.10, Node 20, common Linux utilities                     |
| `"data-science"`   | + pandas, numpy, matplotlib, scipy, scikit-learn                 |
| Custom             | Build your own at [e2b.dev/dashboard/templates](https://e2b.dev) |

## `DaytonaSandboxToolkit`

Same interface, different backend:

```typescript theme={null}
import { Agent, DaytonaSandboxToolkit, openai } from "@agentium/core";

const sandbox = new DaytonaSandboxToolkit({
  apiKey: process.env.DAYTONA_API_KEY,
  workspace: "agent-default",          // workspace / project name
  defaultTimeoutSeconds: 30,
});

const agent = new Agent({
  name: "data-analyst",
  model: openai("gpt-4o"),
  tools: sandbox.getTools(),
});
```

**Requires:** `npm install @daytonaio/sdk`. Hosted Daytona or self-hosted both work; pass `baseURL` for self-hosted.

Tool names: `sandbox_daytona_run`, `sandbox_daytona_shell`, `sandbox_daytona_write_file`, `sandbox_daytona_read_file`.

## When to use which

| You want                            | Pick                                      |
| ----------------------------------- | ----------------------------------------- |
| Fast onboarding, generous free tier | E2B                                       |
| Self-hosted control plane           | Daytona                                   |
| Custom OS image                     | Both support it                           |
| Both in the same agent              | Yes — give the agent both toolkits' tools |

## Compose with `SandboxAgent`

If you want a persistent workspace that survives across turns AND lives in a cloud VM, plug a `CloudSandbox` into [`SandboxAgent`](/features/sandbox-agent):

```typescript theme={null}
import { E2BSandbox, SandboxAgent } from "@agentium/core";

const remote = new E2BSandbox({ template: "data-science" });

const agent = new SandboxAgent({
  backend: "remote",
  remote,
  workspace: { files: [{ path: "data.csv", contents: csvData }] },
});

await agent.start();

const r = await agent.run("import pandas; print(pandas.read_csv('data.csv').describe())", { language: "python" });
console.log(r.output);
```

## Lifecycle and cost

* Sandboxes are created lazily on the first tool call.
* They live until you call `toolkit.close()` (or the provider's idle timeout fires, usually 5–10 min).
* Always `await toolkit.close()` at the end of a request to free the sandbox.
* For multi-tenant deployments, **one sandbox per session** is the right model. Don't reuse across users.

## Failure modes

| Failure                   | Behavior                                                           |
| ------------------------- | ------------------------------------------------------------------ |
| API key missing           | Constructor throws `"missing API key"`                             |
| SDK package not installed | Constructor throws `"@e2b/sdk is required..."`                     |
| Timeout                   | `run()` returns `{ timedOut: true, exitCode: 124, output: "..." }` |
| Network error to provider | `run()` rejects; LLM sees the error string and can retry           |

## See also

* [`SandboxAgent`](/features/sandbox-agent) — persistent workspace agent that can use these as a backend
* [Computer Use Agent](/features/computer-use-agent) — for GUI control, not code execution
* [Code Interpreter Toolkit](/toolkits/code-interpreter) — local-only alternative for trusted environments
