Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
5 changes: 5 additions & 0 deletions .changeset/daytona-isolate-driver.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tanstack/ai-isolate-daytona': minor
---

Add the Daytona sandbox isolate driver for Code Mode.
82 changes: 71 additions & 11 deletions docs/code-mode/code-mode-isolates.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
title: Code Mode Isolate Drivers
id: code-mode-isolates
order: 4
description: "Compare Code Mode sandbox drivers — Node isolated-vm, QuickJS WASM, and Cloudflare Workers — and choose the right runtime for your deployment."
description: "Compare Code Mode sandbox drivers — Node isolated-vm, QuickJS WASM, Cloudflare Workers, and Daytona sandboxes — and choose the right runtime for your deployment."
keywords:
- tanstack ai
- code mode
- isolate driver
- isolated-vm
- quickjs
- cloudflare workers
- daytona
- sandbox
- secure execution
---
Expand All @@ -18,15 +19,15 @@ Isolate drivers provide the secure sandbox runtimes that [Code Mode](./code-mode

## Choosing a Driver

| | Node (`isolated-vm`) | QuickJS (WASM) | Cloudflare Workers |
|---|---|---|---|
| **Best for** | Server-side Node.js apps | Browsers, edge, portability | Edge deployments on Cloudflare |
| **Performance** | Fast (V8 JIT) | Slower (interpreted) | Fast (V8 on Cloudflare edge) |
| **Native deps** | Yes (C++ addon) | None | None |
| **Browser support** | No | Yes | N/A |
| **Memory limit** | Configurable | Configurable | N/A |
| **Stack size limit** | N/A | Configurable | N/A |
| **Setup** | `pnpm add` | `pnpm add` | Deploy a Worker first |
| | Node (`isolated-vm`) | QuickJS (WASM) | Cloudflare Workers | Daytona |
|---|---|---|---|---|
| **Best for** | Server-side Node.js apps | Browsers, edge, portability | Edge deployments on Cloudflare | Remote Daytona sandboxes |
| **Performance** | Fast (V8 JIT) | Slower (interpreted) | Fast (V8 on Cloudflare edge) | Depends on sandbox runtime |
| **Native deps** | Yes (C++ addon) | None | None | None in the driver |
| **Browser support** | No | Yes | N/A | N/A |
| **Memory limit** | Configurable | Configurable | N/A | Sandbox policy |
| **Stack size limit** | N/A | Configurable | N/A | Sandbox policy |
| **Setup** | `pnpm add` | `pnpm add` | Deploy a Worker first | Provide a Daytona sandbox |

---

Expand Down Expand Up @@ -182,9 +183,68 @@ Each round-trip adds network latency, so the `maxToolRounds` limit both prevents

---

## Daytona Driver (`@tanstack/ai-isolate-daytona`)

Runs generated code inside a Daytona sandbox through `sandbox.process.codeRun`. Your application process still owns TanStack tool implementations; the Daytona sandbox only receives wrapped generated code plus replayed tool results.

### Installation

```bash
pnpm add @tanstack/ai-isolate-daytona
```

If your application creates sandboxes with the official Daytona SDK, also install it:

```bash
pnpm add @daytona/sdk
```

### Usage

```typescript
import { Daytona } from '@daytona/sdk'
import { createDaytonaIsolateDriver } from '@tanstack/ai-isolate-daytona'

const daytona = new Daytona()
const sandbox = await daytona.create({ language: 'typescript' })

const driver = createDaytonaIsolateDriver({
sandbox,
timeout: 30_000,
maxToolRounds: 10,
})
```

### Options

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `sandbox` | `DaytonaSandboxLike` | — | **Required.** A caller-owned Daytona sandbox-like object with `process.codeRun(code, params?, timeout?)`. |
| `timeout` | `number` | `30000` | Maximum wall-clock time for the entire execution, including replay rounds, in milliseconds. |
| `maxToolRounds` | `number` | `10` | Maximum number of sandbox <-> host tool callback rounds. Prevents infinite loops when generated code repeatedly asks for tools. |

### How it works

The driver uses the same host-owned tool replay shape as the Cloudflare driver without Cloudflare's parent Worker / Dynamic Worker split:

```
Driver (your server) Daytona sandbox
───────────────────── ───────────────
Send: wrapped code ──────▶ Execute with process.codeRun
◀────── Return: need_tools with tool requests
Execute tools locally
Replay with toolResults ──────▶ Continue execution
◀────── Return: final result / more tool requests
...repeat until done...
```
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

Use this driver when you want Code Mode execution in a full Daytona sandbox instead of an in-process isolate, QuickJS WASM runtime, or Cloudflare Worker. The sandbox should use a language/runtime capable of executing the JavaScript emitted by Code Mode, and your application remains responsible for sandbox lifecycle, filesystem, network, cleanup, and secret policy. Creating a Code Mode context does not create or delete a Daytona sandbox.

---

## The `IsolateDriver` Interface

All three drivers satisfy this interface, exported from `@tanstack/ai-code-mode`:
All provided drivers satisfy this interface, exported from `@tanstack/ai-code-mode`:

```typescript
interface IsolateDriver {
Expand Down
10 changes: 7 additions & 3 deletions docs/code-mode/code-mode.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Tools you pass to Code Mode are converted to typed function stubs that appear in

### Secure sandboxing

Generated code runs in an isolated environment (V8 isolate, QuickJS WASM, or Cloudflare Worker) with no access to the host file system, network, or process. The sandbox has configurable timeouts and memory limits.
Generated code runs in an isolated environment (V8 isolate, QuickJS WASM, Cloudflare Worker, or Daytona sandbox) with no direct access to your application host. The available filesystem, network, process, timeout, and memory boundaries depend on the isolate driver you choose.

## Getting Started

Expand All @@ -56,6 +56,9 @@ pnpm add @tanstack/ai-isolate-quickjs

# Cloudflare Workers — run on the edge
pnpm add @tanstack/ai-isolate-cloudflare

# Daytona sandboxes — run in a remote Daytona sandbox
pnpm add @tanstack/ai-isolate-daytona @daytona/sdk
```

### 2. Define tools
Expand Down Expand Up @@ -209,6 +212,7 @@ interface IsolateDriver {
| `@tanstack/ai-isolate-node` | `createNodeIsolateDriver()` | Node.js |
| `@tanstack/ai-isolate-quickjs` | `createQuickJSIsolateDriver()` | Node.js, browser, edge |
| `@tanstack/ai-isolate-cloudflare` | `createCloudflareIsolateDriver()` | Cloudflare Workers |
| `@tanstack/ai-isolate-daytona` | `createDaytonaIsolateDriver()` | Daytona sandboxes |

For full configuration options for each driver, see [Isolate Drivers](./code-mode-isolates.md).

Expand All @@ -224,7 +228,7 @@ These utilities are used internally and are exported for custom pipelines:

For a full comparison of drivers with all configuration options, see [Isolate Drivers](./code-mode-isolates.md).

In brief: use the **Node driver** for server-side Node.js (fastest, V8 JIT), **QuickJS** for browsers or portable edge deployments (no native deps), and the **Cloudflare driver** when you deploy to Cloudflare Workers.
In brief: use the **Node driver** for server-side Node.js (fastest, V8 JIT), **QuickJS** for browsers or portable edge deployments (no native deps), the **Cloudflare driver** when you deploy to Cloudflare Workers, and the **Daytona driver** when you want execution inside a Daytona sandbox while your application keeps ownership of server tool implementations.

## Custom Events

Expand Down Expand Up @@ -290,4 +294,4 @@ pnpm eval -- --no-judge # skip Anthropic-based judging

- [Showing Code Mode in the UI](./client-integration) — Display execution progress in your React app
- [Code Mode with Skills](./code-mode-with-skills) — Add persistent, reusable skill libraries
- [Isolate Drivers](./code-mode-isolates) — Compare Node, QuickJS, and Cloudflare sandbox runtimes
- [Isolate Drivers](./code-mode-isolates) — Compare Node, QuickJS, Cloudflare, and Daytona sandbox runtimes
92 changes: 92 additions & 0 deletions packages/typescript/ai-isolate-daytona/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# @tanstack/ai-isolate-daytona

Daytona sandbox driver for TanStack AI Code Mode.

This package runs generated JavaScript or TypeScript in a caller-provided Daytona sandbox and keeps TanStack tool implementations in your host process. When generated code calls an `external_*` tool, the sandbox returns a `need_tools` payload, the host executes the matching `ToolBinding.execute` callbacks, and the driver replays the code with accumulated tool results until it completes.

## Installation

```bash
pnpm add @tanstack/ai-isolate-daytona @tanstack/ai-code-mode
```

If you use the official Daytona SDK to create sandboxes, install it in your app too:

```bash
pnpm add @daytona/sdk
```

## Usage

```typescript
import { Daytona } from '@daytona/sdk'
import { createCodeMode } from '@tanstack/ai-code-mode'
import { createDaytonaIsolateDriver } from '@tanstack/ai-isolate-daytona'

const daytona = new Daytona()
const sandbox = await daytona.create({ language: 'typescript' })

const driver = createDaytonaIsolateDriver({
sandbox,
timeout: 30_000,
maxToolRounds: 10,
})

const { tool, systemPrompt } = createCodeMode({
driver,
tools: [myServerTool],
})
```

The driver accepts a structural sandbox object with `sandbox.process.codeRun(...)`; it does not require `@daytona/sdk` as a package dependency.

## API

### `createDaytonaIsolateDriver(config)`

Creates an isolate driver that delegates Code Mode execution to a Daytona sandbox.

- `sandbox` (required): caller-owned object with `process.codeRun(code, params?, timeout?)`
- `timeout` (optional): total execution timeout across replay rounds, in milliseconds (default: `30000`)
- `maxToolRounds` (optional): maximum `need_tools` replay rounds per execution (default: `10`)

## Requirements

- The sandbox must support `process.codeRun`.
- Use a sandbox language/runtime that can execute the JavaScript emitted by Code Mode.
- Tool inputs and outputs must be JSON-serializable.
- Sandbox lifecycle, network access, filesystem contents, secrets, and cleanup are owned by your application. Creating a Code Mode context does not create or delete a Daytona sandbox.

## How It Works

```
Host process Daytona sandbox
------------ ---------------
createCodeMode + tools
wrap generated code ---------> run with process.codeRun
execute host tools <--------- need_tools requests
replay with toolResults ---------> continue execution
final result/logs <--------- done or error envelope
```

Unlike the Cloudflare driver, Daytona does not need a parent Worker / Dynamic Worker split. The host process talks directly to a Daytona sandbox through `process.codeRun`, while tool execution stays host-owned.

## Validation

Run the package checks once the implementation files are present:

```bash
pnpm --filter @tanstack/ai-isolate-daytona test:lib
pnpm --filter @tanstack/ai-isolate-daytona test:types
pnpm --filter @tanstack/ai-isolate-daytona test:eslint
pnpm --filter @tanstack/ai-isolate-daytona build
pnpm --filter @tanstack/ai-isolate-daytona test:build
```

Live Daytona validation should be gated on explicit credentials and sandbox setup in the implementation tests or a local smoke script.

```bash
DAYTONA_LIVE_TEST=1 DAYTONA_API_KEY=... pnpm --filter @tanstack/ai-isolate-daytona test:live
```

The live suite is skipped unless `DAYTONA_LIVE_TEST=1` and `DAYTONA_API_KEY` are both present.
59 changes: 59 additions & 0 deletions packages/typescript/ai-isolate-daytona/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{
"name": "@tanstack/ai-isolate-daytona",
"version": "0.0.1",
"description": "Daytona sandbox driver for TanStack AI Code Mode TypeScript execution.",
"author": "",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/TanStack/ai.git",
"directory": "packages/typescript/ai-isolate-daytona"
},
"type": "module",
"module": "./dist/esm/index.js",
"types": "./dist/esm/index.d.ts",
"exports": {
".": {
"types": "./dist/esm/index.d.ts",
"import": "./dist/esm/index.js"
}
},
"sideEffects": false,
"engines": {
"node": ">=18"
},
"files": [
"dist",
"src"
],
"scripts": {
"build": "vite build",
"clean": "premove ./build ./dist",
"lint:fix": "eslint ./src --fix",
"test:build": "publint --strict",
"test:eslint": "eslint ./src",
"test:live": "vitest --run tests/live.test.ts",
"test:lib": "vitest --passWithNoTests",
"test:lib:dev": "pnpm test:lib --watch",
"test:types": "tsc"
},
"keywords": [
"ai",
"ai-sdk",
"typescript",
"tanstack",
"code-mode",
"daytona",
"sandbox",
"isolate",
"code-execution"
],
"peerDependencies": {
"@tanstack/ai-code-mode": "workspace:*"
},
"devDependencies": {
"@daytona/sdk": "^0.180.0",
"@tanstack/ai-code-mode": "workspace:*",
"@vitest/coverage-v8": "4.0.14"
}
}
36 changes: 36 additions & 0 deletions packages/typescript/ai-isolate-daytona/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* @tanstack/ai-isolate-daytona
*
* Daytona sandbox driver for TanStack AI Code Mode.
* Execute LLM-generated code inside a caller-provided Daytona sandbox.
*
* @example
* ```typescript
* import { createDaytonaIsolateDriver } from '@tanstack/ai-isolate-daytona'
*
* const driver = createDaytonaIsolateDriver({ sandbox })
* ```
*
* @packageDocumentation
*/

export {
createDaytonaIsolateDriver,
type DaytonaIsolateDriverConfig,
} from './isolate-driver'

export type {
DaytonaCodeRunArtifacts,
DaytonaCodeRunParams,
DaytonaCodeRunResponse,
DaytonaProcessLike,
DaytonaSandboxLike,
} from './types'

export type {
ExecutionResult,
IsolateConfig,
IsolateContext,
IsolateDriver,
NormalizedError,
} from '@tanstack/ai-code-mode'
Loading