Sign inConnect your agent
infochanged

Agents, Workers - Agents SDK improves browser automation, code execution, and recovery

Announced
Tags
Agents, Workers
Severity
info, set by reef/rss-rule-v1
Source
https://developers.cloudflare.com/changelog/post/2026-06-16-agents-sdk-v0.16.1/

<p>The latest release of the <a href="https://github.com/cloudflare/agents" target="_blank" rel="noopener">Agents SDK<span class="external-link"> ↗</span></a> makes it easier to build agents that can safely interact with real systems and keep working through interruptions.</p> <p>Agents can now browse websites through Browser Run, write code against external tools through Code Mode, use client-provided tools when delegating to Think sub-agents, and recover more reliably from deploys, Durable Object evictions, and connection churn.</p> <div tabindex="-1" class="heading-wrapper level-h4"><h4 id="safer-browser-automation">Safer browser automation</h4><a class="anchor-link" href="#safer-browser-automation"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>Agents can now use <a href="https://developers.cloudflare.com/browser-run/">Browser Run</a> through a single durable <code>browser_execute</code> tool. Instead of choosing from a fixed list of actions, the model writes code against the Chrome DevTools Protocol (CDP) and can inspect pages, capture screenshots, read rendered content, debug frontend behavior, and interact with live browser sessions.</p> <div><div data-nb-tabs data-nb-sync-key="workersExamples" class><div class="relative flex border-b border-border" role="tablist" data-nb-tabs-list><span class="bg-primary pointer-events-none absolute -bottom-px h-0.5 rounded-t-sm transition-[left,width] duration-200 ease-out" data-nb-tabs-indicator aria-hidden="true"></span></div><div class="mt-3"><div role="tabpanel" data-nb-tabs-content data-nb-tab-label="JavaScript" class><figure class="nb-code-figure" data-nb-lang="js"><pre class="astro-code astro-code-themes github-light github-dark nb-shiki-c6xiwz" tabindex="0" data-language="js" data-nb-lang="js"><code><span class="line"><span class="nb-shiki-1itgoe">const</span><span class="nb-shiki-dzsirb"> browserTools</span><span class="nb-shiki-1itgoe"> =</span><span class="nb-shiki-1t8gfj"> createBrowserTools</span><span class="nb-shiki-140thh">({</span></span> <span class="line"><span class="nb-shiki-140thh"> ctx: </span><span class="nb-shiki-dzsirb">this</span><span class="nb-shiki-140thh">.ctx,</span></span> <span class="line"><span class="nb-shiki-140thh"> browser: </span><span class="nb-shiki-dzsirb">this</span><span class="nb-shiki-140thh">.env.</span><span class="nb-shiki-dzsirb">BROWSER</span><span class="nb-shiki-140thh">,</span></span> <span class="line"><span class="nb-shiki-140thh"> loader: </span><span class="nb-shiki-dzsirb">this</span><span class="nb-shiki-140thh">.env.</span><span class="nb-shiki-dzsirb">LOADER</span><span class="nb-shiki-140thh">,</span></span> <span class="line"><span class="nb-shiki-140thh"> session: { mode: </span><span class="nb-shiki-mdbnqw">"dynamic"</span><span class="nb-shiki-140thh"> },</span></span> <span class="line"><span class="nb-shiki-140thh">});</span></span></code></pre></figure></div><div role="tabpanel" data-nb-tabs-content data-nb-tab-label="TypeScript" class><figure class="nb-code-figure" data-nb-lang="ts"><pre class="astro-code astro-code-themes github-light github-dark nb-shiki-c6xiwz" tabindex="0" data-language="ts" data-nb-lang="ts"><code><span class="line"><span class="nb-shiki-1itgoe">const</span><span class="nb-shiki-dzsirb"> browserTools</span><span class="nb-shiki-1itgoe"> =</span><span class="nb-shiki-1t8gfj"> createBrowserTools</span><span class="nb-shiki-140thh">({</span></span> <span class="line"><span class="nb-shiki-140thh"> ctx: </span><span class="nb-shiki-dzsirb">this</span><span class="nb-shiki-140thh">.ctx,</span></span> <span class="line"><span class="nb-shiki-140thh"> browser: </span><span class="nb-shiki-dzsirb">this</span><span class="nb-shiki-140thh">.env.</span><span class="nb-shiki-dzsirb">BROWSER</span><span class="nb-shiki-140thh">,</span></span> <span class="line"><span class="nb-shiki-140thh"> loader: </span><span class="nb-shiki-dzsirb">this</span><span class="nb-shiki-140thh">.env.</span><span class="nb-shiki-dzsirb">LOADER</span><span class="nb-shiki-140thh">,</span></span> <span class="line"><span class="nb-shiki-140thh"> session: { mode: </span><span class="nb-shiki-mdbnqw">"dynamic"</span><span class="nb-shiki-140thh"> },</span></span> <span class="line"><span class="nb-shiki-140thh">});</span></span></code></pre></figure></div></div></div><script type="module" src="https://developers.cloudflare.com/home/runner/work/cloudflare-docs/cloudflare-docs/src/components/ui/tabs/Tabs.astro?astro&type=script&index=0&lang.ts"></script></div> <p>Browser sessions can be one-time, reused, or promoted from one-time to persistent during a run. This is useful when an agent needs a human to log in, complete MFA, or approve a sensitive action. The run can pause, keep the same tabs and cookies, and resume after approval.</p> <p>The browser tools also add Live View URLs, optional session recording, and quick actions such as <code>browser_markdown</code>, <code>browser_extract</code>, <code>browser_links</code>, and <code>browser_scrape</code> for one-shot browsing tasks.</p> <div tabindex="-1" class="heading-wrapper level-h4"><h4 id="resumable-code-execution-with-approvals">Resumable code execution with approvals</h4><a class="anchor-link" href="#resumable-code-execution-with-approvals"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>Code Mode now uses <code>createCodemodeRuntime</code>, connectors, and a durable execution log. This lets you give a model one <code>codemode</code> tool instead of a large prompt full of tool definitions. The model can discover the capabilities it needs, write code against typed globals, and reuse saved snippets.</p> <div><div data-nb-tabs data-nb-sync-key="workersExamples" class><div class="relative flex border-b border-border" role="tablist" data-nb-tabs-list><span class="bg-primary pointer-events-none absolute -bottom-px h-0.5 rounded-t-sm transition-[left,width] duration-200 ease-out" data-nb-tabs-indicator aria-hidden="true"></span></div><div class="mt-3"><div role="tabpanel" data-nb-tabs-content data-nb-tab-label="JavaScript" class><figure class="nb-code-figure" data-nb-lang="js"><pre class="astro-code astro-code-themes github-light github-dark nb-shiki-c6xiwz" tabindex="0" data-language="js" data-nb-lang="js"><code><span class="line"><span class="nb-shiki-1itgoe">const</span><span class="nb-shiki-dzsirb"> runtime</span><span class="nb-shiki-1itgoe"> =</span><span class="nb-shiki-1t8gfj"> createCodemodeRuntime</span><span class="nb-shiki-140thh">({</span></span> <span class="line"><span class="nb-shiki-140thh"> ctx: </span><span class="nb-shiki-dzsirb">this</span><span class="nb-shiki-140thh">.ctx,</span></span> <span class="line"><span class="nb-shiki-140thh"> executor: </span><span class="nb-shiki-1itgoe">new</span><span class="nb-shiki-1t8gfj"> DynamicWorkerExecutor</span><span class="nb-shiki-140thh">({ loader: </span><span class="nb-shiki-dzsirb">this</span><span class="nb-shiki-140thh">.env.</span><span class="nb-shiki-dzsirb">LOADER</span><span class="nb-shiki-140thh"> }),</span></span> <span class="line"><span class="nb-shiki-140thh"> connectors: [</span><span class="nb-shiki-1itgoe">new</span><span class="nb-shiki-1t8gfj"> GithubConnector</span><span class="nb-shiki-140thh">(</span><span class="nb-shiki-dzsirb">this</span><span class="nb-shiki-140thh">.ctx, </span><span class="nb-shiki-dzsirb">this</span><span class="nb-shiki-140thh">.env, connection)],</span></span> <span class="line"><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"> result</span><span class="nb-shiki-1itgoe"> =</span><span class="nb-shiki-1t8gfj"> streamText</span><span class="nb-shiki-140thh">({</span></span> <span class="line"><span class="nb-shiki-140thh"> model,</span></span> <span class="line"><span class="nb-shiki-140thh"> messages,</span></span> <span class="line"><span class="nb-shiki-140thh"> tools: { codemode: runtime.</span><span class="nb-shiki-1t8gfj">tool</span><span class="nb-shiki-140thh">() },</span></span> <span class="line"><span class="nb-shiki-140thh">});</span></span></code></pre></figure></div><div role="tabpanel" data-nb-tabs-content data-nb-tab-label="TypeScript" class><figure class="nb-code-figure" data-nb-lang="ts"><pre class="astro-code astro-code-themes github-light github-dark nb-shiki-c6xiwz" tabindex="0" data-language="ts" data-nb-lang="ts"><code><span class="line"><span class="nb-shiki-1itgoe">const</span><span class="nb-shiki-dzsirb"> runtime</span><span class="nb-shiki-1itgoe"> =</span><span class="nb-shiki-1t8gfj"> createCodemodeRuntime</span><span class="nb-shiki-140thh">({</span></span> <span class="line"><span class="nb-shiki-140thh"> ctx: </span><span class="nb-shiki-dzsirb">this</span><span class="nb-shiki-140thh">.ctx,</span></span> <span class="line"><span class="nb-shiki-140thh"> executor: </span><span class="nb-shiki-1itgoe">new</span><span class="nb-shiki-1t8gfj"> DynamicWorkerExecutor</span><span class="nb-shiki-140thh">({ loader: </span><span class="nb-shiki-dzsirb">this</span><span class="nb-shiki-140thh">.env.</span><span class="nb-shiki-dzsirb">LOADER</span><span class="nb-shiki-140thh"> }),</span></span> <span class="line"><span class="nb-shiki-140thh"> connectors: [</span><span class="nb-shiki-1itgoe">new</span><span class="nb-shiki-1t8gfj"> GithubConnector</span><span class="nb-shiki-140thh">(</span><span class="nb-shiki-dzsirb">this</span><span class="nb-shiki-140thh">.ctx, </span><span class="nb-shiki-dzsirb">this</span><span class="nb-shiki-140thh">.env, connection)],</span></span> <span class="line"><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"> result</span><span class="nb-shiki-1itgoe"> =</span><span class="nb-shiki-1t8gfj"> streamText</span><span class="nb-shiki-140thh">({</span></span> <span class="line"><span class="nb-shiki-140thh"> model,</span></span> <span class="line"><span class="nb-shiki-140thh"> messages,</span></span> <span class="line"><span class="nb-shiki-140thh"> tools: { codemode: runtime.</span><span class="nb-shiki-1t8gfj">tool</span><span class="nb-shiki-140thh">() },</span></span> <span class="line"><span class="nb-shiki-140thh">});</span></span></code></pre></figure></div></div></div></div> <p>When the code reaches an approval-gated action, the runtime pauses execution and returns a pending approval. After approval, completed calls replay from the durable log, the approved action runs, and the same code continues. This makes it practical to build agents that create issues, update external systems, or perform other side effects without custom pause-and-resume logic for every tool.</p> <div tabindex="-1" class="heading-wrapper level-h4"><h4 id="better-think-delegation">Better Think delegation</h4><a class="anchor-link" href="#better-think-delegation"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>Think sub-agents can now use client-defined tools over the RPC <code>chat()</code> path. A parent agent can pass tool schemas with <code>clientTools</code> and resolve tool calls through <code>onClientToolCall</code>. This lets delegated agents use caller-provided capabilities without requiring a browser WebSocket.</p> <div><div data-nb-tabs data-nb-sync-key="workersExamples" class><div class="relative flex border-b border-border" role="tablist" data-nb-tabs-list><span class="bg-primary pointer-events-none absolute -bottom-px h-0.5 rounded-t-sm transition-[left,width] duration-200 ease-out" data-nb-tabs-indicator aria-hidden="true"></span></div><div class="mt-3"><div role="tabpanel" data-nb-tabs-content data-nb-tab-label="JavaScript" class><figure class="nb-code-figure" data-nb-lang="js"><pre class="astro-code astro-code-themes github-light github-dark nb-shiki-c6xiwz" tabindex="0" data-language="js" data-nb-lang="js"><code><span class="line"><span class="nb-shiki-1itgoe">await</span><span class="nb-shiki-140thh"> child.</span><span class="nb-shiki-1t8gfj">chat</span><span class="nb-shiki-140thh">(message, callback, {</span></span> <span class="line"><span class="nb-shiki-140thh"> signal,</span></span> <span class="line"><span class="nb-shiki-140thh"> clientTools: [</span></span> <span class="line"><span class="nb-shiki-140thh"> {</span></span> <span class="line"><span class="nb-shiki-140thh"> name: </span><span class="nb-shiki-mdbnqw">"get_user_timezone"</span><span class="nb-shiki-140thh">,</span></span> <span class="line"><span class="nb-shiki-140thh"> description: </span><span class="nb-shiki-mdbnqw">"Get the caller's timezone"</span><span class="nb-shiki-140thh">,</span></span> <span class="line"><span class="nb-shiki-140thh"> parameters: { type: </span><span class="nb-shiki-mdbnqw">"object"</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-1t8gfj"> onClientToolCall</span><span class="nb-shiki-140thh">: </span><span class="nb-shiki-1itgoe">async</span><span class="nb-shiki-140thh"> ({ </span><span class="nb-shiki-1jdh33">toolName</span><span class="nb-shiki-140thh">, </span><span class="nb-shiki-1jdh33">input</span><span class="nb-shiki-140thh"> }) </span><span class="nb-shiki-1itgoe">=></span><span class="nb-shiki-140thh"> {</span></span> <span class="line"><span class="nb-shiki-1itgoe"> return</span><span class="nb-shiki-1t8gfj"> runClientTool</span><span class="nb-shiki-140thh">(toolName, input);</span></span> <span class="line"><span class="nb-shiki-140thh"> },</span></span> <span class="line"><span class="nb-shiki-140thh">});</span></span></code></pre></figure></div><div role="tabpanel" data-nb-tabs-content data-nb-tab-label="TypeScript" class><figure class="nb-code-figure" data-nb-lang="ts"><pre class="astro-code astro-code-themes github-light github-dark nb-shiki-c6xiwz" tabindex="0" data-language="ts" data-nb-lang="ts"><code><span class="line"><span class="nb-shiki-1itgoe">await</span><span class="nb-shiki-140thh"> child.</span><span class="nb-shiki-1t8gfj">chat</span><span class="nb-shiki-140thh">(message, callback, {</span></span> <span class="line"><span class="nb-shiki-140thh"> signal,</span></span> <span class="line"><span class="nb-shiki-140thh"> clientTools: [</span></span> <span class="line"><span class="nb-shiki-140thh"> {</span></span> <span class="line"><span class="nb-shiki-140thh"> name: </span><span class="nb-shiki-mdbnqw">"get_user_timezone"</span><span class="nb-shiki-140thh">,</span></span> <span class="line"><span class="nb-shiki-140thh"> description: </span><span class="nb-shiki-mdbnqw">"Get the caller's timezone"</span><span class="nb-shiki-140thh">,</span></span> <span class="line"><span class="nb-shiki-140thh"> parameters: { type: </span><span class="nb-shiki-mdbnqw">"object"</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-1t8gfj"> onClientToolCall</span><span class="nb-shiki-140thh">: </span><span class="nb-shiki-1itgoe">async</span><span class="nb-shiki-140thh"> ({ </span><span class="nb-shiki-1jdh33">toolName</span><span class="nb-shiki-140thh">, </span><span class="nb-shiki-1jdh33">input</span><span class="nb-shiki-140thh"> }) </span><span class="nb-shiki-1itgoe">=&gt;</span><span class="nb-shiki-140thh"> {</span></span> <span class="line"><span class="nb-shiki-1itgoe"> return</span><span class="nb-shiki-1t8gfj"> runClientTool</span><span class="nb-shiki-140thh">(toolName, input);</span></span> <span class="line"><span class="nb-shiki-140thh"> },</span></span> <span class="line"><span class="nb-shiki-140thh">});</span></span></code></pre></figure></div></div></div></div> <p>Think Workflows also improve <code>step.prompt()</code>. A prompt step now runs a full agentic turn before returning structured output, so the agent can call tools before producing the typed result. This makes Workflow steps more useful for durable triage, research, and approval flows.</p> <p>The unified Think execute tool can also include <code>cdp.*</code> browser capabilities alongside <code>state.*</code> and <code>tools.*</code> when Browser Run is bound.</p> <div tabindex="-1" class="heading-wrapper level-h4"><h4 id="voice-output-device-selection">Voice output device selection</h4><a class="anchor-link" href="#voice-output-device-selection"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>Voice clients can route assistant audio to a specific output device. Use <code>outputDeviceId</code> with <code>useVoiceAgent</code>, or call <code>client.setOutputDevice()</code> from the framework-agnostic client.</p> <div><div data-nb-tabs data-nb-sync-key="workersExamples" class><div class="relative flex border-b border-border" role="tablist" data-nb-tabs-list><span class="bg-primary pointer-events-none absolute -bottom-px h-0.5 rounded-t-sm transition-[left,width] duration-200 ease-out" data-nb-tabs-indicator aria-hidden="true"></span></div><div class="mt-3"><div role="tabpanel" data-nb-tabs-content data-nb-tab-label="JavaScript" class><figure class="nb-code-figure" data-nb-lang="js"><pre class="astro-code astro-code-themes github-light github-dark nb-shiki-c6xiwz" tabindex="0" data-language="js" data-nb-lang="js"><code><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"> outputDeviceId: selectedSpeakerId,</span></span> <span class="line"><span class="nb-shiki-140thh">});</span></span></code></pre></figure></div><div role="tabpanel" data-nb-tabs-content data-nb-tab-label="TypeScript" class><figure class="nb-code-figure" data-nb-lang="tsx"><pre class="astro-code astro-code-themes github-light github-dark nb-shiki-c6xiwz" tabindex="0" data-language="tsx" data-nb-lang="tsx"><code><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"> outputDeviceId: selectedSpeakerId,</span></span> <span class="line"><span class="nb-shiki-140thh">});</span></span></code></pre></figure></div></div></div></div> <p>Browsers without speaker-selection support continue playing through the default output device and report a non-fatal <code>outputDeviceError</code>.</p> <div tabindex="-1" class="heading-wrapper level-h4"><h4 id="reliability-fixes">Reliability fixes</h4><a class="anchor-link" href="#reliability-fixes"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>This release includes several fixes for production agents:</p> <ul> <li><code>useAgent</code> and <code>AgentClient</code> handle WebSocket replacement more reliably during reconnects and configuration changes.</li> <li>Chat stream replay is more reliable after reconnects, deploys, and provider errors.</li> <li>Fiber recovery continues across multi-pass scans and backs off when recovery hooks keep failing.</li> <li>Agent teardown continues even when the request that started teardown is canceled.</li> <li>Large session histories use byte-budgeted reads to reduce memory pressure during startup.</li> </ul> <div tabindex="-1" class="heading-wrapper level-h4"><h4 id="upgrade">Upgrade</h4><a class="anchor-link" href="#upgrade"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>To update to the latest version:</p> <script> if (!customElements.get("nb-pm-restore")) { customElements.define( "nb-pm-restore", class extends HTMLElement { connectedCallback() { const card = this.closest("[data-nb-pm]"); if (!card) return; let saved; try { saved = sessionStorage.getItem("ui-pm-tab"); } catch { return; } if (!saved) return; const tabs = card.querySelectorAll("[data-nb-pm-tab]"); let idx = -1; tabs.forEach(function (t, i) { if (t.textContent.trim() === saved) idx = i; }); if (idx < 1) return; tabs.forEach(function (t, i) { t.setAttribute("aria-selected", String(i === idx)); }); card.querySelectorAll("[data-nb-pm-panel]").forEach(function (p, i) { p.hidden = i !== idx; }); } }, ); } </script><div data-nb-pm class="w-full"><div class="flex w-full flex-col overflow-hidden rounded-lg text-sm ring ring-border bg-card"><div class="flex items-center gap-2 px-3 py-2 text-[0.8125rem] font-medium leading-5 text-muted-foreground bg-[var(--nb-surface-sunken)]" role="tablist" aria-label="Package manager"><button role="tab" type="button" aria-selected="true" aria-controls="pm-panel-pm-0bca6d74-aab3-4117-bf80-9ce00a02890f-npm" id="pm-tab-pm-0bca6d74-aab3-4117-bf80-9ce00a02890f-npm" data-nb-pm-tab class="text-muted-foreground hover:bg-accent hover:text-foreground aria-selected:bg-selected aria-selected:text-foreground focus-visible:outline-ring m-0 cursor-pointer rounded-md border-0 bg-transparent px-2 py-0.5 text-xs leading-5 font-medium transition-colors focus-visible:outline-2 focus-visible:outline-offset-2">npm</button><button role="tab" type="button" aria-selected="false" aria-controls="pm-panel-pm-0bca6d74-aab3-4117-bf80-9ce00a02890f-yarn" id="pm-tab-pm-0bca6d74-aab3-4117-bf80-9ce00a02890f-yarn" data-nb-pm-tab class="text-muted-foreground hover:bg-accent hover:text-foreground aria-selected:bg-selected aria-selected:text-foreground focus-visible:outline-ring m-0 cursor-pointer rounded-md border-0 bg-transparent px-2 py-0.5 text-xs leading-5 font-medium transition-colors focus-visible:outline-2 focus-visible:outline-offset-2">yarn</button><button role="tab" type="button" aria-selected="false" aria-controls="pm-panel-pm-0bca6d74-aab3-4117-bf80-9ce00a02890f-pnpm" id="pm-tab-pm-0bca6d74-aab3-4117-bf80-9ce00a02890f-pnpm" data-nb-pm-tab class="text-muted-foreground hover:bg-accent hover:text-foreground aria-selected:bg-selected aria-selected:text-foreground focus-visible:outline-ring m-0 cursor-pointer rounded-md border-0 bg-transparent px-2 py-0.5 text-xs leading-5 font-medium transition-colors focus-visible:outline-2 focus-visible:outline-offset-2">pnpm</button><button role="tab" type="button" aria-selected="false" aria-controls="pm-panel-pm-0bca6d74-aab3-4117-bf80-9ce00a02890f-bun" id="pm-tab-pm-0bca6d74-aab3-4117-bf80-9ce00a02890f-bun" data-nb-pm-tab class="text-muted-foreground hover:bg-accent hover:text-foreground aria-selected:bg-selected aria-selected:text-foreground focus-visible:outline-ring m-0 cursor-pointer rounded-md border-0 bg-transparent px-2 py-0.5 text-xs leading-5 font-medium transition-colors focus-visible:outline-2 focus-visible:outline-offset-2">bun</button></div><div role="tabpanel" id="pm-panel-pm-0bca6d74-aab3-4117-bf80-9ce00a02890f-npm" aria-labelledby="pm-tab-pm-0bca6d74-aab3-4117-bf80-9ce00a02890f-npm" data-nb-pm-panel class="bg-card ring-border relative overflow-hidden rounded-lg text-inherit ring"><div class="flex items-stretch"><pre class="text-foreground my-0 min-w-0 grow overflow-x-auto border-0 bg-transparent px-4 py-3 font-mono text-sm leading-relaxed whitespace-pre"><code data-nb-pm-code><span class="text-success">npm</span><span class="text-warning"> i agents@latest @cloudflare/think@latest @cloudflare/codemode@latest @cloudflare/ai-chat@latest @cloudflare/voice@latest</span></code></pre><button type="button" data-nb-pm-copy data-nb-command="npm i agents@latest @cloudflare/think@latest @cloudflare/codemode@latest @cloudflare/ai-chat@latest @cloudflare/voice@latest" aria-label="Copy to clipboard" class="border-border text-muted-foreground hover:text-foreground focus-visible:outline-ring m-0 flex shrink-0 cursor-pointer items-center justify-center border-0 border-l border-solid bg-transparent px-3 transition-colors focus-visible:outline-2 focus-visible:-outline-offset-2"><svg width="1em" height="1em" viewBox="0 0 256 256" class="h-[18px] w-[18px]" data-icon="ph:copy"><path fill="currentColor" d="M216 32H88a8 8 0 0 0-8 8v40H40a8 8 0 0 0-8 8v128a8 8 0 0 0 8 8h128a8 8 0 0 0 8-8v-40h40a8 8 0 0 0 8-8V40a8 8 0 0 0-8-8m-56 176H48V96h112Zm48-48h-32V88a8 8 0 0 0-8-8H96V48h112Z"/></svg><svg width="1em" height="1em" viewBox="0 0 256 256" class="hidden h-[18px] w-[18px]" data-icon="ph:check"><path fill="currentColor" d="m229.66 77.66l-128 128a8 8 0 0 1-11.32 0l-56-56a8 8 0 0 1 11.32-11.32L96 188.69L218.34 66.34a8 8 0 0 1 11.32 11.32"/></svg></button></div></div><div role="tabpanel" id="pm-panel-pm-0bca6d74-aab3-4117-bf80-9ce00a02890f-yarn" aria-labelledby="pm-tab-pm-0bca6d74-aab3-4117-bf80-9ce00a02890f-yarn" hidden data-nb-pm-panel class="bg-card ring-border relative overflow-hidden rounded-lg text-inherit ring"><div class="flex items-stretch"><pre class="text-foreground my-0 min-w-0 grow overflow-x-auto border-0 bg-transparent px-4 py-3 font-mono text-sm leading-relaxed whitespace-pre"><code data-nb-pm-code><span class="text-success">yarn</span><span class="text-warning"> add agents@latest @cloudflare/think@latest @cloudflare/codemode@latest @cloudflare/ai-chat@latest @cloudflare/voice@latest</span></code></pre><button type="button" data-nb-pm-copy data-nb-command="yarn add agents@latest @cloudflare/think@latest @cloudflare/codemode@latest @cloudflare/ai-chat@latest @cloudflare/voice@latest" aria-label="Copy to clipboard" class="border-border text-muted-foreground hover:text-foreground focus-visible:outline-ring m-0 flex shrink-0 cursor-pointer items-center justify-center border-0 border-l border-solid bg-transparent px-3 transition-colors focus-visible:outline-2 focus-visible:-outline-offset-2"><svg width="1em" height="1em" viewBox="0 0 256 256" class="h-[18px] w-[18px]" data-icon="ph:copy"><path fill="currentColor" d="M216 32H88a8 8 0 0 0-8 8v40H40a8 8 0 0 0-8 8v128a8 8 0 0 0 8 8h128a8 8 0 0 0 8-8v-40h40a8 8 0 0 0 8-8V40a8 8 0 0 0-8-8m-56 176H48V96h112Zm48-48h-32V88a8 8 0 0 0-8-8H96V48h112Z"/></svg><svg width="1em" height="1em" viewBox="0 0 256 256" class="hidden h-[18px] w-[18px]" data-icon="ph:check"><path fill="currentColor" d="m229.66 77.66l-128 128a8 8 0 0 1-11.32 0l-56-56a8 8 0 0 1 11.32-11.32L96 188.69L218.34 66.34a8 8 0 0 1 11.32 11.32"/></svg></button></div></div><div role="tabpanel" id="pm-panel-pm-0bca6d74-aab3-4117-bf80-9ce00a02890f-pnpm" aria-labelledby="pm-tab-pm-0bca6d74-aab3-4117-bf80-9ce00a02890f-pnpm" hidden data-nb-pm-panel class="bg-card ring-border relative overflow-hidden rounded-lg text-inherit ring"><div class="flex items-stretch"><pre class="text-foreground my-0 min-w-0 grow overflow-x-auto border-0 bg-transparent px-4 py-3 font-mono text-sm leading-relaxed whitespace-pre"><code data-nb-pm-code><span class="text-success">pnpm</span><span class="text-warning"> add agents@latest @cloudflare/think@latest @cloudflare/codemode@latest @cloudflare/ai-chat@latest @cloudflare/voice@latest</span></code></pre><button type="button" data-nb-pm-copy data-nb-command="pnpm add agents@latest @cloudflare/think@latest @cloudflare/codemode@latest @cloudflare/ai-chat@latest @cloudflare/voice@latest" aria-label="Copy to clipboard" class="border-border text-muted-foreground hover:text-foreground focus-visible:outline-ring m-0 flex shrink-0 cursor-pointer items-center justify-center border-0 border-l border-solid bg-transparent px-3 transition-colors focus-visible:outline-2 focus-visible:-outline-offset-2"><svg width="1em" height="1em" viewBox="0 0 256 256" class="h-[18px] w-[18px]" data-icon="ph:copy"><path fill="currentColor" d="M216 32H88a8 8 0 0 0-8 8v40H40a8 8 0 0 0-8 8v128a8 8 0 0 0 8 8h128a8 8 0 0 0 8-8v-40h40a8 8 0 0 0 8-8V40a8 8 0 0 0-8-8m-56 176H48V96h112Zm48-48h-32V88a8 8 0 0 0-8-8H96V48h112Z"/></svg><svg width="1em" height="1em" viewBox="0 0 256 256" class="hidden h-[18px] w-[18px]" data-icon="ph:check"><path fill="currentColor" d="m229.66 77.66l-128 128a8 8 0 0 1-11.32 0l-56-56a8 8 0 0 1 11.32-11.32L96 188.69L218.34 66.34a8 8 0 0 1 11.32 11.32"/></svg></button></div></div><div role="tabpanel" id="pm-panel-pm-0bca6d74-aab3-4117-bf80-9ce00a02890f-bun" aria-labelledby="pm-tab-pm-0bca6d74-aab3-4117-bf80-9ce00a02890f-bun" hidden data-nb-pm-panel class="bg-card ring-border relative overflow-hidden rounded-lg text-inherit ring"><div class="flex items-stretch"><pre class="text-foreground my-0 min-w-0 grow overflow-x-auto border-0 bg-transparent px-4 py-3 font-mono text-sm leading-relaxed whitespace-pre"><code data-nb-pm-code><span class="text-success">bun</span><span class="text-warning"> add agents@latest @cloudflare/think@latest @cloudflare/codemode@latest @cloudflare/ai-chat@latest @cloudflare/voice@latest</span></code></pre><button type="button" data-nb-pm-copy data-nb-command="bun add agents@latest @cloudflare/think@latest @cloudflare/codemode@latest @cloudflare/ai-chat@latest @cloudflare/voice@latest" aria-label="Copy to clipboard" class="border-border text-muted-foreground hover:text-foreground focus-visible:outline-ring m-0 flex shrink-0 cursor-pointer items-center justify-center border-0 border-l border-solid bg-transparent px-3 transition-colors focus-visible:outline-2 focus-visible:-outline-offset-2"><svg width="1em" height="1em" viewBox="0 0 256 256" class="h-[18px] w-[18px]" data-icon="ph:copy"><path fill="currentColor" d="M216 32H88a8 8 0 0 0-8 8v40H40a8 8 0 0 0-8 8v128a8 8 0 0 0 8 8h128a8 8 0 0 0 8-8v-40h40a8 8 0 0 0 8-8V40a8 8 0 0 0-8-8m-56 176H48V96h112Zm48-48h-32V88a8 8 0 0 0-8-8H96V48h112Z"/></svg><svg width="1em" height="1em" viewBox="0 0 256 256" class="hidden h-[18px] w-[18px]" data-icon="ph:check"><path fill="currentColor" d="m229.66 77.66l-128 128a8 8 0 0 1-11.32 0l-56-56a8 8 0 0 1 11.32-11.32L96 188.69L218.34 66.34a8 8 0 0 1 11.32 11.32"/></svg></button></div></div><nb-pm-restore style="display:contents"></nb-pm-restore></div></div><script type="module" src="https://developers.cloudflare.com/home/runner/work/cloudflare-docs/cloudflare-docs/src/components/ui/package-managers/PackageManagers.astro?astro&type=script&index=0&lang.ts"></script> <p>Refer to the <a href="https://developers.cloudflare.com/agents/tools/codemode/">Code Mode documentation</a>, <a href="https://developers.cloudflare.com/agents/tools/browser/">Browser tools documentation</a>, <a href="https://developers.cloudflare.com/agents/harnesses/think/tools/">Think tools documentation</a>, and <a href="https://developers.cloudflare.com/agents/communication-channels/voice/">Voice documentation</a> for more information.</p>

The text above is the source's. reef added the severity, the dates it could read from the text, and the endpoints and scopes named in code.