Skip to content

SYSTEM Cited by 5 sources

Cloudflare Agents SDK

Overview

The Cloudflare Agents SDK (@cloudflare/agents) is Cloudflare's TypeScript / JavaScript SDK for building AI agents on the Workers developer platform. It provides the base classes (AIChatAgent, Agent), the routing helper (routeAgentRequest), and the conventions around Durable Object-per-agent-instance actor-model deployment.

Role in the stack

  • Substrate: Durable Objects — one DO per agent session, realising one-to-one actor deployment.
  • Inference: plugs into Workers AI + AI Gateway or external providers via the Vercel ai SDK.
  • Retrieval: composes with AI Search via the ai_search_namespaces binding.
  • Tools: MCP + custom tools registered via the tool() helper with zod schemas.
  • UI: toUIMessageStreamResponse() + chat-starter template for the frontend.

Canonical usage shape

From the 2026-04-16 AI Search support-agent worked example:

import { AIChatAgent, type OnChatMessageOptions } from "@cloudflare/ai-chat";
import { routeAgentRequest } from "agents";

export class SupportAgent extends AIChatAgent<Env> {
  async onChatMessage(_onFinish: unknown, options?: OnChatMessageOptions) {
    // per-agent state, tool definitions, LLM call, streaming response
  }
}

export default {
  async fetch(request: Request, env: Env) {
    return (await routeAgentRequest(request, env)) ||
           new Response("Not found", { status: 404 });
  }
} satisfies ExportedHandler<Env>;

AIChatAgent.messages is the full conversation history, automatically persisted by the SDK across reconnects — the actor-model-with-embedded-state property.

Inference resilience — buffered resumable streaming via AI Gateway (2026-04-16)

The 2026-04-16 AI Platform post extends the SDK's reliability story beyond step-level checkpointing to mid-inference resumability:

"If you're building long-running agents with Agents SDK, your streaming inference calls are also resilient to disconnects. AI Gateway buffers streaming responses as they're generated, independently of your agent's lifetime. If your agent is interrupted mid-inference, it can reconnect to AI Gateway and retrieve the response without having to make a new inference call or paying twice for the same output tokens. Combined with the Agents SDK's built-in checkpointing, the end user never notices."

The two-tier pairing:

  • SDK-side: the existing AIChatAgent.messages persistence + checkpointing — agent state survives code restarts.
  • Gateway-side: AI Gateway buffers the streaming inference response independently of the Agent DO's lifetime, so a restarted agent reconnects to the same stream rather than restarting the inference call.

Paired with the Agents SDK's inherent actor-model persistence (this.setState(...) + DO lifecycle), end users see no evidence of a mid-turn crash — the "never notices" property requires both tiers. See concepts/resilient-inference-stream, patterns/buffered-resumable-inference-stream.

Evolution — Project Think

The 2026-04-15 Project Think launch positions itself as "the next generation of the Agents SDK" — not a replacement, an evolution. Project Think's six primitives (durable fibers, sub-agents via Facets, Persistent Sessions, sandboxed code execution, execution ladder, self-authored extensions) layer on top of the Agents SDK's existing base classes.

Email-native — onEmail + sendEmail + routeAgentEmail (2026-04-16 post)

The 2026-04-16 Email Service public-beta post extends the SDK with a full bidirectional email surface:

  • onEmail(email: AgentEmail) hook on the Agent base class — the inbound counterpart of onChatMessage; triggered when an email arrives at an address owned by this agent instance.
  • this.sendEmail({ binding, fromName, from, to, inReplyTo, subject, text, … }) — outbound from a DO instance; previously could only reply synchronously or send within the same Cloudflare account, now can send to anyone thanks to Email Sending public beta.
  • routeAgentEmail(message, env, { resolver }) — Worker-level dispatcher; drop into the export default { async email(message, env) { … } } handler.
  • createAddressBasedEmailResolver(className) — built-in resolver that parses the To: address's local-part as the agent class and plus-sub as the instance (RFC-5233 sub-addressing). Canonical wiki instance of patterns/sub-addressed-agent-instance.
  • HMAC-SHA256-signed reply-routing headers — when inReplyTo is set on outbound, reply routing headers are signed so replies route back to the exact DO instance that sent the original, even across forwarders. See patterns/signed-reply-routing-header.

Worked example (from the 2026-04-16 post):

import { Agent, routeAgentEmail } from "agents";
import { createAddressBasedEmailResolver, type AgentEmail } from "agents/email";
import PostalMime from "postal-mime";

export class SupportAgent extends Agent {
  async onEmail(email: AgentEmail) {
    const raw = await email.getRaw();
    const parsed = await PostalMime.parse(raw);
    this.setState({
      ...this.state,
      ticket: { from: email.from, subject: parsed.subject, body: parsed.text, messageId: parsed.messageId },
    });
    await this.sendEmail({
      binding: this.env.EMAIL,
      fromName: "Support Agent",
      from: "support@your-agents.example",
      to: this.state.ticket.from,
      inReplyTo: this.state.ticket.messageId,
      subject: `Re: ${this.state.ticket.subject}`,
      text: `Thanks for reaching out...`,
    });
  }
}

export default {
  async email(message, env) {
    await routeAgentEmail(message, env, {
      resolver: createAddressBasedEmailResolver("SupportAgent"),
    });
  },
} satisfies ExportedHandler<Env>;

Three properties inherited from the existing SDK shape:

  • Per-agent DO instance — each email address resolves to one DO via address-based agent routing; same single-writer + embedded-state semantics as HTTP / WebSocket agent requests.
  • State persists across emailsthis.setState(...) is the DO embedded store; the inbox thread + DO state form a per-conversation agent memory substrate.
  • Async reply is first-class — the agent can kick off hours-long background work, then reply later (from a Queue handler, Workflow step, or scheduled task) — the asynchronous-reply property the inbox channel affords but a chat UI doesn't.

Canonical wiki reference implementation: Agentic Inbox (github.com/cloudflare/agentic-inbox).

Seen in

Last updated · 200 distilled / 1,178 read