agents@0.21.0
cloudflare/agentsagents@0.21.0Aug 18, 2026by github-actions[bot]
AI Summary
A major update that exposes framework-neutral transports, supports flexible AI SDK schemas, and introduces Kitesurf support for Browser Tools while optimizing request streaming.
Key Highlights
- Expose `WebSocketChatTransport` from framework-neutral entry point
- Accept AI SDK flexible schemas (Valibot) in `agentTool`
- Add connection-scoped Kitesurf support to Browser Tools
- Stream request bodies to sub-agents to reduce memory usage
Breaking Changes
- Large base64 values outside canonical shape are now redacted
- Rename `response_format.schema` to `response_format.json_schema` for Browser Run
- Backpressure changes: child that doesn't read body cancels upload
New Features
- Framework-neutral WebSocket transport
- Flexible schema support
- Kitesurf integration
- Request streaming optimization
Full Release Notes
### Minor Changes
- [#2052](https://github.com/cloudflare/agents/pull/2052) [`f9d71d6`](https://github.com/cloudflare/agents/commit/f9d71d65ffb31cb45c8594b5f3bd4eeb4a8560d1) Thanks [@cjol](https://github.com/cjol)! - Expose `WebSocketChatTransport` and its connection types from the framework-neutral `agents/chat/transport` entry point. React peers are now optional for framework-neutral clients and servers.
Existing users of `agents/chat/react` or `@cloudflare/ai-chat/react` must continue to declare compatible `react` and `@ai-sdk/react` dependencies explicitly.
- [#2091](https://github.com/cloudflare/agents/pull/2091) [`4d2084c`](https://github.com/cloudflare/agents/commit/4d2084c1580395aac7df1f622d5a1f7a8a40beed) Thanks [@cjol](https://github.com/cjol)! - Accept AI SDK flexible schemas in `agentTool`, including Valibot adapters, while preserving schema-driven input inference and structured output validation. Zod is no longer a peer requirement of `@cloudflare/ai-chat`.
Existing custom schemas that no longer type-check as AI SDK `FlexibleSchema` must use the schema library's AI SDK adapter or wrap raw JSON Schema with `jsonSchema()`. Validation-only Standard Schema implementations are insufficient because tool inputs must expose JSON Schema to the model.
- [#2098](https://github.com/cloudflare/agents/pull/2098) [`fe82e05`](https://github.com/cloudflare/agents/commit/fe82e0524b7ffce9d75d3f55a8b48baeae2bd58b) Thanks [@cjol](https://github.com/cjol)! - Add connection-scoped Kitesurf support to Browser Tools through the `browser: "kitesurf"` session option. Unsupported durable session, Live View, recording, pause/resume, and Kitesurf-backed Quick Action surfaces remain unavailable.
Existing Browser Tools users should note:
- Large base64 values returned outside the canonical `{ type: "browser_screenshot", mediaType, data }` shape are now redacted. Return screenshots in that shape or store binary output elsewhere.
- TanStack browser tools have one output channel, so screenshot output is reduced to the compact model-facing summary rather than returning raw base64 data.
- [#1948](https://github.com/cloudflare/agents/pull/1948) [`aed6d8f`](https://github.com/cloudflare/agents/commit/aed6d8f8506087d405613e768454e4f0c0ae7ea1) Thanks [@ericclemmons](https://github.com/ericclemmons)! - Pass Workflow [`retention`](https://developers.cloudflare.com/workflows/build/workers-api/#workflowinstancecreateoptions) through `Agent.runWorkflow()`.
### Patch Changes
- [#2037](https://github.com/cloudflare/agents/pull/2037) [`1bca2a6`](https://github.com/cloudflare/agents/commit/1bca2a62435dee1a75914c8840d028b832913d0f) Thanks [@cjol](https://github.com/cjol)! - Add `buildAgentPath()` and `buildAgentUrl()` for constructing canonical root-first Agent and sub-agent addresses for external HTTP requests, WebSocket connections, callbacks, and webhooks. React sub-agent connections now share the same descendant path encoder.
- [#2051](https://github.com/cloudflare/agents/pull/2051) [`b9343a0`](https://github.com/cloudflare/agents/commit/b9343a0dadb5a49e998eb7b57ecbbbcc38308d6e) Thanks [@AntoniTok](https://github.com/AntoniTok)! - Stream forwarded request bodies into sub-agents instead of buffering them in the parent Durable Object.
`Agent._cf_forwardToFacet` and `routeSubAgentRequest` both did `forwardInit.body = await req.arrayBuffer()` before dispatching to a child facet, materialising the entire request body in the parent's isolate. Two consequences:
- The read sat **in front of** application-level validation. `Agent.fetch` returns before `onRequest` whenever the path matches `/sub/{class}/{name}`, so an app that carefully bounded request bodies in `onRequest` still had an unbounded read ahead of it — and no way to bound it itself.
- The cost was **per hop**. A nested `/sub/.../sub/...` address re-materialised the same bytes at every level.
Both call sites now pass `req.body` through as a stream. Measured on `wrangler dev --local` with a handler that never reads the body, peak RSS across the `workerd` processes for a single POST:
| Request body | facet route, before | facet route, after | canonical route (control) |
| ------------ | ------------------- | ------------------ | ------------------------- |
| 16 MB | +75 MB | +4 MB | +2 MB |
| 64 MB | +268 MB | +4 MB | +2 MB |
| 128 MB | +546 MB | +4 MB | +2 MB |
This restores the behaviour from before [#1443](https://github.com/cloudflare/agents/issues/1443), which switched to an explicit `RequestInit` in order to set a header on WebSocket upgrades and re-attached the body with `arrayBuffer()` as a side effect. The `Upgrade` header handling from that fix is unchanged.
One behavioural note: backpressure now reaches the client. A child that returns without reading the body will cause the remainder of the upload to be cancelled, where previously the parent drained it in full. Existing handlers that require the complete upload must consume or stream `request.body` before returning.
- [#2034](https://github.com/cloudflare/agents/pull/2034) [`efcb316`](https://github.com/cloudflare/agents/commit/efcb3167b72bcab2bab6e49036f6cee74d35b187) Thanks [@cjol](https://github.com/cjol)! - Send Browser Run extraction schemas under `response_format.json_schema`, matching the Quick Actions `/json` contract.
Direct `browserExtract()` and `runQuickAction()` callers must rename `response_format.schema` to `response_format.json_schema`. The model-facing `browser_extract` tool still accepts its schema in the top-level `schema` field.
- [#2023](https://github.com/cloudflare/agents/pull/2023) [`2b2b598`](https://github.com/cloudflare/agents/commit/2b2b5980e1945cf55f5a11626bc395e7c460516f) Thanks [@threepointone](https://github.com/threepointone)! - Treat `useAgentChat` observer error frames as terminal responses.
Plain-text error bodies are no longer parsed as stream chunks or merged into an empty assistant message. Error frames now clear observer streaming, replay, recovery, and tool-continuation state even when they omit `done`, matching the transport-owned stream behavior.
Existing observer UIs that displayed error bodies as assistant messages must move those diagnostics to a dedicated error surface.
- [#1996](https://github.com/cloudflare/agents/pull/1996) [`753a674`](https://github.com/cloudflare/agents/commit/753a6748c1d20e56a300bedab6174e43acb33a79) Thanks [@mattzcarey](https://github.com/mattzcarey)! - Update PartyServer and the Cloudflare Workers development toolchain for `@cloudflare/workers-types` v5 compatibility. New Think projects now use Workers Types v5 with matching Wrangler and Vite plugin versions.
- [#1994](https://github.com/cloudflare/agents/pull/1994) [`6e77f62`](https://github.com/cloudflare/agents/commit/6e77f62e368279a5bbd11ee2c4b2f489693d0401) Thanks [@mattzcarey](https://github.com/mattzcarey)! - Use `wrapAISDK()` as the single AI SDK v6 and v7 tracing integration, removing the separate `createAISDKTelemetry()` callback adapter that could not preserve the `invoke_agent` parent hierarchy. Mark asynchronously decided AI SDK v7 top-level approval spans when they outlive their invocation.
Existing `createAISDKTelemetry()` users must:
- Remove it from `registerTelemetry()` and per-call telemetry integrations.
- Wrap the AI SDK namespace and call the wrapped functions instead:
```ts
import * as ai from "ai";
import { wrapAISDK } from "agents/observability/ai";
const tracedAI = wrapAISDK(ai, {
storeMessages: true,
storeTools: true,
});
await tracedAI.generateText(/* ... */);
```
- Update telemetry queries that use the removed callback-only `cloudflare.agents.call.id` or `cloudflare.agents.tool_context.*` attributes.
- [#2035](https://github.com/cloudflare/agents/pull/2035) [`5d66723`](https://github.com/cloudflare/agents/commit/5d66723c8c0cacb4d8808d6399074b80020786ef) Thanks [@cjol](https://github.com/cjol)! - Validate BrowserConnector tool arguments before execution and reject JSON-stringified Browser Run extraction schemas with an actionable error.
Existing callers that pass values outside the documented schemas must correct them before execution:
- Pass extraction schemas as JSON objects, not JSON strings.
- Pass the string returned in `attachToTarget().sessionId` to `cdp.send`, not the complete attachment result.
- [#2049](https://github.com/cloudflare/agents/pull/2049) [`ce0e608`](https://github.com/cloudflare/agents/commit/ce0e608675e41794b02178dce0fb13bb62530aa8) Thanks [@cjol](https://github.com/cjol)! - Preserve spacing between streamed text segments separated by tool calls. Think messenger delivery and Voice now share the same boundary-aware text joining logic from `agents/chat`.
Existing users must:
- Replace imports of `textDeltaFromStreamChunk()` from `@cloudflare/think/messengers` with `TextStreamCallback`, passing it the complete structured stream events.
- Upgrade to `agents@0.21.0` when installing `@cloudflare/think@0.16.0` or `@cloudflare/voice@0.3.6`; both now require `agents >=0.20.2`.
- Update exact-text expectations if they relied on segments around tool calls being concatenated without a space.