Skip to content

Version Packages#1347

Merged
threepointone merged 1 commit intomainfrom
changeset-release/main
Apr 23, 2026
Merged

Version Packages#1347
threepointone merged 1 commit intomainfrom
changeset-release/main

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot commented Apr 20, 2026

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

@cloudflare/ai-chat@0.5.0

Minor Changes

  • #1353 f834c81 Thanks @threepointone! - Align AIChatAgent generics and types with @cloudflare/think, plus a reference example for multi-session chat built on the sub-agent routing primitive.

    • New Props generic: AIChatAgent<Env, State, Props> extending Agent<Env, State, Props>. Subclasses now get properly typed this.ctx.props.
    • Shared lifecycle types: ChatResponseResult, ChatRecoveryContext, ChatRecoveryOptions, SaveMessagesResult, and MessageConcurrency now live in agents/chat and are re-exported by both @cloudflare/ai-chat and @cloudflare/think. No behavior change; one place to edit when shapes evolve.
    • ChatMessage stays the public message type: the package continues to export ChatMessage, and the public API/docs keep using that name.
    • messages stays 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/chat where both classes benefit) is captured in design/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: an Inbox Agent owns the chat list + shared memory; each chat is an AIChatAgent facet (this.subAgent(Chat, id)). The client addresses the active chat via useAgent({ sub: [{ agent: "Chat", name: chatId }] }) — no separate DO binding, no custom routing on the server. Inbox.onBeforeSubAgent gates with hasSubAgent as a strict registry, and Chat reaches its parent via this.parentAgent(Inbox).

Patch Changes

  • #1358 ea229b1 Thanks @threepointone! - Fix useAgentChat() crashing on first render when agent.getHttpUrl() returns an empty string. This happened in setups where the WebSocket handshake hadn't completed by the time React rendered — most commonly when the agent is reached through a proxy or custom-routed worker — because @cloudflare/ai-chat unconditionally called new URL(agent.getHttpUrl()). See #1356.

    useAgentChat() now treats a missing HTTP URL as "not ready yet":

    • The built-in /get-messages fetch is deferred until the URL is known, and applied exactly once when it resolves (empty chats only — existing messages are never overwritten).
    • Custom getInitialMessages callbacks continue to run and are passed url: undefined so they can load from other sources if they don't need the socket URL. GetInitialMessagesOptions.url is now string | undefined; callers that previously typed url: string should widen to url?: string.
    • Initial messages are cached by agent identity (class + name) rather than by URL + identity, so the URL-arrival transition no longer invalidates the cache, re-invokes the loader, or re-triggers Suspense once the chat has already been populated.
    • The underlying useChat instance keeps a stable id across the URL-arrival transition, so in-flight stream resume and chat state are preserved.

    No API or behavior changes for apps where the URL was already available synchronously on first render.

@cloudflare/think@0.4.0

Minor Changes

  • #1350 3a1140f Thanks @threepointone! - Align Think generics with Agent / AIChatAgent.

    Think is now Think<Env, State, Props> and extends Agent<Env, State, Props>, so subclasses get properly typed this.state, this.setState(), initialState, and this.ctx.props. The previous Config class generic is removed.

    configure() and getConfig() remain, but the config type is now specified at the call site via a method-level generic:

    // Before
    export class MyAgent extends Think<Env, MyConfig> {
      getModel() {
        const tier = this.getConfig()?.modelTier ?? "fast";
        // ...
      }
    }
    
    // After
    export class MyAgent extends Think<Env> {
      getModel() {
        const tier = this.getConfig<MyConfig>()?.modelTier ?? "fast";
        // ...
      }
    }

    This is a breaking change for anyone using the second type parameter of Think. Update the class declaration and any direct configure(...) / getConfig() call sites that relied on the class-level Config type.

agents@0.11.5

Patch Changes

  • #1353 f834c81 Thanks @threepointone! - Align AIChatAgent generics and types with @cloudflare/think, plus a reference example for multi-session chat built on the sub-agent routing primitive.

    • New Props generic: AIChatAgent<Env, State, Props> extending Agent<Env, State, Props>. Subclasses now get properly typed this.ctx.props.
    • Shared lifecycle types: ChatResponseResult, ChatRecoveryContext, ChatRecoveryOptions, SaveMessagesResult, and MessageConcurrency now live in agents/chat and are re-exported by both @cloudflare/ai-chat and @cloudflare/think. No behavior change; one place to edit when shapes evolve.
    • ChatMessage stays the public message type: the package continues to export ChatMessage, and the public API/docs keep using that name.
    • messages stays 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/chat where both classes benefit) is captured in design/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: an Inbox Agent owns the chat list + shared memory; each chat is an AIChatAgent facet (this.subAgent(Chat, id)). The client addresses the active chat via useAgent({ sub: [{ agent: "Chat", name: chatId }] }) — no separate DO binding, no custom routing on the server. Inbox.onBeforeSubAgent gates with hasSubAgent as a strict registry, and Chat reaches its parent via this.parentAgent(Inbox).

  • #1348 0693a5f Thanks @threepointone! - Bump dependencies.

  • #1362 d901804 Thanks @threepointone! - fix(mcp): capture tool title in MCP client

  • #1355 df2023f Thanks @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 of routeAgentRequest. For custom-routing setups where the outer URL doesn't match the default /agents/... shape.
    • getSubAgentByName(parent, Cls, name) — sub-agent analog of getAgentByName. Returns a typed Proxy that round-trips typed RPC calls through the parent. RPC-only (no .fetch()); use routeSubAgentRequest for 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, mirrors onBeforeConnect / onBeforeRequest. Returns Request | Response | void for 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 by subAgent() / 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 / .name report the leaf identity; .path exposes the full chain.

    Breaking changes: none. routeAgentRequest behavior is unchanged when URLs don't contain /sub/. onBeforeSubAgent defaults to permissive (forward unchanged). useAgent without sub is unchanged. subAgent() / deleteSubAgent() gain registry side effects but preserve return types and failure modes. The _cf_initAsFacet signature gained an optional parentPath parameter. 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.md for the full rationale, design decisions, and edge cases. The spike at packages/agents/src/tests/spike-sub-agent-routing.test.ts documents the three candidate approaches considered for cross-DO stub passthrough and why the per-call bridge won.

  • #1346 a78bb2a Thanks @threepointone! - Remove unused dependencies, devDependencies, and peerDependencies from the agents package.

    • dependencies: drop json-schema, json-schema-to-typescript, and picomatch. None are imported by the package; picomatch was 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/react and viem. @ai-sdk/react is already a peer of @cloudflare/ai-chat (itself an optional peer here), and viem is a regular dependency of @x402/evm, so both are supplied transitively when the relevant optional features are used.

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Open in Devin Review

@github-actions github-actions Bot force-pushed the changeset-release/main branch 6 times, most recently from 48ce786 to 0ed1522 Compare April 23, 2026 02:58
@github-actions github-actions Bot force-pushed the changeset-release/main branch from 0ed1522 to 69e1062 Compare April 23, 2026 03:20
@threepointone threepointone merged commit f07411b into main Apr 23, 2026
@threepointone threepointone deleted the changeset-release/main branch April 23, 2026 03:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant