Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
89b2484
Pull in code-mode changes from ai-code-mode
jherr Feb 21, 2026
5dbebb7
more refinements
jherr Feb 26, 2026
f1f4baf
Simpler example
jherr Feb 26, 2026
2172f2c
Fewer examples
jherr Feb 26, 2026
798a1bf
Working skills example
jherr Feb 27, 2026
573298a
Home page really coming together
jherr Feb 27, 2026
a1f0859
Home page done
jherr Feb 27, 2026
7859d48
More realistic tools
jherr Feb 27, 2026
2f38fc0
Finished home page
jherr Feb 27, 2026
c87092c
Reworking the demo
jherr Mar 1, 2026
eb24789
final fixups
jherr Mar 8, 2026
708cb57
Merge remote-tracking branch 'origin/main' into code-mode
jherr Mar 10, 2026
bfc9173
last few fixups
jherr Mar 10, 2026
0d172ab
ci: apply automated fixes
autofix-ci[bot] Mar 10, 2026
8a9854d
fix: replace md-to-pdf with puppeteer+marked to fix provenance check
jherr Mar 10, 2026
b73b24f
Merge branch 'code-mode' of github.com:TanStack/ai into code-mode
jherr Mar 11, 2026
920f7a2
ci: apply automated fixes
autofix-ci[bot] Mar 11, 2026
2833b3b
add changeset for code mode packages and revert ai-devtools changes
jherr Mar 11, 2026
5550327
Merge remote-tracking branch 'origin/main' into code-mode
jherr Mar 12, 2026
1b05796
feat: add database tools demo route with in-memory DB
claude Mar 12, 2026
ca69fb5
database demo
jherr Mar 12, 2026
3c4b671
database demo
jherr Mar 12, 2026
6677dd5
feat: add gold-standard judging, export, layout fixes, and nav rename…
jherr Mar 12, 2026
904d81d
ci: apply automated fixes
autofix-ci[bot] Mar 12, 2026
48de0b4
Merge branch 'main' into code-mode
AlemTuzlak Mar 13, 2026
2deee13
simplifying
jherr Mar 14, 2026
36deae4
simplifying
jherr Mar 14, 2026
a7760b9
adding skills
jherr Mar 14, 2026
6148b02
refactoring
jherr Mar 14, 2026
ceb63b0
merged code-mode
jherr Mar 14, 2026
70ca9f3
dashboard demo start
jherr Mar 14, 2026
004860f
Merge branch 'main' into code-mode
jherr Mar 15, 2026
326e6c1
Merge remote-tracking branch 'origin/main' into code-mode
AlemTuzlak Mar 17, 2026
34c3d36
merging main
jherr Mar 18, 2026
aeecf21
small tweaks
jherr Mar 18, 2026
0790401
Merge branch 'main' into execute-prompt
jherr Mar 25, 2026
615f5a7
More execute prompt work
jherr Mar 25, 2026
a946076
Model evals
jherr Mar 26, 2026
8881bee
Model evals
jherr Mar 26, 2026
25074e4
chore: sync lockfile with models-eval dotenv ^17.2.3
jherr Mar 27, 2026
db9a7f0
ci: apply automated fixes
autofix-ci[bot] Mar 27, 2026
a91d759
ci: bump autofix-ci/action to v1.3.3 and opt into Node 24
jherr Mar 27, 2026
7c4038f
Merge branch 'execute-prompt' into code-mode
jherr Mar 27, 2026
e829527
feat(ts-code-mode-web): realtime dashboard + execute_prompt API
jherr Mar 30, 2026
36b785b
Working
jherr Mar 30, 2026
c305a91
Merge branch 'code-mode' of github.com:TanStack/ai into code-mode
jherr Mar 30, 2026
8bc70b7
Merge remote-tracking branch 'origin/main' into code-mode
jherr Mar 30, 2026
11a075c
Merged main
jherr Mar 30, 2026
16c4ffe
Merge branch 'code-mode' into execute-prompt
jherr Mar 30, 2026
6415c17
Docs update
jherr Mar 31, 2026
f34a628
ci: apply automated fixes
autofix-ci[bot] Mar 31, 2026
54e358a
final fixes
jherr Apr 1, 2026
551de30
ci: apply automated fixes
autofix-ci[bot] Apr 1, 2026
2685f76
ci: fix formatting and lint in ai-isolate-node
jherr Apr 1, 2026
3013e9d
chore: update changeset with missing packages
jherr Apr 1, 2026
c09de47
fix: correct ai-devtools package name in changeset
jherr Apr 1, 2026
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
20 changes: 20 additions & 0 deletions .changeset/code-mode-packages.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
'@tanstack/ai': minor
'@tanstack/ai-code-mode': minor
'@tanstack/ai-code-mode-skills': minor
'@tanstack/ai-isolate-cloudflare': minor
'@tanstack/ai-isolate-node': minor
'@tanstack/ai-isolate-quickjs': minor
'@tanstack/ai-event-client': minor
'@tanstack/ai-ollama': patch
'@tanstack/ai-openai': patch
'@tanstack/ai-client': patch
'@tanstack/ai-devtools-core': patch
---

