Skip to main content

ai-code-mode

LLM-generated TypeScript execution in sandboxed environments: createCodeModeTool() with isolate drivers (createNodeIsolateDriver, createQuickJSIsolateDriver, createQuickJSBunIsolateDriver, createCloudflareIsolateDriver), codeModeWithSnippets() for persistent snippet libraries, trust strategies, snippet storage (FileSystem, LocalStorage, InMemory, Mongo), client-side execution progress via code_mode:* custom events in useChat.

Informations de source

Dépôt
TanStack/ai
Dernière activité de la source
9 septembre 2026 à 06:08
Langue détectée de SKILL.md
anglais
Étoiles
3 199
Forks
366

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
ai-code-mode
description
LLM-generated TypeScript execution in sandboxed environments: createCodeModeTool() with isolate drivers (createNodeIsolateDriver, createQuickJSIsolateDriver, createQuickJSBunIsolateDriver, createCloudflareIsolateDriver), codeModeWithSnippets() for persistent snippet libraries, trust strategies, snippet storage (FileSystem, LocalStorage, InMemory, Mongo), client-side execution progress via code_mode:* custom events in useChat.
type
core
library
tanstack-ai
library_version
0.3.8
sources
["TanStack/ai:docs/code-mode/code-mode.md","TanStack/ai:docs/code-mode/code-mode-isolates.md","TanStack/ai:docs/code-mode/code-mode-with-snippets.md","TanStack/ai:docs/code-mode/client-integration.md","TanStack/ai:docs/code-mode/lazy-tools.md"]
> **Note**: This skill requires familiarity with ai-core and ai-core/chat-experience. Code Mode is always used on top of a chat experience. ## Setup Complete Code Mode setup with Node.js isolate driver: ```typescript import { chat, toServerSentEventsResponse, toolDefinition } from '@tanstack/ai' import { openaiText } from '@tanstack/ai-openai' import { createCodeModeTool } from '@tanstack/ai-code-mode' import { createNodeIsolateDriver } from '@tanstack/ai-isolate-node' import { z } from 'zod' // Define a tool that code can call const fetchWeather = toolDefinition({ name: 'fetchWeather', description: 'Get current weather for a city', inputSchema: z.object({ city: z.string() }), outputSchema: z.object({ temp: z.number(), condition: z.string() }), }).server(async ({ city }) => { const res = await fetch(`https://api.weather.com/${city}`) return res.json() }) // Create code mode tool with Node isolate const codeModeTool = createCodeModeTool({ driver: createNodeIsolateDriver({ memoryLimit: 128, timeout: 30000, }), tools: [fetchWeather], }) // Use in chat export async function POST(request: Request) { const { messages } = await request.json() const stream = chat({ adapter: openaiText('gpt-5.5'), messages, tools: [codeModeTool], }) return toServerSentEventsResponse(stream) } ``` The recommended higher-level entry point is `createCodeMode()`, which returns both the tool and a matching system prompt: ```typescript import { chat, toServerSentEventsResponse, toolDefinition } from '@tanstack/ai' import { createCodeMode } from '@tanstack/ai-code-mode' import { createNodeIsolateDriver } from '@tanstack/ai-isolate-node' import { openaiText } from '@tanstack/ai-openai' import { z } from 'zod' const fetchWeather = toolDefinition({ name: 'fetchWeather', description: 'Get current weather for a city', inputSchema: z.object({ city: z.string() }), outputSchema: z.object({ temp: z.number(), condition: z.string() }), }).server(async ({ city }) => { const res = await fetch(`https://api.weather.com/${city}`) return res.json() }) const { tool, systemPrompt } = createCodeMode({ driver: createNodeIsolateDriver(), tools: [fetchWeather], timeout: 30_000, }) export async function POST(request: Request) { const { messages } = await request.json() const stream = chat({ adapter: openaiText('gpt-5.5'), systemPrompts: ['You are a helpful assistant.', systemPrompt], tools: [tool], messages, }) return toServerSentEventsResponse(stream) } ``` `createCodeMode` calls `createCodeModeTool` and `createCodeModeSystemPrompt` internally. The system prompt includes generated TypeScript type stubs for each tool so the LLM writes correct calls. ## Core Patterns ### 1. Choosing an Isolate Driver Four drivers implement the `IsolateDriver` interface. All are interchangeable. **Node.js** (`createNodeIsolateDriver`) -- Full V8 with JIT. Fastest option. Requires `isolated-vm` native C++ addon. ```typescript import { createNodeIsolateDriver } from '@tanstack/ai-isolate-node' const driver = createNodeIsolateDriver({ memoryLimit: 128, // MB, default 128 timeout: 30_000, // ms, default 30000 // skipProbe: false -- set true only after verifying compatibility }) ``` **QuickJS** (`createQuickJSIsolateDriver`) -- WASM-based, no native deps. Works in Node.js, browsers, Deno, Bun, and edge runtimes. Slower (interpreted, no JIT). Limited stdlib (no File I/O). ```typescript import { createQuickJSIsolateDriver } from '@tanstack/ai-isolate-quickjs' const driver = createQuickJSIsolateDriver({ memoryLimit: 128, // MB, default 128 timeout: 30_000, // ms, default 30000 maxStackSize: 524288, // bytes, default 512 KiB }) ``` **QuickJS Bun** (`createQuickJSBunIsolateDriver`) -- Native QuickJS on the Bun runtime via `bun:ffi`. Requires Bun >= 1.3.14 (throws a descriptive error on Node.js). No native deps or build step. Each context gets a dedicated QuickJS runtime with its own memory limit, stack size, and interrupt-based timeout. Recommended QuickJS option on Bun, where the WASM driver's asyncify bridge is unreliable for async host tool calls. ```typescript import { createQuickJSBunIsolateDriver } from '@tanstack/ai-isolate-quickjs-bun' const driver = createQuickJSBunIsolateDriver({ memoryLimit: 128, // MB, default 128 timeout: 30_000, // ms, default 30000 maxStackSize: 524288, // bytes, default 512 KiB }) ``` **Cloudflare** (`createCloudflareIsolateDriver`) -- Edge execution via a deployed Cloudflare Worker. Requires a `workerUrl` pointing to your deployed worker. Network latency on each tool call. ```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, // ms, default 30000 maxToolRounds: 10, // max tool-call/result cycles, default 10 }) ``` | Driver | Best for | Native deps | Browser support | Performance | | ----------- | --------------------------- | --------------- | --------------- | --------------------- | | Node | Server-side Node.js | Yes (C++ addon) | No | Fast (V8 JIT) | | QuickJS | Browsers, edge, portability | None (WASM) | Yes | Slower (interpreted) | | QuickJS Bun | Bun servers | None | No | Fast (native QuickJS) | | Cloudflare | Edge deployments | None | N/A | Fast (V8 on edge) | ### 2. Adding Persistent Snippets with codeModeWithSnippets() Snippets let the LLM save reusable code snippets. On future requests, relevant snippets are loaded and exposed as callable tools. ```typescript import { chat, maxIterations, toServerSentEventsResponse, toolDefinition, } from '@tanstack/ai' import { createNodeIsolateDriver } from '@tanstack/ai-isolate-node' import { codeModeWithSnippets, createDefaultTrustStrategy, } from '@tanstack/ai-code-mode-snippets' import { createFileSnippetStorage } from '@tanstack/ai-code-mode-snippets/storage' import { openaiText } from '@tanstack/ai-openai' import { z } from 'zod' const fetchWeather = toolDefinition({ name: 'fetchWeather', description: 'Get current weather for a city', inputSchema: z.object({ city: z.string() }), outputSchema: z.object({ temp: z.number(), condition: z.string() }), }).server(async ({ city }) => { const res = await fetch(`https://api.weather.com/${city}`) return res.json() }) // Trust strategies control how snippets earn trust through executions // Default (createDefaultTrustStrategy): untrusted -> provisional (10+ runs, >=90%) -> trusted (100+ runs, >=95%) // Relaxed (createRelaxedTrustStrategy): untrusted -> provisional (3+ runs, >=80%) -> trusted (10+ runs, >=90%) // Always trusted (createAlwaysTrustedStrategy): immediately trusted (dev/testing) // Custom (createCustomTrustStrategy): configurable thresholds const trustStrategy = createDefaultTrustStrategy() // Storage options: file system (production) or memory (testing) const storage = createFileSnippetStorage({ directory: './.snippets', trustStrategy, }) const driver = createNodeIsolateDriver() export async function POST(request: Request) { const { messages } = await request.json() // High-level API: automatic LLM-based snippet selection const { toolsRegistry, systemPrompt } = await codeModeWithSnippets({ config: { driver, tools: [fetchWeather], timeout: 60_000, memoryLimit: 128, }, adapter: openaiText('gpt-5-mini'), // cheap model for snippet selection snippets: { storage, maxSnippetsInContext: 5, }, messages, }) const stream = chat({ adapter: openaiText('gpt-5.5'), tools: toolsRegistry.getTools(), messages, systemPrompts: ['You are a helpful assistant.', systemPrompt], agentLoopStrategy: maxIterations(15), }) return toServerSentEventsResponse(stream) } ``` The registry includes: `execute_typescript`, `search_snippets`, `get_snippet`, `register_snippet`, and one tool per selected snippet. Custom trust strategy example: ```typescript import { createCustomTrustStrategy } from '@tanstack/ai-code-mode-snippets' const strategy = createCustomTrustStrategy({ initialLevel: 'untrusted', provisionalThreshold: { executions: 5, successRate: 0.85 }, trustedThreshold: { executions: 50, successRate: 0.95 }, }) ``` Storage implementations: ```typescript // File storage (production) -- persists snippets as files on disk import { createFileSnippetStorage } from '@tanstack/ai-code-mode-snippets/storage' const fileStorage = createFileSnippetStorage({ directory: './.snippets' }) // Memory storage (testing) -- in-memory, lost on restart import { createMemorySnippetStorage } from '@tanstack/ai-code-mode-snippets/storage' const memStorage = createMemorySnippetStorage() ``` ### 3. Client-Side Execution Progress Display Code Mode emits custom events during sandbox execution. Handle them in `useChat` via `onCustomEvent`. Events emitted: | Event | When | Key fields | | ----------------------------- | ------------------------------------ | -------------------------------- | | `code_mode:execution_started` | Sandbox begins | `timestamp`, `codeLength` | | `code_mode:console` | Each console.log/error/warn/info | `level`, `message`, `timestamp` | | `code_mode:external_call` | Before an external\_\* function runs | `function`, `args`, `timestamp` | | `code_mode:external_result` | After successful external\_\* call | `function`, `result`, `duration` | | `code_mode:external_error` | When external\_\* call fails | `function`, `error`, `duration` | ```tsx import { useCallback, useRef, useState } from 'react' import { useChat, fetchServerSentEvents } from '@tanstack/ai-react' interface VMEvent { id: string eventType: string data: unknown timestamp: number } export function CodeModeChat() { const [toolCallEvents, setToolCallEvents] = useState< Map<string, Array<VMEvent>> >(new Map()) const eventIdCounter = useRef(0) const handleCustomEvent = useCallback( (eventType: string, data: unknown, context: { toolCallId?: string }) => { const { toolCallId } = context if (!toolCallId) return const event: VMEvent = { id: `event-${eventIdCounter.current++}`, eventType, data, timestamp: Date.now(), } setToolCallEvents((prev) => { const next = new Map(prev) const events = next.get(toolCallId) || [] next.set(toolCallId, [...events, event]) return next }) }, [], ) const { messages, sendMessage, isLoading } = useChat({ connection: fetchServerSentEvents('/api/chat'), onCustomEvent: handleCustomEvent, }) return ( <div> {messages.map((message) => ( <div key={message.id}> {message.parts.map((part, index) => { if (part.type === 'text') { return <p key={index}>{part.content}</p> } if ( part.type === 'tool-call' && part.name === 'execute_typescript' ) { const events = toolCallEvents.get(part.id) || [] return ( <div key={part.id}> <pre>{JSON.parse(part.arguments)?.typescriptCode}</pre> {events.map((evt) => ( <div key={evt.id}> {evt.eventType}: {JSON.stringify(evt.data)} </div>
Voir sur GitHub
Ce SKILL.md est tres volumineux, SkillsMP affiche donc ici seulement la premiere section. Voir sur GitHub