Patch Changes
-
#1353
f834c81Thanks @threepointone! - AlignAIChatAgentgenerics and types with@cloudflare/think, plus a reference example for multi-session chat built on the sub-agent routing primitive.- New
Propsgeneric:AIChatAgent<Env, State, Props>extendingAgent<Env, State, Props>. Subclasses now get properly typedthis.ctx.props. - Shared lifecycle types:
ChatResponseResult,ChatRecoveryContext,ChatRecoveryOptions,SaveMessagesResult, andMessageConcurrencynow live inagents/chatand are re-exported by both@cloudflare/ai-chatand@cloudflare/think. No behavior change; one place to edit when shapes evolve. ChatMessagestays the public message type: the package continues to exportChatMessage, and the public API/docs keep using that name.messagesstays a public field:messages: ChatMessage[].
The full stance (AIChatAgent is first-class, production-ready, and continuing to get features; shared infrastructure should land in
agents/chatwhere both classes benefit) is captured indesign/rfc-ai-chat-maintenance.md.A new example,
examples/multi-ai-chat, demonstrates the multi-session pattern end-to-end on top of the sub-agent routing primitive: anInboxAgent owns the chat list + shared memory; each chat is anAIChatAgentfacet (this.subAgent(Chat, id)). The client addresses the active chat viauseAgent({ sub: [{ agent: "Chat", name: chatId }] })— no separate DO binding, no custom routing on the server.Inbox.onBeforeSubAgentgates withhasSubAgentas a strict registry, andChatreaches its parent viathis.parentAgent(Inbox). - New
-
#1348
0693a5fThanks @threepointone! - Bump dependencies. -
#1362
d901804Thanks @threepointone! - fix(mcp): capture tool title in MCP client -
#1355
df2023fThanks @threepointone! - External addressability for sub-agents.Clients can now reach a facet (a child DO created by
Agent#subAgent()) directly via a nested URL:/agents/{parent-class}/{parent-name}/sub/{child-class}/{child-name}[/...]New public APIs (all
@experimental):routeSubAgentRequest(req, parent, options?)— sub-agent analog ofrouteAgentRequest. For custom-routing setups where the outer URL doesn't match the default/agents/...shape.getSubAgentByName(parent, Cls, name)— sub-agent analog ofgetAgentByName. Returns a typed Proxy that round-trips typed RPC calls through the parent. RPC-only (no.fetch()); userouteSubAgentRequestfor external HTTP/WS.parseSubAgentPath(url, options?)— public URL parser used internally by the routers.SUB_PREFIX— the"sub"separator constant (not configurable; exposed for symbolic URL building).
New public on
Agent:onBeforeSubAgent(req, { className, name })— overridable middleware hook, mirrorsonBeforeConnect/onBeforeRequest. ReturnsRequest | Response | voidfor short-circuit responses, request mutation, or passthrough. Default: void.parentPath/selfPath— root-first{ className, name }ancestor chains, populated at facet init time. Inductive across recursive nesting.hasSubAgent(ClsOrName, name)/listSubAgents(ClsOrName?)— parent-side introspection backed by an auto-maintained SQLite registry written bysubAgent()/deleteSubAgent(). Both accept either the class constructor or a CamelCase class name string.
New public on
useAgent(React):sub?: Array<{ agent, name }>— flat root-first chain addressing a descendant facet. The hook's.agent/.namereport the leaf identity;.pathexposes the full chain.
Breaking changes: none.
routeAgentRequestbehavior is unchanged when URLs don't contain/sub/.onBeforeSubAgentdefaults to permissive (forward unchanged).useAgentwithoutsubis unchanged.subAgent()/deleteSubAgent()gain registry side effects but preserve return types and failure modes. The_cf_initAsFacetsignature gained an optionalparentPathparameter.deleteSubAgent()is now idempotent — calling it for a never-spawned or already-deleted child no longer throws. Sub-agent class names equal to"Sub"are rejected (the/sub/URL separator is reserved).See
design/rfc-sub-agent-routing.mdfor the full rationale, design decisions, and edge cases. The spike atpackages/agents/src/tests/spike-sub-agent-routing.test.tsdocuments the three candidate approaches considered for cross-DO stub passthrough and why the per-call bridge won. -
#1346
a78bb2aThanks @threepointone! - Remove unuseddependencies,devDependencies, andpeerDependenciesfrom theagentspackage.dependencies: dropjson-schema,json-schema-to-typescript, andpicomatch. None are imported by the package;picomatchwas already pulled in transitively via@rolldown/plugin-babel.devDependencies: drop@ai-sdk/openai(only referenced in a commented-out line) and@cloudflare/workers-oauth-provider(not referenced anywhere).peerDependencies/peerDependenciesMeta: drop@ai-sdk/reactandviem.@ai-sdk/reactis already a peer of@cloudflare/ai-chat(itself an optional peer here), andviemis a regular dependency of@x402/evm, so both are supplied transitively when the relevant optional features are used.