Add code mode and isolate packages for secure AI code execution

Also includes fixes for Ollama tool call argument streaming and usage
reporting, OpenAI realtime adapter handling of missing call_id/item_id,
realtime client guards for missing toolCallId, and new DevtoolsChatMiddleware
type export from ai-event-client.
7 changes: 6 additions & 1 deletion .github/workflows/autofix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ jobs:
autofix:
name: autofix
runs-on: ubuntu-latest
env:
# Run JS actions (e.g. autofix-ci/action, still `node20` runtime) on Node 24 per
# https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
steps:
- name: Checkout
uses: actions/checkout@v6.0.2
Expand All @@ -24,6 +28,7 @@ jobs:
- name: Fix formatting
run: pnpm format
- name: Apply fixes
uses: autofix-ci/action@635ffb0c9798bd160680f18fd73371e355b85f27
# v1.3.3 β€” API endpoint reliability (see https://github.com/autofix-ci/action/releases/tag/v1.3.3)
uses: autofix-ci/action@7a166d7532b277f34e16238930461bf77f9d7ed8
with:
commit-message: 'ci: apply automated fixes'
10 changes: 9 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,16 @@ test-traces
playwright-report
test-results

solo.yml
.structured-output-skills

STATUS_*.md

# models-eval run artifacts (full candidate/gold text per model)
packages/typescript/ai-code-mode/models-eval/log/

