@cloudflare/codemode/tanstack-ai エントリポイントを使うと、chat() に 1 つの Code Mode ツールを渡せます。モデルは、TanStack AI のサーバーツールを呼ぶ JavaScript を書けます。
既存の Workers プロジェクトと、設定済みの TanStack AI モデルアダプターが必要です。この例では OpenAI アダプターを使います。
-
Code Mode、TanStack AI、OpenAI アダプター、Zod をインストールします。
npm i @cloudflare/codemode @tanstack/ai @tanstack/ai-openai zodyarn add @cloudflare/codemode @tanstack/ai @tanstack/ai-openai zodpnpm add @cloudflare/codemode @tanstack/ai @tanstack/ai-openai zodbun add @cloudflare/codemode @tanstack/ai @tanstack/ai-openai zod -
Wrangler 設定に Worker Loader バインディングを追加します。
{ "$schema": "./node_modules/wrangler/config-schema.json", "name": "tanstack-codemode", "main": "src/index.ts", // Set this to today's date "compatibility_date": "2026-09-20", "compatibility_flags": [ "nodejs_compat" ], "worker_loaders": [ { "binding": "LOADER" } ] }name = "tanstack-codemode" main = "src/index.ts" # Set this to today's date compatibility_date = "2026-09-20" compatibility_flags = ["nodejs_compat"] [[worker_loaders]] binding = "LOADER" -
TanStack AI のサーバーツールを定義し、名前空間へまとめ、Code Mode ツールを
chat()へ渡します。src/index.jsjs import { DynamicWorkerExecutor } from "@cloudflare/codemode"; import { createCodeTool, tanstackTools, } from "@cloudflare/codemode/tanstack-ai"; import { chat, toolDefinition, toHttpResponse } from "@tanstack/ai"; import { openaiText } from "@tanstack/ai-openai"; import { z } from "zod"; const getWeather = toolDefinition({ name: "get_weather", description: "Get the current weather for a city", inputSchema: z.object({ city: z.string().meta({ description: "City name" }), }), outputSchema: z.object({ city: z.string(), temperatureCelsius: z.number(), conditions: z.string(), }), }).server(async ({ city }) => ({ city, temperatureCelsius: 22, conditions: "sunny", })); const findContacts = toolDefinition({ name: "find_contacts", description: "Find contacts for a team", inputSchema: z.object({ team: z.string().meta({ description: "Team name" }), }), outputSchema: z.array( z.object({ name: z.string(), email: z.string(), }), ), }).server(async ({ team }) => [ { name: `${team} contact`, email: "team@example.com", }, ]); function startChat(env, prompt) { const executor = new DynamicWorkerExecutor({ loader: env.LOADER }); const codeTool = createCodeTool({ tools: [ tanstackTools([getWeather], "weather"), tanstackTools([findContacts], "directory"), ], executor, }); return chat({ adapter: openaiText("gpt-4o"), messages: [{ role: "user", content: prompt }], tools: [codeTool], }); } export default { async fetch(request, env) { const prompt = await request.text(); return toHttpResponse(startChat(env, prompt)); }, };src/index.tsts import { DynamicWorkerExecutor } from "@cloudflare/codemode"; import { createCodeTool, tanstackTools, } from "@cloudflare/codemode/tanstack-ai"; import { chat, toolDefinition, toHttpResponse } from "@tanstack/ai"; import { openaiText } from "@tanstack/ai-openai"; import { z } from "zod"; const getWeather = toolDefinition({ name: "get_weather", description: "Get the current weather for a city", inputSchema: z.object({ city: z.string().meta({ description: "City name" }), }), outputSchema: z.object({ city: z.string(), temperatureCelsius: z.number(), conditions: z.string(), }), }).server(async ({ city }) => ({ city, temperatureCelsius: 22, conditions: "sunny", })); const findContacts = toolDefinition({ name: "find_contacts", description: "Find contacts for a team", inputSchema: z.object({ team: z.string().meta({ description: "Team name" }), }), outputSchema: z.array( z.object({ name: z.string(), email: z.string(), }), ), }).server(async ({ team }) => [ { name: `${team} contact`, email: "team@example.com", }, ]); function startChat(env: Env, prompt: string) { const executor = new DynamicWorkerExecutor({ loader: env.LOADER }); const codeTool = createCodeTool({ tools: [ tanstackTools([getWeather], "weather"), tanstackTools([findContacts], "directory"), ], executor, }); return chat({ adapter: openaiText("gpt-4o"), messages: [{ role: "user", content: prompt }], tools: [codeTool], }); } export default { async fetch(request, env): Promise<Response> { const prompt = await request.text(); return toHttpResponse(startChat(env, prompt)); }, } satisfies ExportedHandler<Env>;
createCodeTool() は、codemode_execute という名前の TanStack AI ServerTool を返します。説明には、両方の名前空間の生成型が含まれます。モデルは次のようなコードを書けます。
async () => {
const weatherResult = await weather.get_weather({ city: "London" });
const contacts = await directory.find_contacts({ team: "travel" });
return { weatherResult, contacts };
};tanstackTools(tools, name) は、TanStack AI ツールの配列を Code Mode のツールプロバイダーへ変換します。各ツール名をメソッド名として使い、入力と出力のスキーマから型を生成します。
省略可能な第 2 引数は、サンドボックスの名前空間を設定します。たとえば tanstackTools([getWeather], "weather") は weather.get_weather() を公開します。名前を省略すると、Code Mode はデフォルトの codemode 名前空間を使います。
const codeTool = createCodeTool({
tools: [tanstackTools([getWeather])],
executor,
});
// Available to model-generated code as codemode.get_weather().const codeTool = createCodeTool({
tools: [tanstackTools([getWeather])],
executor,
});
// Available to model-generated code as codemode.get_weather().ツールグループを組み合わせるときは、名前空間名を重複させないでください。各プロバイダーは、生成した宣言と実行可能なサーバーツールを、同じ Code Mode ツールへ提供します。
createCodeTool() 連携は、TanStack AI の承認のために実行を一時停止しません。tanstackTools() は、needsApproval プロパティが true または関数であるツールを除外します。除外されたツールは生成型宣言に現れず、サンドボックスでは実行できません。
needsApproval: false のツールは利用可能なままです。耐久 Code Mode ランタイムは、コネクターの requiresApproval アノテーションで一時停止付き承認をサポートしますが、この createCodeTool() 連携はその承認フローを使いません。