releases.shpreview

Think no longer prunes tool results by default; chat recovery improved

v0.12.4

3 features2 enhancements5 fixesThis release3 featuresNew capabilities2 enhancementsImprovements to existing features5 fixesBug fixesAI-tallied from the release notes
From the original release noteView original ↗

The latest release of the Agents SDK ↗ brings more reliable chat recovery, fixes Agent state synchronization during reconnects, adds durable submissions for Think, exposes routing retry configuration, and adds connection control for Voice agents.

Chat recovery improvements

@cloudflare/ai-chat now keeps server turns running when a browser or client stream is interrupted. This is useful for long-running AI responses where users refresh the page, close a tab, or temporarily lose connection. Calling stop() still cancels the server turn.

Set cancelOnClientAbort: true if browser or client aborts should also cancel the server turn:

<span class="line"><span class="nb-shiki-1itgoe">const</span><span class="nb-shiki-dzsirb"> chat</span><span class="nb-shiki-1itgoe"> =</span><span class="nb-shiki-1t8gfj"> useAgentChat</span><span class="nb-shiki-140thh">({</span></span>
<span class="line"><span class="nb-shiki-140thh">	agent: </span><span class="nb-shiki-mdbnqw">"assistant"</span><span class="nb-shiki-140thh">,</span></span>
<span class="line"><span class="nb-shiki-140thh">	name: </span><span class="nb-shiki-mdbnqw">"user-123"</span><span class="nb-shiki-140thh">,</span></span>
<span class="line"><span class="nb-shiki-140thh">	cancelOnClientAbort: </span><span class="nb-shiki-dzsirb">true</span><span class="nb-shiki-140thh">,</span></span>
<span class="line"><span class="nb-shiki-140thh">});</span></span>
<span class="line"><span class="nb-shiki-1itgoe">const</span><span class="nb-shiki-dzsirb"> chat</span><span class="nb-shiki-1itgoe"> =</span><span class="nb-shiki-1t8gfj"> useAgentChat</span><span class="nb-shiki-140thh">({</span></span>
<span class="line"><span class="nb-shiki-140thh">	agent: </span><span class="nb-shiki-mdbnqw">"assistant"</span><span class="nb-shiki-140thh">,</span></span>
<span class="line"><span class="nb-shiki-140thh">	name: </span><span class="nb-shiki-mdbnqw">"user-123"</span><span class="nb-shiki-140thh">,</span></span>
<span class="line"><span class="nb-shiki-140thh">	cancelOnClientAbort: </span><span class="nb-shiki-dzsirb">true</span><span class="nb-shiki-140thh">,</span></span>
<span class="line"><span class="nb-shiki-140thh">});</span></span>

Notable bug fixes:

  • Chat stream resume negotiation no longer throws when replay races with a closed WebSocket connection.
  • Recovered chat continuations no longer leave useAgentChat stuck in a streaming state when the original socket disconnects before a terminal response.
  • Approval auto-continuation preserves reasoning parts and persists continuation reasoning in the final message.
  • isServerStreaming now resets correctly when a resumed stream moves from the fallback observer path to a transport-owned stream.
Agent state and routing fixes

agents@0.12.4 prevents duplicate initial state frames during WebSocket connection setup. This avoids stale initial state messages overwriting state updates already sent by the client.

Agent recovery is also more reliable when tool calls span a Durable Object restart. Recovery now defers user finish hooks until after agent startup and isolates hook failures, so one failed hook does not block other recovered runs from finalizing.

getAgentByName() now supports routingRetry for transient Durable Object routing failures:

