Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Comprehensive Cloudflare platform skill covering Workers, D1, R2, KV, AI, Durable Objects, and security.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/agents-sdk/api.md
1# API Reference23## Agent Classes45### AIChatAgent67For AI chat with auto-streaming, message history, tools, resumable streaming.89```ts10import { AIChatAgent } from "@cloudflare/ai-chat";11import { openai } from "@ai-sdk/openai";1213export class ChatAgent extends AIChatAgent<Env> {14async onChatMessage(onFinish) {15return this.streamText({16model: openai("gpt-4"),17messages: this.messages, // Auto-managed message history18tools: {19getWeather: {20description: "Get weather",21parameters: z.object({ city: z.string() }),22execute: async ({ city }) => `Sunny, 72°F in ${city}`23}24},25onFinish, // Persist response to this.messages26});27}28}29```3031### Agent (Base Class)3233Full control for custom logic, WebSockets, email, and SQL.3435```ts36import { Agent } from "agents";3738export class MyAgent extends Agent<Env, State> {39// Lifecycle methods below40}41```4243**Type params:** `Agent<Env, State, ConnState>` - Env bindings, agent state, connection state4445## Lifecycle Hooks4647```ts48onStart() { // Init/restart49this.sql`CREATE TABLE IF NOT EXISTS users (id TEXT, name TEXT)`;50}5152async onRequest(req: Request) { // HTTP53const {pathname} = new URL(req.url);54if (pathname === "/users") return Response.json(this.sql<{id,name}>`SELECT * FROM users`);55return new Response("Not found", {status: 404});56}5758async onConnect(conn: Connection<ConnState>, ctx: ConnectionContext) { // WebSocket59conn.accept();60conn.setState({userId: ctx.request.headers.get("X-User-ID")});61conn.send(JSON.stringify({type: "connected", state: this.state}));62}6364async onMessage(conn: Connection<ConnState>, msg: WSMessage) { // WS messages65const m = JSON.parse(msg as string);66this.setState({messages: [...this.state.messages, m]});67this.connections.forEach(c => c.send(JSON.stringify(m)));68}6970async onEmail(email: AgentEmail) { // Email routing71this.sql`INSERT INTO emails (from_addr,subject,body) VALUES (${email.from},${email.headers.get("subject")},${await email.text()})`;72}73```7475## State, SQL, Scheduling7677```ts78// State79this.setState({count: 42}); // Auto-syncs80this.setState({...this.state, count: this.state.count + 1});8182// SQL (parameterized queries prevent injection)83this.sql`CREATE TABLE IF NOT EXISTS users (id TEXT PRIMARY KEY, name TEXT)`;84this.sql`INSERT INTO users (id,name) VALUES (${userId},${name})`;85const users = this.sql<{id,name}>`SELECT * FROM users WHERE id = ${userId}`;8687// Scheduling88await this.schedule(new Date("2026-12-25"), "sendGreeting", {msg:"Hi"}); // Date89await this.schedule(60, "checkStatus", {}); // Delay (sec)90await this.schedule("0 0 * * *", "dailyCleanup", {}); // Cron91await this.cancelSchedule(scheduleId);92```9394## RPC Methods (@callable)9596```ts97import { Agent, callable } from "agents";9899export class MyAgent extends Agent<Env> {100@callable()101async processTask(input: {text: string}): Promise<{result: string}> {102return { result: await this.env.AI.run("@cf/meta/llama-3.1-8b-instruct", {prompt: input.text}) };103}104}105// Client: const result = await agent.processTask({ text: "Hello" });106// Must return JSON-serializable values107```108109## Connections & AI110111```ts112// Connections (type: Agent<Env, State, ConnState>)113this.connections.forEach(c => c.send(JSON.stringify(msg))); // Broadcast114conn.setState({userId:"123"}); conn.close(1000, "Goodbye");115116// Workers AI117const r = await this.env.AI.run("@cf/meta/llama-3.1-8b-instruct", {prompt});118119// Manual streaming (prefer AIChatAgent)120const stream = await client.chat.completions.create({model: "gpt-4", messages, stream: true});121for await (const chunk of stream) conn.send(JSON.stringify({chunk: chunk.choices[0].delta.content}));122```123124**Type-safe state:** `Agent<Env, State, ConnState>` - third param types `conn.state`125126## MCP Integration127128Model Context Protocol for exposing tools:129130```ts131// Register & use MCP server132await this.mcp.registerServer("github", {133url: env.MCP_SERVER_URL,134auth: { type: "oauth", clientId: env.GITHUB_CLIENT_ID, clientSecret: env.GITHUB_CLIENT_SECRET }135});136const tools = await this.mcp.getAITools(["github"]);137return this.streamText({ model: openai("gpt-4"), messages: this.messages, tools, onFinish });138```139140## Task Queue141142```ts143await this.queue("processVideo", { videoId: "abc123" }); // Add task144const tasks = await this.dequeue(10); // Process up to 10145```146147## Context & Cleanup148149```ts150const agent = getCurrentAgent<MyAgent>(); // Get current instance151async destroy() { /* cleanup before agent destroyed */ }152```153154## AI Integration155156```ts157// Workers AI158const r = await this.env.AI.run("@cf/meta/llama-3.1-8b-instruct", {prompt});159160// Manual streaming (prefer AIChatAgent for auto-streaming)161const stream = await client.chat.completions.create({model: "gpt-4", messages, stream: true});162for await (const chunk of stream) {163if (chunk.choices[0]?.delta?.content) conn.send(JSON.stringify({chunk: chunk.choices[0].delta.content}));164}165```166167## Client Hooks (React)168169```ts170// useAgent() - WebSocket connection + RPC171import { useAgent } from "agents/react";172const agent = useAgent({ agent: "MyAgent", name: "user-123" }); // name for idFromName173const result = await agent.processTask({ text: "Hello" }); // Call @callable methods174// agent.readyState: 0=CONNECTING, 1=OPEN, 2=CLOSING, 3=CLOSED175176// useAgentChat() - AI chat UI177import { useAgentChat } from "@cloudflare/ai-chat/react";178const agent = useAgent({ agent: "ChatAgent" });179const { messages, input, handleInputChange, handleSubmit, isLoading, stop, clearHistory } =180useAgentChat({181agent,182maxSteps: 5, // Max tool iterations183resume: true, // Auto-resume on disconnect184onToolCall: async (toolCall) => {185// Client tools (human-in-the-loop)186if (toolCall.toolName === "confirm") return { ok: window.confirm("Proceed?") };187}188});189// status: "ready" | "submitted" | "streaming" | "error"190```191