← Создание агентов на Cloudflare / agents / tools / codemode
Используйте Code Mode с TanStack AI
Используйте @cloudflare/codemode/tanstack-ai точку входа, чтобы предоставить chat() один инструмент Code Mode. После этого модель может написать JavaScript, который вызывает серверные инструменты TanStack AI.
Предварительные требования
Вам понадобится существующий проект Workers и настроенный адаптер модели TanStack AI. В этом примере используется адаптер OpenAI.
Добавьте Code Mode
-
Установите Code Mode, TanStack AI, адаптер OpenAI и Zod:
npm i @cloudflare/codemode @tanstack/ai @tanstack/ai-openai zod -
Добавьте привязку Worker Loader в конфигурацию Wrangler:
{ "$schema": "./node_modules/wrangler/config-schema.json", "name": "tanstack-codemode", "main": "src/index.ts", // Set this to today's date "compatibility_date": "2026-08-28", "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-28" compatibility_flags = ["nodejs_compat"] [[worker_loaders]] binding = "LOADER" -
Определите серверные инструменты TanStack AI, сгруппируйте их в пространства имён и передайте инструмент Code Mode в
chat():src/index.jsimport { 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.tsimport { 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() возвращает TanStack AI ServerTool с именем codemode_execute. Его описание содержит сгенерированные типы для обоих пространств имён. Модель может написать код, похожий на этот:
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. Имя каждого инструмента используется как имя метода, а типы генерируются из его входной и выходной схем.
Необязательный второй аргумент задаёт пространство имён sandbox. Например, 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 или функцию. Исключённый инструмент не появляется в сгенерированных объявлениях типов и не может быть запущен в sandbox.
Инструменты с needsApproval: false остаются доступными. Устойчивый рантайм Code Mode поддерживает приостановленные подтверждения через коннектор requiresApproval аннотации, но этот createCodeTool() интеграция не использует этот поток подтверждения.