Readable Agent State
The Agents SDK now exposes agent state as a readable property on both useAgent (React) and AgentClient (vanilla JS), eliminating the need for manual state tracking through callbacks. Previously, developers had to manage state separately with useState and onStateUpdate handlers.
In React, agent.state is reactive—the component automatically re-renders when state changes from the server or client-side setState() calls. In vanilla JavaScript, client.state provides direct access to the current agent state. State begins as undefined and populates when the server sends initial state on connect or when setState() is called.
Idempotent Scheduling
schedule() now supports an idempotent option that deduplicates schedules by (type, callback, payload), preventing duplicate rows from accumulating on Durable Object restarts. Cron schedules are idempotent by default—calling schedule("0 * * * *", "tick") multiple times returns the existing schedule instead of creating new ones.
Delayed and date-scheduled types can opt into idempotency with { idempotent: true }. Two new warnings help catch common mistakes:
- Calling
schedule()inonStart()without{ idempotent: true }emits a console warning with guidance - Processing 10+ stale one-shot rows for the same callback triggers a warning and diagnostics event
Full TypeScript Support for AgentClient
AgentClient now accepts an optional type parameter for complete type inference on RPC calls, matching the experience already available in useAgent. Method names autocomplete, and argument and return types are fully inferred. The new stub proxy enables direct RPC-style calls (e.g., await client.stub.getValue()).
State is automatically inferred from the agent type, so onStateUpdate callbacks are also fully typed. Existing untyped usage continues to work without changes.
Additional Improvements
- Zod 4 migration:
agents,@cloudflare/ai-chat, and@cloudflare/codemodenow require Zod 4.0.0+; Zod v3 is no longer supported @cloudflare/ai-chatfixes: Turn serialization now queues work to prevent concurrent streams, clicking stop during streams no longer duplicates messages, and tool call cleanup prevents orphaned client IDs in persistent storagekeepAlive()stabilization:keepAlive()andkeepAliveWhile()are no longer experimental; the implementation now uses lightweight in-memory ref counting instead of schedule rows- TanStack AI integration: New
@cloudflare/codemode/tanstack-aientry point adds support for TanStack AI'schat()function