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.

소스 정보

저장소
TanStack/ai
최근 소스 활동
2026년 10월 22일 04:34
감지된 SKILL.md 언어
영어
스타
3,247
포크
371

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
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, threadId } = await request.json() const stream = chat({ adapter: openaiText('gpt-5.5'), messages, threadId, 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, threadId } = await request.json() const stream = chat({ adapter: openaiText('gpt-5.5'), systemPrompts: ['You are a helpful assistant.', systemPrompt], tools: [tool], messages, threadId, }) 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, threadId } = 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, threadId, }) const stream = chat({ adapter: openaiText('gpt-5.5'), tools: toolsRegistry.getTools(), messages, threadId, 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'), threadId: 'support-42', 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) => (
GitHub에서 보기
이 SKILL.md는 매우 커서 SkillsMP가 여기에는 첫 섹션만 미리 보여줍니다. GitHub에서 보기