<span class="line"><span class="nb-shiki-1itgoe">import</span><span class="nb-shiki-140thh"> { getAgentByName } </span><span class="nb-shiki-1itgoe">from</span><span class="nb-shiki-mdbnqw"> "agents"</span><span class="nb-shiki-140thh">;</span></span>
<span class="line"></span>
<span class="line"><span class="nb-shiki-1itgoe">const</span><span class="nb-shiki-dzsirb"> agent</span><span class="nb-shiki-1itgoe"> =</span><span class="nb-shiki-1itgoe"> await</span><span class="nb-shiki-1t8gfj"> getAgentByName</span><span class="nb-shiki-140thh">(env.AssistantAgent, </span><span class="nb-shiki-mdbnqw">"user-123"</span><span class="nb-shiki-140thh">, {</span></span>
<span class="line"><span class="nb-shiki-140thh">	routingRetry: {</span></span>
<span class="line"><span class="nb-shiki-140thh">		maxAttempts: </span><span class="nb-shiki-dzsirb">3</span><span class="nb-shiki-140thh">,</span></span>
<span class="line"><span class="nb-shiki-140thh">	},</span></span>
<span class="line"><span class="nb-shiki-140thh">});</span></span>
<span class="line"><span class="nb-shiki-1itgoe">import</span><span class="nb-shiki-140thh"> { getAgentByName } </span><span class="nb-shiki-1itgoe">from</span><span class="nb-shiki-mdbnqw"> "agents"</span><span class="nb-shiki-140thh">;</span></span>
<span class="line"></span>
<span class="line"><span class="nb-shiki-1itgoe">const</span><span class="nb-shiki-dzsirb"> agent</span><span class="nb-shiki-1itgoe"> =</span><span class="nb-shiki-1itgoe"> await</span><span class="nb-shiki-1t8gfj"> getAgentByName</span><span class="nb-shiki-140thh">(env.AssistantAgent, </span><span class="nb-shiki-mdbnqw">"user-123"</span><span class="nb-shiki-140thh">, {</span></span>
<span class="line"><span class="nb-shiki-140thh">	routingRetry: {</span></span>
<span class="line"><span class="nb-shiki-140thh">		maxAttempts: </span><span class="nb-shiki-dzsirb">3</span><span class="nb-shiki-140thh">,</span></span>
<span class="line"><span class="nb-shiki-140thh">	},</span></span>
<span class="line"><span class="nb-shiki-140thh">});</span></span>
Durable Think submissions

@cloudflare/think now supports durable programmatic submissions. submitMessages() provides durable acceptance, idempotent retries, status inspection, cancellation, and cleanup for server-driven turns that should continue after the caller returns.

Think.chat() RPC turns now run inside chat recovery fibers and persist their stream chunks. Interrupted sub-agent turns can recover partial output instead of starting over.

ChatOptions.tools has been removed from the TypeScript API. Define durable tools on the child agent or use agent tools for orchestration. Runtime options.tools values passed by legacy callers are ignored with a warning.

Think message pruning behavior change

@cloudflare/think no longer applies pruneMessages({ toolCalls: "before-last-2-messages" }) to model context by default. The previous default could strip client-side tool results from longer multi-turn flows.

truncateOlderMessages still runs as before, so context cost remains bounded. Subclasses that relied on the old aggressive pruning can opt back in from beforeTurn:

<span class="line"><span class="nb-shiki-1itgoe">import</span><span class="nb-shiki-140thh"> { Think } </span><span class="nb-shiki-1itgoe">from</span><span class="nb-shiki-mdbnqw"> "@cloudflare/think"</span><span class="nb-shiki-140thh">;</span></span>
<span class="line"><span class="nb-shiki-1itgoe">import</span><span class="nb-shiki-140thh"> { pruneMessages } </span><span class="nb-shiki-1itgoe">from</span><span class="nb-shiki-mdbnqw"> "ai"</span><span class="nb-shiki-140thh">;</span></span>
<span class="line"></span>
<span class="line"><span class="nb-shiki-1itgoe">export</span><span class="nb-shiki-1itgoe"> class</span><span class="nb-shiki-1t8gfj"> MyAgent</span><span class="nb-shiki-1itgoe"> extends</span><span class="nb-shiki-1t8gfj"> Think</span><span class="nb-shiki-140thh"> {</span></span>
<span class="line"><span class="nb-shiki-1t8gfj">	beforeTurn</span><span class="nb-shiki-140thh">(</span><span class="nb-shiki-1jdh33">ctx</span><span class="nb-shiki-140thh">) {</span></span>
<span class="line"><span class="nb-shiki-1itgoe">		return</span><span class="nb-shiki-140thh"> {</span></span>
<span class="line"><span class="nb-shiki-140thh">			messages: </span><span class="nb-shiki-1t8gfj">pruneMessages</span><span class="nb-shiki-140thh">({</span></span>
<span class="line"><span class="nb-shiki-140thh">				messages: ctx.messages,</span></span>
<span class="line"><span class="nb-shiki-140thh">				toolCalls: </span><span class="nb-shiki-mdbnqw">"before-last-2-messages"</span><span class="nb-shiki-140thh">,</span></span>
<span class="line"><span class="nb-shiki-140thh">			}),</span></span>
<span class="line"><span class="nb-shiki-140thh">		};</span></span>
<span class="line"><span class="nb-shiki-140thh">	}</span></span>
<span class="line"><span class="nb-shiki-140thh">}</span></span>
<span class="line"><span class="nb-shiki-1itgoe">import</span><span class="nb-shiki-140thh"> { Think } </span><span class="nb-shiki-1itgoe">from</span><span class="nb-shiki-mdbnqw"> "@cloudflare/think"</span><span class="nb-shiki-140thh">;</span></span>
<span class="line"><span class="nb-shiki-1itgoe">import</span><span class="nb-shiki-140thh"> { pruneMessages } </span><span class="nb-shiki-1itgoe">from</span><span class="nb-shiki-mdbnqw"> "ai"</span><span class="nb-shiki-140thh">;</span></span>
<span class="line"></span>
<span class="line"><span class="nb-shiki-1itgoe">export</span><span class="nb-shiki-1itgoe"> class</span><span class="nb-shiki-1t8gfj"> MyAgent</span><span class="nb-shiki-1itgoe"> extends</span><span class="nb-shiki-1t8gfj"> Think</span><span class="nb-shiki-140thh"><</span><span class="nb-shiki-1t8gfj">Env</span><span class="nb-shiki-140thh">> {</span></span>
<span class="line"><span class="nb-shiki-1t8gfj">	beforeTurn</span><span class="nb-shiki-140thh">(</span><span class="nb-shiki-1jdh33">ctx</span><span class="nb-shiki-140thh">) {</span></span>
<span class="line"><span class="nb-shiki-1itgoe">		return</span><span class="nb-shiki-140thh"> {</span></span>
<span class="line"><span class="nb-shiki-140thh">			messages: </span><span class="nb-shiki-1t8gfj">pruneMessages</span><span class="nb-shiki-140thh">({</span></span>
<span class="line"><span class="nb-shiki-140thh">				messages: ctx.messages,</span></span>
<span class="line"><span class="nb-shiki-140thh">				toolCalls: </span><span class="nb-shiki-mdbnqw">"before-last-2-messages"</span><span class="nb-shiki-140thh">,</span></span>
<span class="line"><span class="nb-shiki-140thh">			}),</span></span>
<span class="line"><span class="nb-shiki-140thh">		};</span></span>
<span class="line"><span class="nb-shiki-140thh">	}</span></span>
<span class="line"><span class="nb-shiki-140thh">}</span></span>
Voice agent connection control

