Skip to content
Merged
118 changes: 118 additions & 0 deletions src/content/changelog/agents/2026-02-17-agents-sdk-v0.5.0.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
---
title: "Agents SDK v0.5.0: Protocol message control, retry utilities, data parts, and @cloudflare/ai-chat v0.1.0"
Comment thread
threepointone marked this conversation as resolved.
description: The Agents SDK v0.5.0 adds per-connection protocol message control for binary clients, built-in retry utilities with exponential backoff, data parts for typed JSON in chat messages, the first stable release of `@cloudflare/ai-chat`, and several developer experience improvements.
products:
- agents
- workers
date: 2026-02-17
---

import { TypeScriptExample } from "~/components";

The latest release of the [Agents SDK](https://github.com/cloudflare/agents) adds built-in retry utilities, per-connection protocol message control, and a fully rewritten `@cloudflare/ai-chat` with data parts, tool approval persistence, and zero breaking changes.

## Retry utilities

A new `this.retry()` method lets you retry any async operation with exponential backoff and jitter. You can pass an optional `shouldRetry` predicate to bail early on non-retryable errors.

<TypeScriptExample>

```ts
class MyAgent extends Agent {
async onRequest(request: Request) {
const result = await this.retry(() => fetch("https://example.com/api"), {
maxRetries: 3,
shouldRetry: (error) => error.status !== 404,
});
return result;
}
}
```

</TypeScriptExample>

Retry options are also available per-task on `queue()`, `schedule()`, `scheduleEvery()`, and `addMcpServer()`:

<TypeScriptExample>

```ts
// Per-task retry configuration, persisted in SQLite alongside the task
await this.schedule("sendReport", Date.now() + 60_000, {
retry: { maxRetries: 5 },
});

// Class-level retry defaults
class MyAgent extends Agent {
static options = {
retry: { maxRetries: 3 },
};
}
```

</TypeScriptExample>

Retry options are validated eagerly at enqueue/schedule time, and invalid values throw immediately. Internal retries have also been added for workflow operations (`terminateWorkflow`, `pauseWorkflow`, and others) with Durable Object-aware error detection.

## Per-connection protocol message control

Agents automatically send JSON text frames (identity, state, MCP server lists) to every WebSocket connection. You can now suppress these per-connection for clients that cannot handle them — binary-only devices, MQTT clients, or lightweight embedded systems.

<TypeScriptExample>

```ts
class MyAgent extends Agent {
shouldSendProtocolMessages(connection: Connection, ctx: ConnectionContext) {
// Suppress protocol messages for MQTT clients
const subprotocol = ctx.request.headers.get("Sec-WebSocket-Protocol");
return subprotocol !== "mqtt";
}
}
```

</TypeScriptExample>

Connections with protocol messages disabled still fully participate in RPC and regular messaging. Use `isConnectionProtocolEnabled(connection)` to check a connection's status at any time. The flag persists across Durable Object hibernation.

See [Protocol messages](/agents/api-reference/protocol-messages/) for full documentation.

## `@cloudflare/ai-chat` v0.1.0
Comment thread
threepointone marked this conversation as resolved.

The first stable release of `@cloudflare/ai-chat` ships alongside this release with a major refactor of `AIChatAgent` internals — new `ResumableStream` class, WebSocket `ChatTransport`, and simplified SSE parsing — with zero breaking changes. Existing code using `AIChatAgent` and `useAgentChat` works as-is.

Key new features:

- **Data parts** — Attach typed JSON blobs (`data-*`) to messages alongside text. Supports reconciliation (type+id updates in-place), append, and transient parts (ephemeral via `onData` callback). See [Data parts](/agents/api-reference/chat-agents/#data-parts).
- **Tool approval persistence** — The `needsApproval` approval UI now survives page refresh and DO hibernation. The streaming message is persisted to SQLite when a tool enters `approval-requested` state.
- **`maxPersistedMessages`** — Cap SQLite message storage with automatic oldest-message deletion.
- **`body` option on `useAgentChat`** — Send custom data with every request (static or dynamic).
- **Incremental persistence** — Hash-based cache to skip redundant SQL writes.
- **Row size guard** — Automatic two-pass compaction when messages approach the SQLite 2 MB limit.
- **`autoContinueAfterToolResult` defaults to `true`** — Client-side tool results and tool approvals now automatically trigger a server continuation, matching server-executed tool behavior. Set `autoContinueAfterToolResult: false` in `useAgentChat` to restore the previous behavior.

Notable bug fixes:

- Resolved stream resumption race conditions
- Resolved an issue where `setMessages` functional updater sent empty arrays
- Resolved an issue where client tool schemas were lost after DO hibernation
- Resolved `InvalidPromptError` after tool approval (`approval.id` was dropped)
- Resolved an issue where message metadata was not propagated on broadcast/resume paths
- Resolved an issue where `clearAll()` did not clear in-memory chunk buffers
- Resolved an issue where `reasoning-delta` silently dropped data when `reasoning-start` was missed during stream resumption

## Synchronous queue and schedule getters

`getQueue()`, `getQueues()`, `getSchedule()`, `dequeue()`, `dequeueAll()`, and `dequeueAllByCallback()` were unnecessarily `async` despite only performing synchronous SQL operations. They now return values directly instead of wrapping them in Promises. This is backward compatible — existing code using `await` on these methods will continue to work.

## Other improvements

- **Fix TypeScript "excessively deep" error** — A depth counter on `CanSerialize` and `IsSerializableParam` types bails out to `true` after 10 levels of recursion, preventing the "Type instantiation is excessively deep" error with deeply nested types like AI SDK `CoreMessage[]`.
- **POST SSE keepalive** — The POST SSE handler now sends `event: ping` every 30 seconds to keep the connection alive, matching the existing GET SSE handler behavior. This prevents POST response streams from being silently dropped by proxies during long-running tool calls.
- **Widened peer dependency ranges** — Peer dependency ranges across packages have been widened to prevent cascading major bumps during 0.x minor releases. `@cloudflare/ai-chat` and `@cloudflare/codemode` are now marked as optional peer dependencies.

### Upgrade

To update to the latest version:

```sh
npm i agents@latest @cloudflare/ai-chat@latest
```
Loading