Agents SDK v0.5.0: Retry utilities, protocol message control, and ai-chat v0.1.0
The Agents SDK now includes built-in retry utilities with exponential backoff, per-connection protocol message control for embedded systems, and a fully rewritten ai-chat package with data parts, tool approval persistence, and zero breaking changes. This release also improves performance with synchronous queue/schedule getters and fixes critical stream resumption race conditions.
The latest release of the Agents SDK ↗ 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.
class MyAgent extends Agent {
async onRequest(request) {
const data = await this.retry(() => callUnreliableService(), {
maxAttempts: 4,
shouldRetry: (err) => !(err instanceof PermanentError),
});
return Response.json(data);
}
}class MyAgent extends Agent {
async onRequest(request: Request) {
const data = await this.retry(() => callUnreliableService(), {
maxAttempts: 4,
shouldRetry: (err) => !(err instanceof PermanentError),
});
return Response.json(data);
}
}
Retry options are also available per-task on queue(), schedule(), scheduleEvery(), and addMcpServer():
// Per-task retry configuration, persisted in SQLite alongside the task
await this.schedule(
Date.now() + 60_000,
"sendReport",
{ userId: "abc" },
{
retry: { maxAttempts: 5 },
},
);
// Class-level retry defaults
class MyAgent extends Agent {
static options = {
retry: { maxAttempts: 3 },
};
}// Per-task retry configuration, persisted in SQLite alongside the task
await this.schedule(Date.now() + 60_000, "sendReport", { userId: "abc" }, {
retry: { maxAttempts: 5 },
});
// Class-level retry defaults
class MyAgent extends Agent {
static options = {
retry: { maxAttempts: 3 },
};
}
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.
class MyAgent extends Agent {
shouldSendProtocolMessages(connection, ctx) {
// Suppress protocol messages for MQTT clients
const subprotocol = ctx.request.headers.get("Sec-WebSocket-Protocol");
return subprotocol !== "mqtt";
}
}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";
}
}
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 for full documentation.
@cloudflare/ai-chat v0.1.0
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 viaonDatacallback). See Data parts. - Tool approval persistence — The
needsApprovalapproval UI now survives page refresh and DO hibernation. The streaming message is persisted to SQLite when a tool entersapproval-requestedstate. maxPersistedMessages— Cap SQLite message storage with automatic oldest-message deletion.bodyoption onuseAgentChat— 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.
autoContinueAfterToolResultdefaults totrue— Client-side tool results and tool approvals now automatically trigger a server continuation, matching server-executed tool behavior. SetautoContinueAfterToolResult: falseinuseAgentChatto restore the previous behavior.
Notable bug fixes:
- Resolved stream resumption race conditions
- Resolved an issue where
setMessagesfunctional updater sent empty arrays - Resolved an issue where client tool schemas were lost after DO hibernation
- Resolved
InvalidPromptErrorafter tool approval (approval.idwas 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-deltasilently dropped data whenreasoning-startwas 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
CanSerializeandIsSerializableParamtypes bails out totrueafter 10 levels of recursion, preventing the "Type instantiation is excessively deep" error with deeply nested types like AI SDKCoreMessage[]. - POST SSE keepalive — The POST SSE handler now sends
event: pingevery 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-chatand@cloudflare/codemodeare now marked as optional peer dependencies.
Upgrade
To update to the latest version:
npm i agents@latest @cloudflare/ai-chat@latestSource: original entry ↗
More from Cloudflare
Follow Cloudflare to get its new changes in your feed and email digest.
Cloudflare One Client for macOS 2026.8.2100.0
GA release for macOS Cloudflare One Client with improved split tunnel handling that no longer briefly blocks traffic during reconnects, support for non-RFC 1918 local IPv4 networks, faster connects with lower memory use, and numerous reliability fixes across DNS, reauthentication, and client stability.
Cloudflare One Client for Windows 2026.8.2100.0
This GA release improves split tunnel reliability, adds support for non-RFC 1918 local networks, optimizes connection performance with faster reconnections and lower memory usage, and includes numerous bug fixes for DNS, registration, and network handling. The client now features a service recovery mechanism that automatically restarts on system unlock and better handles large hosts files without blocking traffic.
Cloudflare One Client for Linux 2026.8.2100.0
New GA release for Linux with improved split tunnel handling that no longer briefly blocks traffic during reconnects, support for non-RFC 1918 local IPv4 networks, faster tunnel reconnections, and lower memory usage. Includes numerous stability and reliability fixes for DNS, reconnection behavior, and crash issues.