@cloudflare/codemode/ai 入口将 AI SDK 工具转换为一个 Code Mode 工具。模型编写调用工具的 JavaScript,执行器在隔离沙箱中运行该代码。
在两种集成模式间选择:
| 模式 | 用例 | 审批行为 |
|---|---|---|
createCodeTool() |
一个或多个工具提供商的简单无状态执行 | 排除使用 needsApproval 的工具 |
ToolSetConnector 或 toolSetConnector() |
通过 Code Mode 运行时的持久执行 | 将 needsApproval 映射到持久运行时审批 |
createCodeTool() 接受 AI SDK ToolSet 或工具提供商数组。还需要执行器。返回标准 AI SDK 工具,供 streamText() 或 generateText() 使用。
-
安装 Code Mode、AI SDK 与 Zod:
npm i @cloudflare/codemode agents ai zodyarn add @cloudflare/codemode agents ai zodpnpm add @cloudflare/codemode agents ai zodbun add @cloudflare/codemode agents ai zod -
为
DynamicWorkerExecutor添加 Worker Loader 绑定:{ "$schema": "./node_modules/wrangler/config-schema.json", // Set this to today's date "compatibility_date": "2026-08-17", "compatibility_flags": [ "nodejs_compat" ], "worker_loaders": [ { "binding": "LOADER" } ] }# Set this to today's date compatibility_date = "2026-08-17" compatibility_flags = ["nodejs_compat"] [[worker_loaders]] binding = "LOADER" -
定义可执行的 AI SDK tool。Code Mode 使用其 schema 生成类型并在调用
execute前验证参数。src/tools.jsjs import { tool } from "ai"; import { z } from "zod"; export const weatherTools = { getWeather: tool({ description: "Get the weather for a city", inputSchema: z.object({ city: z.string().describe("City name"), }), outputSchema: z.object({ city: z.string(), conditions: z.string(), }), execute: async ({ city }) => ({ city, conditions: "sunny", }), }), };src/tools.tsts import { tool } from "ai"; import { z } from "zod"; export const weatherTools = { getWeather: tool({ description: "Get the weather for a city", inputSchema: z.object({ city: z.string().describe("City name") }), outputSchema: z.object({ city: z.string(), conditions: z.string() }), execute: async ({ city }) => ({ city, conditions: "sunny" }) }) };每个沙箱可调用 tool 需要
execute函数。Client-side 或 provider 执行的 tool 无法通过此 server-side executor 运行。 -
创建 Code Mode tool 并传给 AI SDK model 调用:
src/index.jsjs import { DynamicWorkerExecutor } from "@cloudflare/codemode"; import { createCodeTool } from "@cloudflare/codemode/ai"; import { generateText, stepCountIs } from "ai"; import { model } from "./model"; import { weatherTools } from "./tools"; export default { async fetch(request, env) { const executor = new DynamicWorkerExecutor({ loader: env.LOADER }); const codemode = createCodeTool({ tools: weatherTools, executor }); const response = await generateText({ model, prompt: await request.text(), tools: { codemode }, stopWhen: stepCountIs(5), }); return new Response(response.text); }, };src/index.tsts import { DynamicWorkerExecutor } from "@cloudflare/codemode"; import { createCodeTool } from "@cloudflare/codemode/ai"; import { generateText, stepCountIs } from "ai"; import { model } from "./model"; import { weatherTools } from "./tools"; export default { async fetch(request, env): Promise<Response> { const executor = new DynamicWorkerExecutor({ loader: env.LOADER }); const codemode = createCodeTool({ tools: weatherTools, executor }); const response = await generateText({ model, prompt: await request.text(), tools: { codemode }, stopWhen: stepCountIs(5), }); return new Response(response.text); }, } satisfies ExportedHandler<Env>;
示例使用 generateText() 获取完整响应。可将相同 codemode tool 传给 streamText() 以流式传输。生成的 tool 描述包含 getWeather 的 TypeScript 定义。模型仍编写 JavaScript,例如:
async () => {
const weather = await codemode.getWeather({ city: "Lisbon" });
return weather.conditions;
};默认命名空间为 codemode。createCodeTool() 也接受自定义 description。在 Code Mode 应插入生成定义处包含 {{types}}。
Tool provider 将 tool 分组到一个沙箱命名空间下。每个 tool 属于 codemode.* 时直接传递 tool set。
与其他包的 provider 组合 AI SDK tool 时使用 aiTools()。以下可选 workspace 示例还需要 @cloudflare/shell:
npm i @cloudflare/shellyarn add @cloudflare/shellpnpm add @cloudflare/shellbun add @cloudflare/shellimport { AIChatAgent } from "@cloudflare/ai-chat";
import { DynamicWorkerExecutor } from "@cloudflare/codemode";
import { aiTools, createCodeTool } from "@cloudflare/codemode/ai";
import { Workspace } from "@cloudflare/shell";
import { stateTools } from "@cloudflare/shell/workers";
import { weatherTools } from "./tools";
export class Chat extends AIChatAgent {
workspace = new Workspace({ sql: this.ctx.storage.sql });
codemodeTool() {
return createCodeTool({
tools: [aiTools(weatherTools), stateTools(this.workspace)],
executor: new DynamicWorkerExecutor({ loader: this.env.LOADER }),
});
}
}import { AIChatAgent } from "@cloudflare/ai-chat";
import { DynamicWorkerExecutor } from "@cloudflare/codemode";
import { aiTools, createCodeTool } from "@cloudflare/codemode/ai";
import { Workspace } from "@cloudflare/shell";
import { stateTools } from "@cloudflare/shell/workers";
import { weatherTools } from "./tools";
export class Chat extends AIChatAgent<Env> {
workspace = new Workspace({ sql: this.ctx.storage.sql });
codemodeTool() {
return createCodeTool({
tools: [aiTools(weatherTools), stateTools(this.workspace)],
executor: new DynamicWorkerExecutor({ loader: this.env.LOADER }),
});
}
}此示例将 AI SDK tool 暴露为 codemode.*,workspace tool 为 state.*。
要分配自定义命名空间,改为传递 provider 对象:
const executor = new DynamicWorkerExecutor({ loader: env.LOADER });
const codemode = createCodeTool({
tools: [
{ name: "weather", tools: weatherTools },
{ name: "notifications", tools: notificationTools },
],
executor,
});const executor = new DynamicWorkerExecutor({ loader: env.LOADER });
const codemode = createCodeTool({
tools: [
{ name: "weather", tools: weatherTools },
{ name: "notifications", tools: notificationTools },
],
executor,
});生成的代码可调用 weather.getWeather() 与 notifications.send()。Provider 名称须唯一且为有效 JavaScript 标识符。
当运行需要持久状态时使用 ToolSetConnector 或其 toolSetConnector() 便利函数。连接器将 AI SDK ToolSet 适配 createCodemodeRuntime()。辅助函数返回 new ToolSetConnector(ctx, options)。
在 Agent 或另一 Durable Object 内创建 connector:
import { AIChatAgent } from "@cloudflare/ai-chat";
import {
createCodemodeRuntime,
DynamicWorkerExecutor,
} from "@cloudflare/codemode";
import { toolSetConnector } from "@cloudflare/codemode/ai";
import { convertToModelMessages, streamText } from "ai";
import { model } from "./model";
import { operationTools } from "./tools";
// Export this manually when the @cloudflare/codemode/vite plugin is not configured.
export { CodemodeRuntime } from "@cloudflare/codemode";
export class OperationsAgent extends AIChatAgent {
async onChatMessage() {
const operations = toolSetConnector(this.ctx, {
name: "operations",
instructions: "Use these tools to manage customer requests.",
tools: operationTools,
});
const runtime = createCodemodeRuntime({
ctx: this.ctx,
executor: new DynamicWorkerExecutor({ loader: this.env.LOADER }),
connectors: [operations],
});
const result = streamText({
model,
messages: await convertToModelMessages(this.messages),
tools: { codemode: runtime.tool() },
});
return result.toUIMessageStreamResponse();
}
}import { AIChatAgent } from "@cloudflare/ai-chat";
import {
createCodemodeRuntime,
DynamicWorkerExecutor,
} from "@cloudflare/codemode";
import { toolSetConnector } from "@cloudflare/codemode/ai";
import { convertToModelMessages, streamText } from "ai";
import { model } from "./model";
import { operationTools } from "./tools";
// Export this manually when the @cloudflare/codemode/vite plugin is not configured.
export { CodemodeRuntime } from "@cloudflare/codemode";
export class OperationsAgent extends AIChatAgent<Env> {
async onChatMessage() {
const operations = toolSetConnector(this.ctx, {
name: "operations",
instructions: "Use these tools to manage customer requests.",
tools: operationTools,
});
const runtime = createCodemodeRuntime({
ctx: this.ctx,
executor: new DynamicWorkerExecutor({ loader: this.env.LOADER }),
connectors: [operations],
});
const result = streamText({
model,
messages: await convertToModelMessages(this.messages),
tools: { codemode: runtime.tool() },
});
return result.toUIMessageStreamResponse();
}
}示例手动导出 CodemodeRuntime。若按 创建持久 Code Mode 运行时 配置 Code Mode Vite 插件,移除该手动导出,因插件会添加。
省略 name 时连接器默认为 tools 命名空间。从无 execute 函数的工具中排除生成类型与沙箱绑定。
持久运行时添加执行日志、暂停/恢复行为与按需连接器发现。模型可用 codemode.search() 查找方法并用 codemode.describe() 检查类型。
两种集成模式对 AI SDK 审批处理不同。
createCodeTool() 过滤 needsApproval 为 true 或函数的工具。过滤的工具不出现在生成类型中,无法从沙箱代码运行。needsApproval: false 的工具仍可用。
此无状态路径不为 AI SDK 审批暂停执行。若工具需要 AI SDK 审批流程,在 Code Mode 外使用标准 AI SDK 工具。
ToolSetConnector 将 AI SDK needsApproval 映射到持久运行时的 requiresApproval 注解。调用该工具会暂停运行。应用可检查待处理操作并用 runtime.approve({ executionId }) 恢复同一执行。
函数值 needsApproval 无法在沙箱提供参数前求值。因此连接器将该工具视为始终需要审批。needsApproval: false 执行时不暂停。
此审批使用 Code Mode 运行时的持久暂停、审批与重放流程。不使用 AI SDK 按次审批流程。