.skills
# Only .claude.settings.json should be committed
.claude/settings.local.json
.claude/worktrees/*
.claude/worktrees/*
solo.yml
203 changes: 203 additions & 0 deletions docs/guides/code-mode-isolates.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
---
title: Code Mode Isolate Drivers
id: code-mode-isolates
order: 21
---

Isolate drivers provide the secure sandbox runtimes that [Code Mode](./code-mode.md) uses to execute generated TypeScript. All drivers implement the same `IsolateDriver` interface, so you can swap them without changing any other code.

## 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.js Driver (`@tanstack/ai-isolate-node`)

Uses V8 isolates via the [`isolated-vm`](https://github.com/laverdet/isolated-vm) native addon. This is the fastest option for server-side Node.js applications because generated code runs in the same V8 engine as the host, under JIT compilation, with no serialization overhead beyond tool call boundaries.

### Installation

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

`isolated-vm` is a native C++ addon and must be compiled for your platform. It requires Node.js 18 or later.

### Usage

```typescript
import { createNodeIsolateDriver } from '@tanstack/ai-isolate-node'

const driver = createNodeIsolateDriver({
memoryLimit: 128, // MB
timeout: 30_000, // ms
})
```

### Options

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `memoryLimit` | `number` | `128` | Maximum heap size for the V8 isolate, in megabytes. Execution is terminated if this limit is exceeded. |
| `timeout` | `number` | `30000` | Maximum wall-clock time per execution, in milliseconds. |

### How it works

Each `execute_typescript` call creates a fresh V8 isolate. Your tools are bridged into the isolate as async reference functions β€” when generated code calls `external_myTool(...)`, the call crosses the isolate boundary back into the host Node.js process, executes your tool implementation, and returns the result. Console output (`log`, `error`, `warn`, `info`) is captured and returned in the execution result. The isolate is destroyed after each call.

---

## QuickJS Driver (`@tanstack/ai-isolate-quickjs`)

Uses [QuickJS](https://bellard.org/quickjs/) compiled to WebAssembly via Emscripten. Because the sandbox is a WASM module, it has no native dependencies and runs anywhere JavaScript runs: Node.js, browsers, Deno, Bun, and Cloudflare Workers (without deploying a separate Worker).

### Installation

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

### Usage

```typescript
import { createQuickJSIsolateDriver } from '@tanstack/ai-isolate-quickjs'

const driver = createQuickJSIsolateDriver({
memoryLimit: 128, // MB
timeout: 30_000, // ms
maxStackSize: 524288, // bytes (512 KiB)
})
```

### Options

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `memoryLimit` | `number` | `128` | Maximum heap memory for the QuickJS VM, in megabytes. |
| `timeout` | `number` | `30000` | Maximum wall-clock time per execution, in milliseconds. |
| `maxStackSize` | `number` | `524288` | Maximum call stack size in bytes (default: 512 KiB). Increase for deeply recursive code; decrease to catch runaway recursion sooner. |

### How it works

QuickJS WASM uses an asyncified execution model β€” the WASM module can pause while awaiting host async functions (your tools). Executions are serialized through a global queue to prevent concurrent WASM calls, which the asyncify model does not support. Fatal errors (memory exhaustion, stack overflow) are detected, the VM is disposed, and a structured error is returned. Console output is captured and returned with the result.

> **Performance note:** QuickJS interprets JavaScript rather than JIT-compiling it, so compute-heavy scripts run slower than with the Node driver. For typical LLM-generated scripts that are mostly waiting on `external_*` tool calls, this difference is not significant.

---

## Cloudflare Workers Driver (`@tanstack/ai-isolate-cloudflare`)

Runs generated code inside a [Cloudflare Worker](https://workers.cloudflare.com/) at the edge. Your application server sends code and tool schemas to the Worker via HTTP; the Worker executes the code and calls back when it needs a tool result. This keeps your tool implementations on your server while sandboxed execution happens on Cloudflare's global network.

### Installation

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

### Usage

```typescript
import { createCloudflareIsolateDriver } from '@tanstack/ai-isolate-cloudflare'

const driver = createCloudflareIsolateDriver({
workerUrl: 'https://my-code-mode-worker.my-account.workers.dev',
authorization: process.env.CODE_MODE_WORKER_SECRET,
timeout: 30_000,
maxToolRounds: 10,
})
```

### Options

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `workerUrl` | `string` | β€” | **Required.** Full URL of the deployed Cloudflare Worker. |
| `authorization` | `string` | β€” | Optional value sent as the `Authorization` header on every request. Use this to prevent unauthorized access to your Worker. |
| `timeout` | `number` | `30000` | Maximum wall-clock time for the entire execution (including all tool round-trips), in milliseconds. |
| `maxToolRounds` | `number` | `10` | Maximum number of tool-call/result cycles per execution. Prevents infinite loops when generated code calls tools in a loop. |

### Deploying the Worker

The package exports a ready-made Worker handler at `@tanstack/ai-isolate-cloudflare/worker`. Create a `wrangler.toml` and a worker entry file:

```toml
# wrangler.toml
name = "code-mode-worker"
main = "src/worker.ts"
compatibility_date = "2024-01-01"

[unsafe]
bindings = [{ name = "eval", type = "eval" }]
```

```typescript
// src/worker.ts
export { default } from '@tanstack/ai-isolate-cloudflare/worker'
```

Deploy:

```bash
wrangler deploy
```

### How it works

The driver implements a request/response loop for tool execution:

```
Driver (your server) Worker (Cloudflare edge)
───────────────────── ─────────────────────────
Send: code + tool schemas ──────▢ Execute code
◀────── Return: needs tool X with args Y
Execute tool X locally
Send: tool result ──────▢ Resume execution
◀────── Return: final result / needs tool Z
...repeat until done...
```

Each round-trip adds network latency, so the `maxToolRounds` limit both prevents runaway scripts and caps the maximum number of cross-continent hops. Console output from all rounds is aggregated and returned in the final result.

> **Security:** The Worker requires `UNSAFE_EVAL` (local dev) or the `eval` unsafe binding (production) to execute arbitrary code. Restrict access using the `authorization` option or Cloudflare Access policies.

---

## The `IsolateDriver` Interface

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

```typescript
interface IsolateDriver {
createContext(config: IsolateConfig): Promise<IsolateContext>
}

interface IsolateConfig {
bindings: Record<string, ToolBinding>
timeout?: number
memoryLimit?: number
}

interface IsolateContext {
execute(code: string): Promise<ExecutionResult>
dispose(): Promise<void>
}

interface ExecutionResult<T = unknown> {
success: boolean
value?: T
logs: Array<string>
error?: NormalizedError
}
```

You can implement this interface to build a custom driver β€” for example, a Docker-based sandbox or a Deno subprocess.
Loading
Loading