使用 @cloudflare/codemode/tanstack-ai 入口为 chat() 提供一个 Code Mode tool。模型随后可编写 JavaScript 调用 TanStack AI server tool。
需要现有 Workers 项目与已配置的 TanStack AI model adapter。本例使用 OpenAI adapter。
-
安装 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 binding:
{ "$schema": "./node_modules/wrangler/config-schema.json", "name": "tanstack-codemode", "main": "src/index.ts", // Set this to today's date "compatibility_date": "2026-08-17", "compatibility_flags": [ "nodejs_compat" ], "worker_loaders": [ { "binding": "LOADER" } ] }name = "tanstack-codemode" main = "src/index.ts" # Set this to today's date compatibility_date = "2026-08-17" compatibility_flags = ["nodejs_compat"] [[worker_loaders]] binding = "LOADER" -
定义 TanStack AI server tool,分组到 namespace,并将 Code Mode tool 传给
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: "[email protected]", }, ]); 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: "[email protected]", }, ]); 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。其 description 包含两个 namespace 的生成类型。模型可编写类似代码:
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 tool 数组转为 Code Mode tool provider。以每个 tool 名作为 method 名,并从 input/output schema 生成类型。
可选第二参数设置 sandbox namespace。例如 tanstackTools([getWeather], "weather") 暴露 weather.get_weather()。省略 name 时 Code Mode 使用默认 codemode namespace:
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 审批暂停执行。needsApproval 为 true 或函数时 tanstackTools() 排除该 tool。被排除的 tool 不出现在生成类型声明中,也不能在 sandbox 中运行。
needsApproval: false 的工具仍可用。持久 Code Mode 运行时通过连接器 requiresApproval 注解支持暂停审批,但此 createCodeTool() 集成不使用该审批流程。