Skip to main content

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

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:

SandboxInstance

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

SandboxCommands

Shell command execution within the sandbox:

SandboxFilesystem

File operations within the sandbox:

Key Types

E2B Provider

The @jinba-toolbox/sandbox-e2b package implements the sandbox interface using the E2B Code Interpreter SDK.

Configuration

How It Works

  1. Sandbox creation: The provider creates an E2B sandbox, optionally using a custom template. When the egress proxy is enabled for your organization, tool runs use the egress template and are hardened before any user code runs.
  2. Package installation: If packages are specified, pip install (Python) or npm install (TypeScript) runs inside the sandbox. Python standard-library modules are filtered out; for TypeScript, zod and tsx are always added.
  3. Egress lockdown (only when the egress proxy is enabled for the organization): Outbound network traffic from the sandbox is routed through the Jinba egress proxy; the proxy credential never enters the tool’s environment.
  4. Code execution: Python tool code is written to a file and executed through E2B’s runCode API in the Jupyter-like kernel; under egress lockdown it is run instead as a plain python3 <file> process as the sandbox user. TypeScript tool code is written to a .mts file and run with npx tsx as a regular Node.js process, so npm packages resolve normally.
  5. Lifecycle: The sandbox is killed as soon as the run finishes.

Tool Code Wrapping

The API wraps your code before execution: the input JSON is passed to the entrypoint (run by default) as Input(**data) in Python or as a plain object in TypeScript, and the return value is printed as JSON on the last line of stdout, which becomes the run’s output.

Daytona Provider

The @jinba-toolbox/sandbox-daytona package implements the sandbox interface using the Daytona SDK.

Configuration

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.
The Daytona provider does not implement the egress proxy lockdown and refuses egress-restricted runs. The console only offers E2B when creating a ToolSet; daytona can be selected through the API.

ToolSet Sandbox Configuration

When creating a toolset, you specify which sandbox provider and settings to use:
Only resources.timeout currently affects execution (it bounds sandbox creation and the tool run); cpu and memory are accepted and stored but not applied by the providers. The SandboxConfig stored on each toolset:

Error Handling

All sandbox packages use a unified SandboxError type:

Adding a New Provider

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

Create a new package

Create packages/sandbox-<provider> with the standard package structure.
2

Implement the SandboxProvider interface

Implement create() and resume() methods that return a SandboxInstance.
3

Register the provider

Add the provider case to the API server’s getSandboxProvider function. No changes to sandbox-core or business logic are needed.