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

# Sandbox Providers

> Learn about the provider-agnostic sandbox architecture and how to configure E2B and Daytona execution environments

## Overview

Jinba Toolbox executes tool code in **isolated sandbox environments**. The sandbox system is designed around a provider-agnostic architecture: a shared interface package (`@jinba-toolbox/sandbox-core`) defines the contract, and individual provider packages (`sandbox-e2b`, `sandbox-daytona`) implement it.

This separation means you can switch providers or add new ones without modifying any business logic.

## Architecture

```
┌─────────────────────────────────────────────────────────────┐
│                     API Server                              │
│                                                             │
│  Execution Service ──▶ SandboxProvider interface            │
│                                                             │
├─────────────────────────────────────────────────────────────┤
│                  Provider Implementations                   │
│       ┌────────────────┐       ┌─────────────────┐         │
│       │ sandbox-e2b    │       │ sandbox-daytona  │         │
│       │ (E2B Code      │       │ (Daytona SDK)    │         │
│       │  Interpreter)  │       │                  │         │
│       └────────────────┘       └─────────────────┘         │
├─────────────────────────────────────────────────────────────┤
│                    sandbox-core                              │
│           (Interfaces & Types only)                         │
└─────────────────────────────────────────────────────────────┘
```

## Core Interface

The `@jinba-toolbox/sandbox-core` package contains only interfaces and types -- no concrete implementations. All providers must conform to these contracts.

### SandboxProvider

The factory that creates and resumes sandbox instances:

```typescript theme={null}
interface SandboxProvider {
  /** Create a new sandbox instance */
  create(options: SandboxCreateOptions): Promise<SandboxInstance>;
  /** Resume an existing sandbox by ID */
  resume(sandboxId: string): Promise<SandboxInstance>;
}
```

### SandboxInstance

A running sandbox environment with code execution, shell commands, and filesystem access:

```typescript theme={null}
interface SandboxInstance {
  readonly sandboxId: string;
  readonly commands: SandboxCommands;
  readonly filesystem: SandboxFilesystem;

  executeCode(
    code: string,
    language: SandboxLanguage,
    options?: CodeExecutionOptions
  ): Promise<CodeExecutionResult>;

  kill(): Promise<void>;
  pause(): Promise<void>;
  getHost(port: number): Promise<string>;
}
```

### SandboxCommands

Shell command execution within the sandbox:

```typescript theme={null}
interface SandboxCommands {
  run(
    command: string,
    options?: SandboxCommandOptions
  ): Promise<SandboxExecutionResult>;
}
```

### SandboxFilesystem

File operations within the sandbox:

```typescript theme={null}
interface SandboxFilesystem {
  read(path: string): Promise<string>;
  readBytes(path: string): Promise<Uint8Array>;
  write(path: string, content: string | Uint8Array): Promise<void>;
  list(path: string): Promise<SandboxFileInfo[]>;
  exists(path: string): Promise<boolean>;
  mkdir(path: string): Promise<void>;
  remove(path: string): Promise<void>;
}
```

### Key Types

```typescript theme={null}
type SandboxLanguage = "python" | "typescript";

interface SandboxCreateOptions {
  language: SandboxLanguage;
  packages?: string[];               // Packages to install
  envs?: Record<string, string>;     // Environment variables
  workingDirectory?: string;         // Working directory inside sandbox
  timeoutMs?: number;                // Timeout in milliseconds
}

interface CodeExecutionResult {
  success: boolean;
  output?: unknown;       // Parsed JSON output if available
  stdout: string;
  stderr: string;
  durationMs: number;
  error?: {
    name: string;
    message: string;
    traceback?: string;
  };
}

interface SandboxExecutionResult {
  exitCode: number;
  stdout: string;
  stderr: string;
}
```

## E2B Provider