@cloudflare/voice adds an enabled option to useVoiceAgent. React apps can now delay creating and connecting a VoiceClient until prerequisites such as capability tokens are ready.

<span class="line"><span class="nb-shiki-1itgoe">const</span><span class="nb-shiki-dzsirb"> voice</span><span class="nb-shiki-1itgoe"> =</span><span class="nb-shiki-1t8gfj"> useVoiceAgent</span><span class="nb-shiki-140thh">({</span></span>
<span class="line"><span class="nb-shiki-140thh">	agent: </span><span class="nb-shiki-mdbnqw">"MyVoiceAgent"</span><span class="nb-shiki-140thh">,</span></span>
<span class="line"><span class="nb-shiki-140thh">	enabled: </span><span class="nb-shiki-1t8gfj">Boolean</span><span class="nb-shiki-140thh">(token),</span></span>
<span class="line"><span class="nb-shiki-140thh">});</span></span>
<span class="line"><span class="nb-shiki-1itgoe">const</span><span class="nb-shiki-dzsirb"> voice</span><span class="nb-shiki-1itgoe"> =</span><span class="nb-shiki-1t8gfj"> useVoiceAgent</span><span class="nb-shiki-140thh">({</span></span>
<span class="line"><span class="nb-shiki-140thh">	agent: </span><span class="nb-shiki-mdbnqw">"MyVoiceAgent"</span><span class="nb-shiki-140thh">,</span></span>
<span class="line"><span class="nb-shiki-140thh">	enabled: </span><span class="nb-shiki-1t8gfj">Boolean</span><span class="nb-shiki-140thh">(token),</span></span>
<span class="line"><span class="nb-shiki-140thh">});</span></span>

This release also fixes Workers AI speech-to-text session edge cases and withVoice text streaming from AI SDK textStream responses.

Other improvements
  • Streamable HTTP routing — Server-to-client requests now route through the originating POST stream when no standalone SSE stream is available.
  • Structured tool output — Tool output shapes are preserved when truncating older messages or oversized persisted rows.
  • Non-chat Think tool steps — Think agent-tool children can complete without emitting assistant text and can return structured output through getAgentToolOutput.
  • Sub-agent schedules — Stale sub-agent schedule rows are pruned when their owning facet registry entry no longer exists.
  • @cloudflare/codemode — Adds a browser-safe export with an iframe sandbox executor and resolves OpenAPI specs inside the sandbox to avoid Worker Loader RPC size limits.
Upgrade

To update to the latest version:

<span class="line"><span class="nb-shiki-1t8gfj">npm</span><span class="nb-shiki-mdbnqw"> i</span><span class="nb-shiki-mdbnqw"> agents@latest</span><span class="nb-shiki-mdbnqw"> @cloudflare/ai-chat@latest</span><span class="nb-shiki-mdbnqw"> @cloudflare/think@latest</span><span class="nb-shiki-mdbnqw"> @cloudflare/voice@latest</span></span>

Refer to the Agents API reference and Chat agents documentation for more information.

Fetched July 22, 2026