The `@jinba-toolbox/sandbox-e2b` package implements the sandbox interface using the [E2B Code Interpreter](https://e2b.dev) SDK.

### Configuration

```typescript theme={null}
import { createE2BProvider } from "@jinba-toolbox/sandbox-e2b";

const provider = createE2BProvider({
  apiKey: process.env.E2B_API_KEY!,
  templateId: "custom-template",  // Optional custom sandbox template
  timeoutMs: 300000,              // Default: 5 minutes
});
```

| Option       | Type     | Default     | Description                 |
| ------------ | -------- | ----------- | --------------------------- |
| `apiKey`     | `string` | (required)  | E2B API key                 |
| `templateId` | `string` | `undefined` | Custom sandbox template ID  |
| `timeoutMs`  | `number` | `300000`    | Default timeout (5 minutes) |

### How It Works

1. **Sandbox creation**: The provider creates an E2B Code Interpreter sandbox, optionally using a custom template.
2. **Package installation**: If packages are specified, `pip install` (Python) or `npm install` (TypeScript) runs inside the sandbox.
3. **Code execution**: Tool code is executed via E2B's `runCode` API in a Jupyter-like kernel.
4. **Lifecycle**: Sandboxes can be paused, resumed, or terminated.

### TypeScript Note

E2B's Code Interpreter executes TypeScript in a Jupyter kernel that does not support ESM file imports. For this reason, TypeScript tool code is **inlined** rather than loaded from files. Python tools can use filesystem imports normally.

## Daytona Provider

The `@jinba-toolbox/sandbox-daytona` package implements the sandbox interface using the [Daytona](https://daytona.io) SDK.

### Configuration

```typescript theme={null}
import { createDaytonaProvider } from "@jinba-toolbox/sandbox-daytona";

const provider = createDaytonaProvider({
  apiKey: process.env.DAYTONA_API_KEY!,
  apiUrl: "https://app.daytona.io/api",  // Default
  target: "us",                           // Region: "us" or "eu"
  timeoutMs: 300000,                      // Default: 5 minutes
});
```

| Option      | Type     | Default                      | Description                  |
| ----------- | -------- | ---------------------------- | ---------------------------- |
| `apiKey`    | `string` | (required)                   | Daytona API key              |
| `apiUrl`    | `string` | `https://app.daytona.io/api` | Daytona API URL              |
| `target`    | `string` | `us`                         | Target region (`us` or `eu`) |
| `timeoutMs` | `number` | `300000`                     | Default timeout (5 minutes)  |

### How It Works

1. **Sandbox creation**: The provider initializes the Daytona SDK and creates a sandbox with the specified language.
2. **Package installation**: If packages are specified, the provider runs `pip install` or `npm install` inside the sandbox.
3. **Code execution**: Tool code is executed via Daytona's `process.codeRun` API.
4. **Lifecycle**: Sandboxes can be started, stopped, and deleted.

## ToolSet Sandbox Configuration

When creating a toolset, you specify which sandbox provider and settings to use:

```typescript theme={null}
await client.createToolSet({
  slug: "data-tools",
  name: { default: "Data Tools" },
  description: { default: "Data processing tools" },
  sandbox: {
    provider: "e2b",          // or "daytona"
    language: "python",       // or "typescript"
    packages: [
      { name: "pandas", version: "2.0" },
      { name: "numpy" }
    ],
    resources: {
      cpu: "2",
      memory: "4Gi",
      timeout: 120000
    }
  }
});
```

The `SandboxConfig` stored on each toolset:

```typescript theme={null}
interface SandboxConfig {
  provider: "e2b" | "daytona";
  language: "python" | "typescript";
  runtime?: string;
  packages: { name: string; version?: string }[];
  resources: {
    cpu?: string;
    memory?: string;
    timeout?: number;
  };
}
```

## Error Handling

All sandbox packages use a unified `SandboxError` type:

```typescript theme={null}
class SandboxError extends Error {
  constructor(
    message: string,
    code: SandboxErrorCode,
    cause?: unknown
  );
}

type SandboxErrorCode =
  | "CONNECTION_FAILED"    // Failed to connect to provider
  | "TIMEOUT"              // Execution timed out
  | "NOT_FOUND"            // Sandbox not found (resume)
  | "EXECUTION_FAILED"     // Code execution failed
  | "INTERNAL";            // Unexpected internal error
```

## Adding a New Provider

The architecture is designed for extensibility. To add a new sandbox provider:

<Steps>
  <Step title="Create a new package">
    Create `packages/sandbox-<provider>` with the standard package structure.
  </Step>

  <Step title="Implement the SandboxProvider interface">
    Implement `create()` and `resume()` methods that return a `SandboxInstance`.
  </Step>

  <Step title="Register the provider">
    Add the provider case to the API server's `getSandboxProvider` function. No changes to `sandbox-core` or business logic are needed.
  </Step>
</Steps>

## Related

* [REST API](/en/pages/toolbox/developer/api) -- Endpoints for managing toolsets and running tools
* [Versioning & Publishing](/en/pages/toolbox/advanced/versioning) -- How sandbox config is frozen in versions
* [Security & Access Control](/en/pages/toolbox/advanced/security) -- Isolation and tenant boundaries
