---
title: Workers Changelog
image: https://edgetunnel-b2h.pages.dev/cf-twitter-card.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://edgetunnel-b2h.pages.dev/changelog/llms.txt  
> Use this file to discover all available pages before exploring further. 

[Skip to content](#%5Ftop) 

# Changelog

New updates and improvements at Cloudflare.

[ Subscribe to RSS ](https://edgetunnel-b2h.pages.dev/changelog/rss/index.xml) [ View RSS feeds ](https://edgetunnel-b2h.pages.dev/fundamentals/new-features/available-rss-feeds/) 

Workers

![hero image](https://edgetunnel-b2h.pages.dev/_astro/hero.CVYJHPAd_26AMqX.svg) 

Jul 14, 2026
1. ### [Platforms can now create Temporary Accounts via the Cloudflare API](https://edgetunnel-b2h.pages.dev/changelog/post/2026-07-14-temporary-accounts-api/)  
[ Workers ](https://edgetunnel-b2h.pages.dev/workers/)  
Platforms can now create temporary preview accounts through the Cloudflare REST API. This lets your platform deploy a live Worker before the user signs in to Cloudflare.  
With the Temporary Accounts API, coding agents, AI app builders, and other platforms can build a similar flow for generated Workers and supported resources.  
Your platform can keep users in its onboarding flow while they generate, deploy, and test an application. Users do not need an existing Cloudflare account, and your platform does not need write access to one.  
![Diagram showing an AI agent deploying, verifying, and redeploying a Worker in a temporary account, then a user authenticating and claiming the account to keep its resources](https://edgetunnel-b2h.pages.dev/_astro/claim-deployments-flow.Co0tUHG4_g1dGj.webp)  
The API returns a claim URL that lets the user make the temporary account and its resources permanent.  
[Cloudflare Drop ↗](https://www.cloudflare.com/drop/) demonstrates this preview-and-claim pattern for static sites. Someone can upload a site, test and share it for one hour, then sign in or create an account only when they want to keep it.  
This API expands the flow first introduced with [wrangler deploy --temporary](https://edgetunnel-b2h.pages.dev/changelog/post/2026-06-19-temporary-accounts-for-agents/). Your backend now controls the provisioning and deployment experience directly:

  1. Show Cloudflare's Terms of Service and Privacy Policy in your product, and require the user to accept them.
  2. Request and solve a proof-of-work challenge.
  3. Create a temporary preview account.
  4. Deploy with the returned temporary account ID and API token.
  5. Show the deployed Worker URL and claim URL to the user.  
```bash  
curl "https://api.cloudflare.com/client/v4/provisioning/previews/challenge" \
  -X POST \
  -H "Content-Type: application/json" \
  --data '{}'  
curl "https://api.cloudflare.com/client/v4/provisioning/previews" \
  -X POST \
  -H "Content-Type: application/json" \
  --data '{  
    "termsOfService": "https://www.cloudflare.com/terms/",  
    "privacyPolicy": "https://www.cloudflare.com/privacypolicy/",  
    "acceptTermsOfService": "yes",  
    "challengeToken": "<CHALLENGE_TOKEN>",  
    "solution": {  
      "checkpoints": "<BASE64_CHECKPOINTS>"  
    }  
  }'  
```  
For the complete API flow, proof-of-work requirements, supported products, and limits, refer to [Claim deployments (temporary accounts)](https://edgetunnel-b2h.pages.dev/workers/platform/claim-deployments/#integrate-with-the-rest-api). For the background and design goals behind this flow, refer to [Temporary Cloudflare Accounts for AI agents ↗](https://blog.cloudflare.com/temporary-accounts/).

Jul 13, 2026
1. ### [Agents can respond to MCP elicitation requests](https://edgetunnel-b2h.pages.dev/changelog/post/2026-07-13-mcp-client-elicitation/)  
[ Agents ](https://edgetunnel-b2h.pages.dev/agents/)[ Workers ](https://edgetunnel-b2h.pages.dev/workers/)  
Agents connected to Model Context Protocol (MCP) servers with [addMcpServer](https://edgetunnel-b2h.pages.dev/agents/model-context-protocol/apis/client-api/) can now handle [elicitation ↗](https://modelcontextprotocol.io/specification/2025-11-25/client/elicitation) requests.  
Elicitation lets an MCP server request user input while it handles a tool call. Form mode collects structured, non-sensitive data. URL mode asks for consent before opening an out-of-band flow, such as third-party authorization or payment.  
sequenceDiagram  
    participant User  
    participant Agent as Agent (MCP client)  
    participant Server as MCP server  
    participant Browser  
    Server->>Agent: elicitation/create  
    Agent->>User: Show server, reason, and input or URL  
    User->>Agent: Submit, open, decline, or cancel  
    Agent->>Browser: Open URL after consent (URL mode)  
    Agent->>Server: accept, decline, or cancel  
    Server-->>Agent: Optional URL completion notification  
Register a handler for each mode your Agent supports in `onStart()`:

  * [  JavaScript ](#tab-panel-2987)
  * [  TypeScript ](#tab-panel-2988)

**JavaScript**  
```js  
import { Agent } from "agents";  
export class MyAgent extends Agent {  
  onStart() {  
    this.mcp.configureElicitationHandlers({  
      form: (request, serverId) => this.forwardToUser(request, serverId),  
      url: (request, serverId) => this.forwardToUser(request, serverId),  
    });  
  }  
  forwardToUser(request, serverId) {  
    // Show the request in your UI and resolve after the user responds.  
    throw new Error(  
      `Implement elicitation for ${serverId}: ${request.params.message}`,  
    );  
  }  
}  
```

**TypeScript**  
```ts  
import { Agent } from "agents";  
import type { ElicitRequest, ElicitResult } from "agents/mcp";  
export class MyAgent extends Agent<Env> {  
  onStart() {  
    this.mcp.configureElicitationHandlers({  
      form: (request, serverId) => this.forwardToUser(request, serverId),  
      url: (request, serverId) => this.forwardToUser(request, serverId),  
    });  
  }  
  private forwardToUser(  
    request: ElicitRequest,  
    serverId: string,  
  ): Promise<ElicitResult> {  
    // Show the request in your UI and resolve after the user responds.  
    throw new Error(  
      `Implement elicitation for ${serverId}: ${request.params.message}`,  
    );  
  }  
}  
```  
Connections advertise only the modes with configured handlers. An Agent without handlers advertises no elicitation capability, which lets the server use its fallback. The SDK stores the advertised modes with each MCP server registration so they survive Durable Object hibernation. Callback functions remain in memory and reattach when `onStart()` runs.  
For implementation details and a browser forwarding pattern, refer to [MCP client elicitation](https://edgetunnel-b2h.pages.dev/agents/model-context-protocol/apis/client-api/#elicitation). The [mcp-client ↗](https://github.com/cloudflare/agents/tree/main/examples/mcp-client) and [mcp-elicitation ↗](https://github.com/cloudflare/agents/tree/main/examples/mcp-elicitation) examples implement both sides.  
#### Upgrade  
To update to this release:  
 npm  yarn  pnpm  bun  
```  
npm i agents@latest  
```  
```  
yarn add agents@latest  
```  
```  
pnpm add agents@latest  
```  
```  
bun add agents@latest  
```

Jul 09, 2026
1. ### [New Durable Object namespaces must use the SQLite storage backend](https://edgetunnel-b2h.pages.dev/changelog/post/2026-07-09-restrict-new-kv-backed-namespaces/)  
[ Durable Objects ](https://edgetunnel-b2h.pages.dev/durable-objects/)[ Workers ](https://edgetunnel-b2h.pages.dev/workers/)  
If your account does not already have a key-value (KV) backed Durable Object namespace, you can no longer create new ones. New Durable Object namespaces must use the [SQLite storage backend](https://edgetunnel-b2h.pages.dev/durable-objects/best-practices/access-durable-objects-storage/#create-sqlite-backed-durable-object-class), which has been recommended for all new Durable Objects since it became [generally available ↗](https://blog.cloudflare.com/sqlite-in-durable-objects/) in 2024.  
Create a new class with a `new_sqlite_classes` migration:

  * [  wrangler.jsonc ](#tab-panel-2971)
  * [  wrangler.toml ](#tab-panel-2972)

**JSONC**  
```jsonc  
{  
  "$schema": "./node_modules/wrangler/config-schema.json",  
  "migrations": [  
    {  
      "tag": "v1",  
      "new_sqlite_classes": [  
        "MyDurableObject"  
      ]  
    }  
  ]  
}  
```

**TOML**  
```toml  
[[migrations]]  
tag = "v1"  
new_sqlite_classes = ["MyDurableObject"]  
```  
SQLite-backed Durable Objects have feature parity with the key-value backend — including the [key-value storage API](https://edgetunnel-b2h.pages.dev/durable-objects/api/sqlite-storage-api/#synchronous-kv-api) — and additionally support relational [SQL queries](https://edgetunnel-b2h.pages.dev/durable-objects/api/sqlite-storage-api/#sql-api) and [point-in-time recovery](https://edgetunnel-b2h.pages.dev/durable-objects/api/sqlite-storage-api/#pitr-point-in-time-recovery-api) to restore an object's storage to any point in the past 30 days.  
If you attempt to create a new key-value backed namespace (a `new_classes` migration) on an affected account, the deployment fails with the following error:  
```txt  
Creating new key-value backed Durable Object namespaces is no longer supported on this account. Please create a namespace using a `new_sqlite_classes` migration instead.  
```  
This change only affects accounts that are not already using the key-value storage backend. Accounts with at least one existing key-value backed namespace can still create new ones for now, and the Workers Free plan has only ever supported SQLite-backed Durable Objects. It is part of a broader move toward SQLite as the single storage backend for Durable Objects, ahead of a future migration path for existing key-value backed objects.  
For more information, refer to [Durable Objects migrations](https://edgetunnel-b2h.pages.dev/durable-objects/reference/durable-objects-migrations/).

Jul 09, 2026
1. ### [Send npm package dependency metadata with Worker uploads](https://edgetunnel-b2h.pages.dev/changelog/post/2026-07-07-wrangler-deploy-upload-dependencies-metadata/)  
[ Workers ](https://edgetunnel-b2h.pages.dev/workers/)  
Wrangler now collects npm package dependency information from your project's `package.json` during [wrangler deploy](https://edgetunnel-b2h.pages.dev/workers/wrangler/commands/general/#deploy) and [wrangler versions upload](https://edgetunnel-b2h.pages.dev/workers/wrangler/commands/general/#upload), and includes it in the upload metadata sent to the Cloudflare API. This data, each dependency's name, declared version range, and exact installed version, enables dependency analytics and future supply chain security features such as vulnerability alerting.  
To opt out, set [dependencies\_instrumentation.enabled](https://edgetunnel-b2h.pages.dev/workers/wrangler/configuration/#top-level-only-keys) to `false` in your Wrangler configuration file:

  * [  wrangler.jsonc ](#tab-panel-2969)
  * [  wrangler.toml ](#tab-panel-2970)

**JSONC**  
```jsonc  
{  
  "dependencies_instrumentation": {  
    "enabled": false  
  }  
}  
```

**TOML**  
```toml  
[dependencies_instrumentation]  
enabled = false  
```  
For more details, refer to [Wrangler configuration](https://edgetunnel-b2h.pages.dev/workers/wrangler/configuration/#top-level-only-keys).

Jul 08, 2026
1. ### [Cloudflare Drop](https://edgetunnel-b2h.pages.dev/changelog/post/2026-07-08-cloudflare-drag-and-drop/)  
[ Workers ](https://edgetunnel-b2h.pages.dev/workers/)  
[Cloudflare Drop ↗](https://cloudflare.com/drop) lets you deploy a static site to Cloudflare without requiring a Cloudflare account to get started.  
![Cloudflare Drag and Drop upload screen for browsing folders or ZIP files](https://edgetunnel-b2h.pages.dev/_astro/cloudflare-drag-and-drop-upload.KujM69eS_2q5iiu.webp)  
Upload a folder or zip file of static assets (static HTML, CSS, JavaScript, images, and fonts) and get a temporary live preview that stays live for 1 hour. During that window, you can test the site, share the preview URL, or [claim the deployment](https://edgetunnel-b2h.pages.dev/workers/platform/claim-deployments/) to keep it.  
![Cloudflare Drag and Drop temporary live preview screen with claim and copy claim link actions](https://edgetunnel-b2h.pages.dev/_astro/cloudflare-drag-and-drop-preview.BQ1__XRX_2eteg3.webp)  
When you are ready to make the deployment permanent, click **Claim** to sign in or create a Cloudflare account. You can claim the site into an existing Cloudflare account or create a new account for the deployment.  
Note  
If you are creating a new account, you will need to verify your email address before continuing.  
![Cloudflare Drag and Drop claim account screen with a countdown before the claim link expires](https://edgetunnel-b2h.pages.dev/_astro/cloudflare-drag-and-drop-claim.8Zv6px9B_Z1vMkhk.webp)  
After claiming the site, you can:

  * **Add a domain**: [Connect](https://edgetunnel-b2h.pages.dev/workers/configuration/routing/custom-domains/) an existing domain or purchase a new one for your site.
  * **Enable [observability](https://edgetunnel-b2h.pages.dev/workers/observability/)**: Monitor your site's performance and usage.
  * **Enable [Markdown for Agents](https://edgetunnel-b2h.pages.dev/fundamentals/reference/markdown-for-agents/)**: Allow AI agents to access your site's content in Markdown.
  * **Control access**: Make your site [private](https://edgetunnel-b2h.pages.dev/cloudflare-one/access-controls/policies/) and choose who can view it.  
![Claimed Cloudflare Drag and Drop site setup screen showing options to add a domain, control access, enable observability, and enable Markdown for agents](https://edgetunnel-b2h.pages.dev/_astro/cloudflare-drag-and-drop-post-claim.DvlaNmI7_Zmbdcj.webp)

Jul 04, 2026
1. ### [Declare Durable Object class lifecycle with \`exports\`](https://edgetunnel-b2h.pages.dev/changelog/post/2026-06-30-declarative-do-class-exports/)  
[ Durable Objects ](https://edgetunnel-b2h.pages.dev/durable-objects/)[ Workers ](https://edgetunnel-b2h.pages.dev/workers/)  
A new declarative [exports](https://edgetunnel-b2h.pages.dev/durable-objects/reference/durable-objects-migrations/) field in your Wrangler configuration file replaces the imperative [migrations](https://edgetunnel-b2h.pages.dev/durable-objects/reference/durable-object-class-migrations-legacy/) array for managing Durable Object class lifecycle. Instead of writing an ordered list of migration steps with unique tags, you declare each Durable Object class your Worker exports and Cloudflare compares that against what's already deployed to determine what Durable Object state needs to be created, renamed, or deleted.  
With legacy migrations, renaming `ChatRoom` to `Room` requires retaining both tagged steps:

**Before — legacy migrations**  
```jsonc  
{  
  "migrations": [  
    { "tag": "v1", "new_sqlite_classes": ["ChatRoom"] },  
    {  
      "tag": "v2",  
      "renamed_classes": [{ "from": "ChatRoom", "to": "Room" }],  
    },  
  ],  
}  
```  
With `exports`, you instead declare `Room` as the current class and mark `ChatRoom` as renamed:

**After — declarative exports**  
```jsonc  
{  
  "exports": {  
    "ChatRoom": {  
      "type": "durable-object",  
      "state": "renamed",  
      "renamed_to": "Room",  
    },  
    "Room": { "type": "durable-object", "storage": "sqlite" },  
  },  
}  
```  
Each entry is keyed by class name. The `state` field carries the lifecycle (`created` by default — a live class — plus tombstone states `deleted`, `renamed`, and `transferred`, and the `expecting-transfer` receiving state for cross-Worker transfers).  
Key improvements over the legacy `migrations` array:

  * **No migration tags.** The current `exports` map is the source of truth — there is no historical chain of `v1`, `v2`, `v3` entries to maintain.
  * **Structured deployment output.** Wrangler reports when it creates, updates, deletes, renames, or transfers Durable Object classes. It also identifies stale configuration entries that are safe to remove. Deployments with no changes or notices do not print this output.
  * **Zero-downtime rename and transfer patterns are first-class.** Tombstones may coexist with the source class still in code, enabling a [three-deploy rename](https://edgetunnel-b2h.pages.dev/durable-objects/reference/durable-objects-migrations/#avoid-downtime-during-a-rename) and a [four-deploy cross-Worker transfer](https://edgetunnel-b2h.pages.dev/durable-objects/reference/durable-objects-migrations/#transfer-a-durable-object-class-between-workers) without runtime errors during the rollout window.
  * **Cross-Worker safety.** When you delete or rename a class, Cloudflare lists every other Worker in your account whose bindings still reference the namespace, so you can redeploy them before the change goes live.  
Existing Workers using the legacy [migrations](https://edgetunnel-b2h.pages.dev/durable-objects/reference/durable-object-class-migrations-legacy/) array continue to work unchanged. To move to `exports`, refer to the [migration guide](https://edgetunnel-b2h.pages.dev/durable-objects/reference/durable-objects-migrations/#migrate-from-the-legacy-migrations-flow). `exports` and `migrations` are mutually exclusive within a single Worker.  
For the full reference, refer to [Durable Object class exports](https://edgetunnel-b2h.pages.dev/durable-objects/reference/durable-objects-migrations/).

Jul 03, 2026
1. ### [Simpler runtime types with @cloudflare/workers-types v5](https://edgetunnel-b2h.pages.dev/changelog/post/2026-07-03-workers-types-v5/)  
[ Workers ](https://edgetunnel-b2h.pages.dev/workers/)  
We have released version 5 of [@cloudflare/workers-types ↗](https://www.npmjs.com/package/@cloudflare/workers-types). This release simplifies the package to expose only the latest runtime types.  
We still recommend that you generate types for your Worker using [wrangler types](https://edgetunnel-b2h.pages.dev/workers/wrangler/commands/general/#types), but if you want to use the package directly, you can install it with your package manager of choice:  
 npm  yarn  pnpm  bun  
```  
npm i -D @cloudflare/workers-types@latest  
```  
```  
yarn add -D @cloudflare/workers-types@latest  
```  
```  
pnpm add -D @cloudflare/workers-types@latest  
```  
```  
bun add -d @cloudflare/workers-types@latest  
```  
The package now exposes two entrypoints:

  * `@cloudflare/workers-types` reflects the latest compatibility date, using the latest stable compatibility flags.
  * `@cloudflare/workers-types/experimental` reflects APIs behind experimental compatibility flags.  
The dated entrypoints, such as `@cloudflare/workers-types/2022-11-30` and `@cloudflare/workers-types/2023-03-01`, are removed. With runtime type generation in [Wrangler v4](https://edgetunnel-b2h.pages.dev/workers/wrangler/), you can generate these with the `wrangler types` command to create types locked to your Worker's compatibility date.  
For more information, refer to [TypeScript language support](https://edgetunnel-b2h.pages.dev/workers/languages/typescript/).

Jul 02, 2026
1. ### [Work across multiple accounts with Wrangler auth profiles](https://edgetunnel-b2h.pages.dev/changelog/post/2026-07-02-wrangler-auth-profiles/)  
[ Workers ](https://edgetunnel-b2h.pages.dev/workers/)  
[Wrangler CLI](https://edgetunnel-b2h.pages.dev/workers/wrangler/) now supports auth profiles: named logins that you scope to specific Cloudflare accounts and switch between automatically, based on the directory you are working in.  
A profile is a named OAuth login bound to a directory. Commands run in that directory, and its subdirectories, use the matching account — so you can move between accounts without re-running `wrangler login`.  
Use profiles to keep a separate login for each client when working at an agency, or to separate staging and production into different accounts. Pair a profile with an `account_id` in your [Wrangler configuration file](https://edgetunnel-b2h.pages.dev/workers/wrangler/configuration/) so a command cannot reach the wrong account.  
```sh  
# Create a profile for each account, choosing which accounts it can reach  
wrangler auth create client-a  
wrangler auth activate client-a ~/clients/client-a  
wrangler auth create client-b  
wrangler auth activate client-b ~/clients/client-b  
```  
Use the `--profile` flag to run a single command with a specific profile:  
```sh  
wrangler deploy --profile personal  
```  
In CI and other automated environments, `CLOUDFLARE_API_TOKEN` still takes precedence over all profiles.  
For setup, the resolution order, and the full command reference, refer to [Authentication profiles](https://edgetunnel-b2h.pages.dev/workers/wrangler/profiles/).

Jun 30, 2026
1. ### [Track memory usage for Workers and Durable Objects in the dashboard](https://edgetunnel-b2h.pages.dev/changelog/post/2026-06-30-memory-usage-metrics/)  
[ Workers ](https://edgetunnel-b2h.pages.dev/workers/)[ Durable Objects ](https://edgetunnel-b2h.pages.dev/durable-objects/)  
You can now monitor how much memory your [Workers](https://edgetunnel-b2h.pages.dev/workers/) and [Durable Objects](https://edgetunnel-b2h.pages.dev/durable-objects/) consume across invocations with the new **Memory Usage** chart in the Workers Metrics tab, broken down by P50, P90, P99, and P999 percentiles.  
![Memory usage chart showing P50, P90, P99, and P999 percentiles with deployment markers](https://edgetunnel-b2h.pages.dev/_astro/2026-06-26-memory-usage.B20y2uNp_2e7cPL.webp)  
Memory usage measures the V8 [isolate](https://edgetunnel-b2h.pages.dev/workers/reference/how-workers-works/#isolates) memory at the time of each invocation, subject to the [128 MB per-isolate limit](https://edgetunnel-b2h.pages.dev/workers/platform/limits/#memory) — a single isolate can handle many concurrent requests and shares memory across them.  
Use the Memory Usage chart to:

  * **Track memory trends** — Spot gradual increases that may indicate a memory leak before they cause `Exceeded Memory` errors.
  * **Correlate with deployments** — Deployment markers on the chart help you identify whether a new version introduced a memory regression.
  * **Right-size your Worker** — Understand your baseline memory footprint and how much headroom you have before hitting the 128 MB limit.  
For Durable Objects, memory usage reflects the in-memory state an object holds (class properties, caches, active WebSocket connections), which persists across invocations until the object is [hibernated or evicted](https://edgetunnel-b2h.pages.dev/durable-objects/concepts/durable-object-lifecycle/). This state is not preserved across eviction, hibernation, or a crash, so persist anything important to [storage](https://edgetunnel-b2h.pages.dev/durable-objects/best-practices/access-durable-objects-storage/).  
To view memory usage, open the **Metrics** tab for your [Worker ↗](https://dash.cloudflare.com/?to=/:account/workers/services/view/:worker/production/metrics) or [Durable Object namespace ↗](https://dash.cloudflare.com/?to=/:account/workers/durable-objects). For Durable Objects, you can filter by DO ID or name to drill down into memory usage for a specific object. You can also query memory usage programmatically via the [GraphQL Analytics API](https://edgetunnel-b2h.pages.dev/analytics/graphql-api/tutorials/querying-workers-metrics/) using the `workersInvocationsAdaptive` dataset — the `quantiles.memoryUsageBytesP50` through `quantiles.memoryUsageBytesP999` fields return percentile values in bytes.  
For local memory debugging, you can also [profile memory with DevTools](https://edgetunnel-b2h.pages.dev/workers/observability/dev-tools/memory-usage/) to take heap snapshots and identify specific objects causing high memory usage.

Jun 28, 2026
1. ### [Workers fetch requests now support cf.vary](https://edgetunnel-b2h.pages.dev/changelog/post/2026-06-28-cf-vary-request-option/)  
[ Workers ](https://edgetunnel-b2h.pages.dev/workers/)  
Workers `fetch()` requests now support the `cf.vary` request option. Use `cf.vary` to control how Cloudflare caches origin responses with a `Vary` header for a single subrequest.

  * [  JavaScript ](#tab-panel-2989)
  * [  TypeScript ](#tab-panel-2990)

**src/index.js**  
```js  
export default {  
  async fetch(request) {  
    return fetch(request, {  
      cf: {  
        vary: {  
          default: { action: "bypass" },  
          headers: {  
            accept: {  
              action: "normalize",  
              media_types: ["text/html", "application/json"],  
            },  
            "accept-language": {  
              action: "normalize",  
              languages: ["en", "fr", "de"],  
            },  
          },  
        },  
      },  
    });  
  },  
};  
```

**src/index.ts**  
```ts  
export default {  
  async fetch(request): Promise<Response> {  
    return fetch(request, {  
      cf: {  
        vary: {  
          default: { action: "bypass" },  
          headers: {  
            accept: {  
              action: "normalize",  
              media_types: ["text/html", "application/json"],  
            },  
            "accept-language": {  
              action: "normalize",  
              languages: ["en", "fr", "de"],  
            },  
          },  
        },  
      },  
    });  
  },  
} satisfies ExportedHandler;  
```  
For more information, refer to [cf.vary](https://edgetunnel-b2h.pages.dev/workers/runtime-apis/request/#the-cfvary-property).

Jun 26, 2026
1. ### [Agents SDK adds background sub-agents and a unified turn entry point](https://edgetunnel-b2h.pages.dev/changelog/post/2026-06-26-agents-sdk-v0170/)  
[ Agents ](https://edgetunnel-b2h.pages.dev/agents/)[ Workers ](https://edgetunnel-b2h.pages.dev/workers/)  
The latest release of the [Agents SDK ↗](https://github.com/cloudflare/agents) makes it easier to run long work in the background, drive turns through one entry point, and keep chat agents working through deploys, evictions, and reconnects.  
This release adds first-class detached (background) sub-agent runs with live progress and durable milestones, a single `runTurn` turn-admission entry point, and a large round of recovery and reliability fixes that continue converging `@cloudflare/think` and `@cloudflare/ai-chat` onto one model.  
#### Background sub-agents with progress and milestones  
`runAgentTool` can now dispatch a sub-agent without blocking the calling turn. A detached run returns a handle immediately and is owned by a durable, eviction-surviving backbone instead of being abandoned when the dispatching turn ends.

  * [  JavaScript ](#tab-panel-2983)
  * [  TypeScript ](#tab-panel-2984)

**JavaScript**  
```js  
class OrdersAgent extends Think {  
  async startImport(input) {  
    // Fire-and-forget, or wire a durable completion callback  
    // (by method name, like schedule()):  
    await this.runAgentTool(ImportAgent, {  
      input,  
      detached: { onFinish: "onImportDone", maxBudgetMs: 60 * 60 * 1000 },  
    });  
  }  
  // result.status: "completed" | "error" | "aborted" | "interrupted"  
  async onImportDone(run, result) {}  
}  
```

**TypeScript**  
```ts  
class OrdersAgent extends Think {  
  async startImport(input) {  
    // Fire-and-forget, or wire a durable completion callback  
    // (by method name, like schedule()):  
    await this.runAgentTool(ImportAgent, {  
      input,  
      detached: { onFinish: "onImportDone", maxBudgetMs: 60 * 60 * 1000 },  
    });  
  }  
  // result.status: "completed" | "error" | "aborted" | "interrupted"  
  async onImportDone(run, result) {}  
}  
```  
Highlights:

  * **Durable, exactly-once-on-the-happy-path completion** via a warm fast path plus a self-scheduling reconcile backbone that survives eviction and deploys.
  * **Bounded.** An absolute `maxBudgetMs` ceiling (default 24h) and `cancelAgentTool(runId)` keep abandoned runs from holding a concurrency slot forever.
  * **`detached: { notify: true }`** lets a finished background run inject a message back into the chat so the model reacts to the result — no hand-wired `onFinish` needed.  
Sub-agents can also report mid-run progress that rides their own turn stream back to the parent's connected clients:

  * [  JavaScript ](#tab-panel-2979)
  * [  TypeScript ](#tab-panel-2980)

**JavaScript**  
```js  
// Inside the child sub-agent:  
await this.reportProgress({  
  fraction: 0.6,  
  phase: "deploying",  
  message: "Generating menu page…",  
});  
```

**TypeScript**  
```ts  
// Inside the child sub-agent:  
await this.reportProgress({  
  fraction: 0.6,  
  phase: "deploying",  
  message: "Generating menu page…",  
});  
```  
Progress surfaces on `AgentToolRunState.progress` via `useAgentToolEvents`, so a background-runs tray can render a live bar without drilling in, and the latest snapshot is persisted for inspection after eviction. Naming a `milestone` promotes a signal to a durable, replayable row, and `detached: { onMilestones }` can surface a milestone as a synthetic chat message (`"narrate"` for a cheap status line, or `"react"` to drive a model turn).  
#### One entry point for turns: `runTurn`  
`@cloudflare/think` adds a public `runTurn(options)` facade that unifies turn admission behind a single `mode`:

  * [  JavaScript ](#tab-panel-2977)
  * [  TypeScript ](#tab-panel-2978)

**JavaScript**  
```js  
await this.runTurn({ mode: "wait", messages }); // saveMessages / continueLastTurn  
await this.runTurn({ mode: "submit", messages }); // durable submitMessages  
await this.runTurn({ mode: "stream", messages }); // chat()  
```

**TypeScript**  
```ts  
await this.runTurn({ mode: "wait", messages }); // saveMessages / continueLastTurn  
await this.runTurn({ mode: "submit", messages }); // durable submitMessages  
await this.runTurn({ mode: "stream", messages }); // chat()  
```  
`stream` mode accepts array and function inputs to match `wait` mode, and all entry points now route through a shared internal admission path that throws a clear error on nested blocking admissions that previously could deadlock.  
#### Recovery and reliability  
A large part of this release continues hardening recovery and converging `@cloudflare/think` and `@cloudflare/ai-chat` onto one model:

  * **Stream stall watchdog.** `AIChatAgent` can detect and recover from a hung model/transport stream via the opt-in `chatStreamStallTimeoutMs` watchdog. With `chatRecovery` enabled the stall routes into the same bounded-recovery machinery a deploy or eviction uses; otherwise it surfaces as a terminal stream error so the spinner clears.
  * **Interrupted tool-call repair.** `AIChatAgent` now repairs a transcript with a dead server-tool call before re-entering inference (parity with `@cloudflare/think`), so a recovered turn no longer fails with `AI_MissingToolResultsError`. An overridable `repairInterruptedToolPart(part)` hook lets apps customize the repaired shape.
  * **Stuck status after reconnect.** Fixed AI SDK `status` getting stuck when a reconnect races a turn that has been accepted but has not started streaming yet, so the UI now renders the in-flight turn instead of settling on `ready`.
  * **Live "recovering…" on connect.** `AIChatAgent` now replays the recovering status to a client that connects mid-recovery, so `useAgentChat`'s `isRecovering` reflects in-progress recovery immediately instead of appearing frozen.
  * **Terminal connection failures.** The client stops reconnecting on terminal WebSocket close events and exposes them via `connectionError` / `onConnectionError` on `AgentClient`, `useAgent`, and `useAgentChat`.
  * **Agent-tool child recovery.** A healthy long-running sub-agent run is no longer abandoned as `interrupted` after a deploy (both `@cloudflare/think` and `AIChatAgent`).
  * **Workflows from sub-agent facets.** Agent Workflows can now start from sub-agent facets, with callbacks and Workflow RPC routed back to the originating facet.
  * Plus forward-progress crediting convergence, broadcast-first give-up ordering, an event-driven auto-continuation barrier, and structured row-size compaction in `AIChatAgent`.  
#### Other improvements

  * **Shared chat React core.** A new `agents/chat/react` entry exposes `useAgentChat`, transport helpers, and shared wire types, with `syncMessagesToServer` for server-authoritative transcript storage. `@cloudflare/think/react` and `@cloudflare/ai-chat/react` are now thin wrappers over it.
  * **Optional `ai` peer.** The root `agents` and `@cloudflare/codemode` runtimes no longer reference AI SDK types, so they bundle without `ai` / `zod` installed; AI-specific entry points still require the peer when imported. `just-bash` likewise moves to an optional peer used only by the skills bash runner.
  * **Code Mode.** The default `DynamicWorkerExecutor` timeout increases from 30s to 60s, executions now dispose the dynamically-loaded Worker and its RPC stub after each run (fixing a flaky isolate-shutdown assertion), connector imports are cleaned up, and the outer MCP tool-call context is passed to `openApiMcpServer` request callbacks.
  * **Voice.** Voice turns now support AI SDK `fullStream` responses (and warn when `textStream` is used).
  * **MCP.** `McpAgent` server-to-client requests can now be sent from callbacks that do not inherit the agent's async context, including callbacks reached through Worker Loader RPC.
  * **Experimental: server actions and channels.** This release lays groundwork for guarded server actions (`action()` / `getActions()` with a durable replay ledger and approvals) and a unified channels surface (`configureChannels()`, `deliverNotice()`). Both are experimental and their APIs may change, so we don't recommend depending on them yet.  
#### Upgrade  
To update to the latest version:  
 npm  yarn  pnpm  bun  
```  
npm i agents@latest @cloudflare/think@latest @cloudflare/ai-chat@latest @cloudflare/codemode@latest @cloudflare/voice@latest  
```  
```  
yarn add agents@latest @cloudflare/think@latest @cloudflare/ai-chat@latest @cloudflare/codemode@latest @cloudflare/voice@latest  
```  
```  
pnpm add agents@latest @cloudflare/think@latest @cloudflare/ai-chat@latest @cloudflare/codemode@latest @cloudflare/voice@latest  
```  
```  
bun add agents@latest @cloudflare/think@latest @cloudflare/ai-chat@latest @cloudflare/codemode@latest @cloudflare/voice@latest  
```  
Refer to the [Think documentation](https://edgetunnel-b2h.pages.dev/agents/harnesses/think/), [Code Mode documentation](https://edgetunnel-b2h.pages.dev/agents/tools/codemode/), and [Agents documentation](https://edgetunnel-b2h.pages.dev/agents/) for more information.

Jun 26, 2026
1. ### [New \`us\` jurisdiction for Durable Objects](https://edgetunnel-b2h.pages.dev/changelog/post/2026-06-26-durable-objects-us-jurisdiction/)  
[ Durable Objects ](https://edgetunnel-b2h.pages.dev/durable-objects/)[ Workers ](https://edgetunnel-b2h.pages.dev/workers/)  
Durable Objects now supports a `us` [jurisdiction](https://edgetunnel-b2h.pages.dev/durable-objects/reference/data-location/#restrict-durable-objects-to-a-jurisdiction), letting you create Durable Objects that only run and store data within the United States. Use the `us` jurisdiction when you need to keep a Durable Object's compute and storage inside the United States to meet data residency requirements.  
Create a namespace restricted to the `us` jurisdiction the same way as any other jurisdiction:

**JavaScript**  
```js  
// Worker  
export default {  
  async fetch(request, env) {  
    const usSubnamespace = env.MY_DURABLE_OBJECT.jurisdiction("us");  
    const stub = usSubnamespace.getByName("general");  
    return stub.fetch(request);  
  },  
};  
```  
Workers may still access Durable Objects constrained to the `us` jurisdiction from anywhere in the world. The jurisdiction constraint only controls where the Durable Object itself runs and persists data.  
For the full list of supported jurisdictions, refer to [Data location — Restrict Durable Objects to a jurisdiction](https://edgetunnel-b2h.pages.dev/durable-objects/reference/data-location/#restrict-durable-objects-to-a-jurisdiction).

Jun 25, 2026
1. ### [Test Durable Object eviction with new cloudflare:test helpers](https://edgetunnel-b2h.pages.dev/changelog/post/2026-06-25-durable-object-eviction-test-helpers/)  
[ Durable Objects ](https://edgetunnel-b2h.pages.dev/durable-objects/)[ Workers ](https://edgetunnel-b2h.pages.dev/workers/)  
The `@cloudflare/vitest-pool-workers` package now includes `evictDurableObject` and `evictAllDurableObjects` test helpers, exported from `cloudflare:test`.  
These helpers let you test how a Durable Object behaves across evictions, simulating the production lifecycle where an idle Durable Object can be evicted from memory.  
For more context, refer to [Lifecycle of a Durable Object](https://edgetunnel-b2h.pages.dev/durable-objects/concepts/durable-object-lifecycle/).

**TypeScript**  
```ts  
import { evictDurableObject, evictAllDurableObjects } from "cloudflare:test";  
import { env } from "cloudflare:workers";  
const id = env.COUNTER.idFromName("my-counter");  
const stub = env.COUNTER.get(id);  
// Evict the Durable Object instance pointed to by a specific stub  
await evictDurableObject(stub);  
// Close WebSockets instead of hibernating them  
await evictDurableObject(stub, { webSockets: "close" });  
// Evict all currently-running Durable Objects in evictable namespaces  
await evictAllDurableObjects();  
```  
These helpers are available in `@cloudflare/vitest-pool-workers@0.16.20` and later.  
Learn more in the [Test APIs reference](https://edgetunnel-b2h.pages.dev/workers/testing/vitest-integration/test-apis/#durable-objects) and the [Testing Durable Objects guide](https://edgetunnel-b2h.pages.dev/durable-objects/examples/testing-with-durable-objects/#testing-eviction).

Jun 19, 2026
1. ### [New Asia-Pacific location hints: apac-ne and apac-se](https://edgetunnel-b2h.pages.dev/changelog/post/2026-06-19-apac-ne-apac-se-location-hints/)  
[ Durable Objects ](https://edgetunnel-b2h.pages.dev/durable-objects/)[ Workers ](https://edgetunnel-b2h.pages.dev/workers/)  
Durable Objects now supports two new location hints for Asia-Pacific: `apac-ne` (Northeast Asia-Pacific) and `apac-se` (Southeast Asia-Pacific). Use `apac-ne` or `apac-se` when you want finer-grained placement within Asia-Pacific rather than the broader `apac` hint.  
Use the new hints the same way as any other `locationHint`:

**JavaScript**  
```js  
// Northeast Asia-Pacific (Japan, Korea, etc.)  
const stubNE = env.MY_DURABLE_OBJECT.get(id, { locationHint: "apac-ne" });  
// Southeast Asia-Pacific (Singapore, Indonesia, etc.)  
const stubSE = env.MY_DURABLE_OBJECT.get(id, { locationHint: "apac-se" });  
```  
If your users are spread across all of Asia-Pacific, the existing `apac` hint remains the right choice. Only reach for `apac-ne` or `apac-se` when your traffic is clearly concentrated in one sub-region and you want to minimize round-trip time to that audience. The default behavior and what we generally recommended is not adding a location hint unless absolutely needed, this will create the Durable Object as close to the initializing request as possible to reduce latency.  
As with all location hints, these are best-effort suggestions. Cloudflare will place the Durable Object in a nearby data center, not necessarily the exact hinted location.  
For the full list of supported hints, refer to [Data location — Provide a location hint](https://edgetunnel-b2h.pages.dev/durable-objects/reference/data-location/#provide-a-location-hint).

Jun 19, 2026
1. ### [Temporary accounts for AI agent deployments](https://edgetunnel-b2h.pages.dev/changelog/post/2026-06-19-temporary-accounts-for-agents/)  
[ Workers ](https://edgetunnel-b2h.pages.dev/workers/)  
AI agents can now deploy Workers to Cloudflare without first requiring a user to sign up, open a browser-based OAuth flow, click through the dashboard, or create an API token. When an agent tries to deploy without Cloudflare credentials, Wrangler can tell it to rerun with `--temporary`, then deploy the Worker to a temporary preview account.  
To try this with your agent, update to Wrangler 4.102.0 or later, make sure you are logged out (`wrangler logout`), and then ask your agent to build something and deploy it to Cloudflare. The agent should follow Wrangler's output and deploy using the `--temporary` flag.  
![Diagram showing an AI agent deploying, verifying, and redeploying a Worker to a temporary account, then claiming it after authentication and moving it to a permanent account](https://edgetunnel-b2h.pages.dev/_astro/claim-deployments-flow.Co0tUHG4_g1dGj.webp)  
```sh  
wrangler deploy --temporary  
```  
The temporary deployment stays live for 60 minutes. During that window, the agent can verify the Worker, redeploy changes, and return both the live Worker URL and claim URL. Opening the claim URL lets you sign in to or create a Cloudflare account and make the temporary account permanent.  
Temporary preview accounts currently support a limited set of products, including Workers, Workers Static Assets, Workers KV, D1, Durable Objects, Hyperdrive, Queues, and SSL/TLS certificates. For supported products, limits, and claim behavior, refer to [Claim deployments (temporary accounts)](https://edgetunnel-b2h.pages.dev/workers/platform/claim-deployments/).  
For more context, refer to [Temporary Cloudflare Accounts for Agents ↗](https://blog.cloudflare.com/temporary-accounts/).

Jun 18, 2026
1. ### [Create PlanetScale Postgres and MySQL databases, billed to your Cloudflare account](https://edgetunnel-b2h.pages.dev/changelog/post/2026-06-18-planetscale-databases-cloudflare-billing/)  
[ Hyperdrive ](https://edgetunnel-b2h.pages.dev/hyperdrive/)[ Workers ](https://edgetunnel-b2h.pages.dev/workers/)  
You can create PlanetScale Postgres and MySQL databases from Cloudflare and bill PlanetScale database usage through your Cloudflare account as a pay-as-you-go customer. Cloudflare contract customers will be able to add PlanetScale usage to their contract in July so reach out to your Cloudflare account team if interested.  
Create a PlanetScale database from the Cloudflare dashboard to check out globally distributed Workers optimized for regional data access.  
[ Go to **Create a PlanetScale database** ](https://dash.cloudflare.com/?to=/:account/workers/hyperdrive?modal=1&type=planetscale&step=1) ![Request flow from a user to Workers, Hyperdrive caches, connection pools, and PlanetScale.](https://edgetunnel-b2h.pages.dev/_astro/planetscale-request-flow.CchJ2m4p_1fTg6l.svg)  
PlanetScale databases created from Cloudflare work with [Workers](https://edgetunnel-b2h.pages.dev/workers/) through [Hyperdrive](https://edgetunnel-b2h.pages.dev/hyperdrive/). Hyperdrive manages database connection pools and query caching, so you can use PlanetScale as a centralized relational database for Workers applications without changing your database drivers, object-relational mapping (ORM) libraries, or SQL tooling.  
PlanetScale usage appears on your Cloudflare invoice each billing period as a dollar total at PlanetScale's standard [pricing ↗](https://planetscale.com/pricing). You can introspect per-database billing usage via PlanetScale's [dashboard ↗](https://planetscale.com/docs/billing#organization-usage-and-billing-page).  
When you create a PlanetScale database from the Cloudflare dashboard, you receive the same PlanetScale developer experience, including development branches, query insights, and Model Context Protocol (MCP) server support for agents.  
To get started, refer to [PlanetScale Postgres and MySQL with Hyperdrive](https://edgetunnel-b2h.pages.dev/hyperdrive/planetscale/).

Jun 16, 2026
1. ### [Agents SDK improves browser automation, code execution, and recovery](https://edgetunnel-b2h.pages.dev/changelog/post/2026-06-16-agents-sdk-v0161/)  
[ Agents ](https://edgetunnel-b2h.pages.dev/agents/)[ Workers ](https://edgetunnel-b2h.pages.dev/workers/)  
The latest release of the [Agents SDK ↗](https://github.com/cloudflare/agents) makes it easier to build agents that can safely interact with real systems and keep working through interruptions.  
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.  
#### Safer browser automation  
Agents can now use [Browser Run](https://edgetunnel-b2h.pages.dev/browser-run/) through a single durable `browser_execute` 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.

  * [  JavaScript ](#tab-panel-2981)
  * [  TypeScript ](#tab-panel-2982)

**JavaScript**  
```js  
const browserTools = createBrowserTools({  
  ctx: this.ctx,  
  browser: this.env.BROWSER,  
  loader: this.env.LOADER,  
  session: { mode: "dynamic" },  
});  
```

**TypeScript**  
```ts  
const browserTools = createBrowserTools({  
  ctx: this.ctx,  
  browser: this.env.BROWSER,  
  loader: this.env.LOADER,  
  session: { mode: "dynamic" },  
});  
```  
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.  
The browser tools also add Live View URLs, optional session recording, and quick actions such as `browser_markdown`, `browser_extract`, `browser_links`, and `browser_scrape` for one-shot browsing tasks.  
#### Resumable code execution with approvals  
Code Mode now uses `createCodemodeRuntime`, connectors, and a durable execution log. This lets you give a model one `codemode` 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.

  * [  JavaScript ](#tab-panel-2991)
  * [  TypeScript ](#tab-panel-2992)

**JavaScript**  
```js  
const runtime = createCodemodeRuntime({  
  ctx: this.ctx,  
  executor: new DynamicWorkerExecutor({ loader: this.env.LOADER }),  
  connectors: [new GithubConnector(this.ctx, this.env, connection)],  
});  
const result = streamText({  
  model,  
  messages,  
  tools: { codemode: runtime.tool() },  
});  
```

**TypeScript**  
```ts  
const runtime = createCodemodeRuntime({  
  ctx: this.ctx,  
  executor: new DynamicWorkerExecutor({ loader: this.env.LOADER }),  
  connectors: [new GithubConnector(this.ctx, this.env, connection)],  
});  
const result = streamText({  
  model,  
  messages,  
  tools: { codemode: runtime.tool() },  
});  
```  
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.  
#### Better Think delegation  
Think sub-agents can now use client-defined tools over the RPC `chat()` path. A parent agent can pass tool schemas with `clientTools` and resolve tool calls through `onClientToolCall`. This lets delegated agents use caller-provided capabilities without requiring a browser WebSocket.

  * [  JavaScript ](#tab-panel-2993)
  * [  TypeScript ](#tab-panel-2994)

**JavaScript**  
```js  
await child.chat(message, callback, {  
  signal,  
  clientTools: [  
    {  
      name: "get_user_timezone",  
      description: "Get the caller's timezone",  
      parameters: { type: "object" },  
    },  
  ],  
  onClientToolCall: async ({ toolName, input }) => {  
    return runClientTool(toolName, input);  
  },  
});  
```

**TypeScript**  
```ts  
await child.chat(message, callback, {  
  signal,  
  clientTools: [  
    {  
      name: "get_user_timezone",  
      description: "Get the caller's timezone",  
      parameters: { type: "object" },  
    },  
  ],  
  onClientToolCall: async ({ toolName, input }) => {  
    return runClientTool(toolName, input);  
  },  
});  
```  
Think Workflows also improve `step.prompt()`. 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.  
The unified Think execute tool can also include `cdp.*` browser capabilities alongside `state.*` and `tools.*` when Browser Run is bound.  
#### Voice output device selection  
Voice clients can route assistant audio to a specific output device. Use `outputDeviceId` with `useVoiceAgent`, or call `client.setOutputDevice()` from the framework-agnostic client.

  * [  JavaScript ](#tab-panel-2985)
  * [  TypeScript ](#tab-panel-2986)

**JavaScript**  
```js  
const voice = useVoiceAgent({  
  agent: "MyVoiceAgent",  
  outputDeviceId: selectedSpeakerId,  
});  
```

**TypeScript**  
```ts  
const voice = useVoiceAgent({  
  agent: "MyVoiceAgent",  
  outputDeviceId: selectedSpeakerId,  
});  
```  
Browsers without speaker-selection support continue playing through the default output device and report a non-fatal `outputDeviceError`.  
#### Reliability fixes  
This release includes several fixes for production agents:

  * `useAgent` and `AgentClient` handle WebSocket replacement more reliably during reconnects and configuration changes.
  * Chat stream replay is more reliable after reconnects, deploys, and provider errors.
  * Fiber recovery continues across multi-pass scans and backs off when recovery hooks keep failing.
  * Agent teardown continues even when the request that started teardown is canceled.
  * Large session histories use byte-budgeted reads to reduce memory pressure during startup.  
#### Upgrade  
To update to the latest version:  
 npm  yarn  pnpm  bun  
```  
npm i agents@latest @cloudflare/think@latest @cloudflare/codemode@latest @cloudflare/ai-chat@latest @cloudflare/voice@latest  
```  
```  
yarn add agents@latest @cloudflare/think@latest @cloudflare/codemode@latest @cloudflare/ai-chat@latest @cloudflare/voice@latest  
```  
```  
pnpm add agents@latest @cloudflare/think@latest @cloudflare/codemode@latest @cloudflare/ai-chat@latest @cloudflare/voice@latest  
```  
```  
bun add agents@latest @cloudflare/think@latest @cloudflare/codemode@latest @cloudflare/ai-chat@latest @cloudflare/voice@latest  
```  
Refer to the [Code Mode documentation](https://edgetunnel-b2h.pages.dev/agents/tools/codemode/), [Browser tools documentation](https://edgetunnel-b2h.pages.dev/agents/tools/browser/), [Think tools documentation](https://edgetunnel-b2h.pages.dev/agents/harnesses/think/tools/), and [Voice documentation](https://edgetunnel-b2h.pages.dev/agents/communication-channels/voice/) for more information.

Jun 16, 2026
1. ### [Introducing GLM-5.2 on Workers AI](https://edgetunnel-b2h.pages.dev/changelog/post/2026-06-16-glm-52-workers-ai/)  
[ Workers ](https://edgetunnel-b2h.pages.dev/workers/)[ Agents ](https://edgetunnel-b2h.pages.dev/agents/)[ Workers AI ](https://edgetunnel-b2h.pages.dev/workers-ai/)  
We are excited to announce **GLM-5.2** on Workers AI, Z.ai's flagship agentic coding model.  
[@cf/zai-org/glm-5.2](https://edgetunnel-b2h.pages.dev/workers-ai/models/glm-5.2/) is a text generation model built for agentic coding workflows. With function calling and reasoning support, it can handle long codebases, multi-step planning, and tool-augmented agents.

**Key features and use cases:**

  * **Agentic coding**: Designed for autonomous coding tasks, long-horizon planning, and complex software engineering workflows
  * **Large context window**: GLM-5.2 supports up to a 1,048,576 token context window. Workers AI is launching the model with a 262,144 token context window and plans to increase this in the future
  * **Function calling**: Build agents that invoke tools and APIs across multiple conversation turns
  * **Reasoning**: Tackles complex problem-solving and step-by-step reasoning tasks  
Use GLM-5.2 through the [Workers AI binding](https://edgetunnel-b2h.pages.dev/workers-ai/configuration/bindings/) (`env.AI.run()`), the REST API at `/run` or `/v1/chat/completions`, or [AI Gateway](https://edgetunnel-b2h.pages.dev/ai-gateway/).  
Pricing is available on the [model page](https://edgetunnel-b2h.pages.dev/workers-ai/models/glm-5.2/) or [pricing page](https://edgetunnel-b2h.pages.dev/workers-ai/platform/pricing/).

Jun 16, 2026
1. ### [Workers tracing now supports custom spans](https://edgetunnel-b2h.pages.dev/changelog/post/2026-06-16-custom-spans/)  
[ Workers ](https://edgetunnel-b2h.pages.dev/workers/)  
You can now create custom trace spans in your Workers code using `tracing.enterSpan()`. Custom spans appear alongside the automatic platform instrumentation (fetch calls, KV reads, D1 queries, and other platform operations) in your traces and OpenTelemetry exports, with correct parent-child nesting.  
The API is available via `import { tracing } from "cloudflare:workers"` or through the handler context as `ctx.tracing`:

**TypeScript**  
```ts  
import { tracing } from "cloudflare:workers";  
export default {  
  async fetch(request, env, ctx) {  
    return tracing.enterSpan("handleRequest", async (span) => {  
      span.setAttribute("url.path", new URL(request.url).pathname);  
      const data = await env.MY_KV.get("key");  
      return new Response(data);  
    });  
  },  
};  
```  
Spans nest automatically based on the JavaScript async context, and are auto-ended when the callback returns or its returned promise settles. The `Span` object provides `setAttribute(key, value)` for attaching metadata and an `isTraced` property to check whether the current request is being sampled.  
![Trace waterfall showing custom spans nested alongside automatic KV and fetch instrumentation](https://edgetunnel-b2h.pages.dev/_astro/wobs_custom_spans_screenshot.B-hsHjyv_ZGVlIY.webp)  
[Tracing must be enabled](https://edgetunnel-b2h.pages.dev/workers/observability/traces/#how-to-enable-tracing) in your Wrangler configuration for spans to be recorded.  
For full API details and examples, refer to [Custom spans](https://edgetunnel-b2h.pages.dev/workers/observability/traces/custom-spans/).

Jun 12, 2026
1. ### [Filter Durable Objects metrics by object ID or name](https://edgetunnel-b2h.pages.dev/changelog/post/2026-06-12-durable-objects-metrics-filter-by-id-name/)  
[ Durable Objects ](https://edgetunnel-b2h.pages.dev/durable-objects/)[ Workers ](https://edgetunnel-b2h.pages.dev/workers/)  
You can now filter the **Metrics** tab for a Durable Objects namespace by an individual Durable Object's [ID](https://edgetunnel-b2h.pages.dev/durable-objects/api/id/) or [name](https://edgetunnel-b2h.pages.dev/durable-objects/api/id/#name) in the Cloudflare dashboard. Previously, metrics charts only showed aggregate, namespace-level data, making it difficult to isolate the behavior of a specific object.  
[ Go to **Durable Objects** ](https://dash.cloudflare.com/?to=/:account/workers/durable-objects) ![The Durable Objects Metrics tab filtered to a single object by ID, showing per-object requests and errors by invocation status.](https://edgetunnel-b2h.pages.dev/_astro/durable-objects-metrics-dashboard.BFZTyhWU_Z2e46Sb.webp)  
Start typing an ID or name into the filter and select a match from the autocomplete dropdown. The autocomplete only shows objects with invocations during the selected time range, so an object that does not appear has not been invoked in that window. This does not necessarily mean the object has been deleted. Every chart on the page updates to reflect only the selected object. This makes it easier to identify and investigate a single Durable Object when debugging a high-traffic object, an error spike, or unexpected storage usage. Clear the filter to return to namespace-level metrics.  
Metrics are powered by the [GraphQL Analytics API](https://edgetunnel-b2h.pages.dev/analytics/graphql-api/), so standard analytics behavior such as ingestion delay and [sampling](https://edgetunnel-b2h.pages.dev/analytics/faq/graphql-api-inconsistent-results/) applies.  
For more information, refer to [Metrics and analytics](https://edgetunnel-b2h.pages.dev/durable-objects/observability/metrics-and-analytics/).

Jun 11, 2026
1. ### [Track Dynamic Workers usage from the dashboard and GraphQL API](https://edgetunnel-b2h.pages.dev/changelog/post/2026-06-11-dynamic-workers-count/)  
[ Workers ](https://edgetunnel-b2h.pages.dev/workers/)  
![Dynamic Workers usage on the Workers overview page](https://edgetunnel-b2h.pages.dev/_astro/dynamic-workers-count.BcGsgQ0m_ZBdT2X.webp)  
Customers can now view the number of [Dynamic Workers](https://edgetunnel-b2h.pages.dev/dynamic-workers/) invoked during their billing period from the Workers overview page in the Cloudflare dashboard.  
This count reflects the number of Dynamic Workers that Cloudflare would bill for during the selected billing period. Dynamic Workers usage data only goes back to June 1, 2026.  
You can also query this count through the [GraphQL Analytics API](https://edgetunnel-b2h.pages.dev/analytics/graphql-api/) by using `workersInvocationsByOwnerAndScriptGroups` and selecting `distinctDynamicWorkerCount`:  
```graphql  
query getDynamicWorkersCount(  
  $accountTag: string!  
  $filter: AccountWorkersInvocationsByOwnerAndScriptGroupsFilter_InputObject  
) {  
  viewer {  
    accounts(filter: { accountTag: $accountTag }) {  
      workersInvocationsByOwnerAndScriptGroups(limit: 10000, filter: $filter) {  
        uniq {  
          distinctDynamicWorkerCount  
        }  
      }  
    }  
  }  
}  
```  
Use variables to set the account and billing-period date range:  
```json  
{  
  "accountTag": "<ACCOUNT_ID>",  
  "filter": {  
    "date_geq": "2026-06-01",  
    "date_leq": "2026-06-30"  
  }  
}  
```  
For more information, refer to [Dynamic Workers pricing](https://edgetunnel-b2h.pages.dev/dynamic-workers/pricing/).

Jun 04, 2026
1. ### [Billable usage and budget alerts now in product sidebars](https://edgetunnel-b2h.pages.dev/changelog/post/2026-06-04-billable-usage-product-sidebar/)  
[ Cloudflare Fundamentals ](https://edgetunnel-b2h.pages.dev/fundamentals/)[ Workers ](https://edgetunnel-b2h.pages.dev/workers/)[ D1 ](https://edgetunnel-b2h.pages.dev/d1/)[ R2 ](https://edgetunnel-b2h.pages.dev/r2/)[ KV ](https://edgetunnel-b2h.pages.dev/kv/)[ Queues ](https://edgetunnel-b2h.pages.dev/queues/)[ Vectorize ](https://edgetunnel-b2h.pages.dev/vectorize/)[ Durable Objects ](https://edgetunnel-b2h.pages.dev/durable-objects/)[ Containers ](https://edgetunnel-b2h.pages.dev/containers/)  
Pay-as-you-go customers can now view billable usage and create [budget alerts](https://edgetunnel-b2h.pages.dev/changelog/post/2026-04-13-billable-usage-dashboard-and-budget-alerts/) directly from the product overview pages for [Workers & Pages](https://edgetunnel-b2h.pages.dev/workers/), [D1](https://edgetunnel-b2h.pages.dev/d1/), [R2](https://edgetunnel-b2h.pages.dev/r2/), [Workers KV](https://edgetunnel-b2h.pages.dev/kv/), [Queues](https://edgetunnel-b2h.pages.dev/queues/), [Vectorize](https://edgetunnel-b2h.pages.dev/vectorize/), [Durable Objects](https://edgetunnel-b2h.pages.dev/durable-objects/), and [Containers](https://edgetunnel-b2h.pages.dev/containers/). A new sidebar widget shows current-period spend and the billing cycle date range, alongside a button to create a budget alert.  
The widget pulls from the same data as the [Billable Usage dashboard](https://edgetunnel-b2h.pages.dev/changelog/post/2026-04-13-billable-usage-dashboard-and-budget-alerts/) and aligns to your billing cycle (or the current day on Free plans), so the numbers match your invoice. Enterprise contract accounts are not yet supported.  
![Billable usage widget in the Durable Objects product sidebar showing current-period spend and a breakdown by service](https://edgetunnel-b2h.pages.dev/_astro/2026-06-04-billable-usage-product-sidebar.BUuIokn__ZAx1o6.webp)  
Selecting **Create budget alert** opens the budget alert flow inline so you can set a dollar threshold in the same place you are reviewing usage. Budget alerts apply to your total account-level spend across all products, not just the product page you create them from.  
For more information, refer to the [Usage-based billing documentation](https://edgetunnel-b2h.pages.dev/billing/).

Jun 04, 2026
1. ### [Pipeline binding configuration field renamed to stream](https://edgetunnel-b2h.pages.dev/changelog/post/2026-05-27-pipeline-binding-stream-field/)  
[ Pipelines ](https://edgetunnel-b2h.pages.dev/pipelines/)[ Workers ](https://edgetunnel-b2h.pages.dev/workers/)  
The `pipeline` field inside the `pipelines` binding configuration in your [Wrangler configuration file](https://edgetunnel-b2h.pages.dev/workers/wrangler/configuration/) has been renamed to `stream`. The old field is deprecated but still accepted.  
Update your configuration to use `stream` to avoid the deprecation warning.

**Before (deprecated):**

  * [  wrangler.jsonc ](#tab-panel-2973)
  * [  wrangler.toml ](#tab-panel-2974)

**JSONC**  
```jsonc  
{  
  "$schema": "./node_modules/wrangler/config-schema.json",  
  "pipelines": [  
    {  
      "binding": "MY_PIPELINE",  
      "pipeline": "<STREAM_ID>"  
    }  
  ]  
}  
```

**TOML**  
```toml  
[[pipelines]]  
binding = "MY_PIPELINE"  
pipeline = "<STREAM_ID>"  
```

**After:**

  * [  wrangler.jsonc ](#tab-panel-2975)
  * [  wrangler.toml ](#tab-panel-2976)

**JSONC**  
```jsonc  
{  
  "$schema": "./node_modules/wrangler/config-schema.json",  
  "pipelines": [  
    {  
      "binding": "MY_PIPELINE",  
      "stream": "<STREAM_ID>"  
    }  
  ]  
}  
```

**TOML**  
```toml  
[[pipelines]]  
binding = "MY_PIPELINE"  
stream = "<STREAM_ID>"  
```  
No other changes are required. The binding name, TypeScript types, and runtime API (`env.MY_PIPELINE.send(...)`) remain the same.  
For more information on configuring pipeline bindings, refer to [Writing to streams](https://edgetunnel-b2h.pages.dev/pipelines/streams/writing-to-streams/#configure-pipeline-binding).

Jun 03, 2026
1. ### [New Workers bulk secrets API endpoint](https://edgetunnel-b2h.pages.dev/changelog/post/2026-06-03-bulk-secrets-api/)  
[ Workers ](https://edgetunnel-b2h.pages.dev/workers/)  
You can now create, update, or delete multiple secrets for your Worker in a single request using the [bulk secrets endpoint](https://edgetunnel-b2h.pages.dev/api/resources/workers/subresources/scripts/subresources/secrets/methods/bulk%5Fupdate/).

  * Include a secret with a value to create or update.
  * Set a secret to `null` to delete.
  * Secrets not included in the request are left unchanged.  
The following example creates `API_KEY`, updates the already existing `DB_PASSWORD`, and deletes `OLD_SECRET`:  
```json  
{  
  "secrets": {  
    "API_KEY": { "type": "secret_text", "name": "API_KEY", "text": "my-api-key" },  
    "DB_PASSWORD": { "type": "secret_text", "name": "DB_PASSWORD", "text": "my-db-password" },  
    "OLD_SECRET": null  
  }  
}  
```  
You can do the same from the command line using [wrangler secret bulk](https://edgetunnel-b2h.pages.dev/workers/wrangler/commands/workers/#secret-bulk):  
```sh  
npx wrangler secret bulk < secrets.json  
```  
To delete a key, set its value to `null` in the JSON file. Deletion is not supported with `.env` files.  
Each request supports up to **100 total operations** (creates, updates, and deletes combined).

Jun 03, 2026
1. ### [Store Wrangler's OAuth credentials in your OS keychain](https://edgetunnel-b2h.pages.dev/changelog/post/2026-06-03-wrangler-keyring-credential-storage/)  
[ Workers ](https://edgetunnel-b2h.pages.dev/workers/)  
[Wrangler](https://edgetunnel-b2h.pages.dev/workers/wrangler/) can now store the OAuth credentials returned by `wrangler login` in an [AES-256-GCM ↗](https://en.wikipedia.org/wiki/Galois/Counter%5FMode)\-encrypted file, with the encryption key held in your operating system keychain. The default behavior is unchanged — credentials still live in a plaintext TOML file unless you opt in.  
To opt in, run:  
```sh  
npx wrangler login --use-keyring  
```  
The choice is persisted across Wrangler invocations. Opt back out with `npx wrangler login --no-use-keyring`, or override the preference for a single command with the `CLOUDFLARE_AUTH_USE_KEYRING` environment variable.  
`wrangler whoami` now reports where credentials are stored:  
```sh  
🔐 Credentials are stored in: Encrypted file (~/.config/.wrangler/config/default.enc) with key in macOS Keychain (service=wrangler, account=default)  
```  
Per-platform backends:

  * **macOS** uses the built-in Keychain via `/usr/bin/security`.
  * **Linux** uses [libsecret ↗](https://wiki.gnome.org/Projects/Libsecret) via the `secret-tool` CLI from the `libsecret-tools` package.
  * **Windows** uses Credential Manager via [@napi-rs/keyring ↗](https://www.npmjs.com/package/@napi-rs/keyring), installed on-demand the first time you opt in.  
Refer to [Storing OAuth credentials in the OS keychain](https://edgetunnel-b2h.pages.dev/workers/wrangler/commands/general/#storing-oauth-credentials-in-the-os-keychain) for the full details, including the migration behavior on opt-in/opt-out and the `CLOUDFLARE_AUTH_USE_KEYRING` environment variable.

```json
{"@context":"https://schema.org","@type":"BlogPosting","@id":"https://edgetunnel-b2h.pages.dev/changelog/product/workers/#page","headline":"Workers Changelog | Cloudflare Docs","url":"https://edgetunnel-b2h.pages.dev/changelog/product/workers/","inLanguage":"en","image":"https://edgetunnel-b2h.pages.dev/cf-twitter-card.png","publisher":{"@type":"Organization","name":"Cloudflare","url":"https://www.cloudflare.com/"},"isPartOf":{"@type":"WebSite","@id":"https://edgetunnel-b2h.pages.dev/#website","name":"Cloudflare Docs","url":"https://edgetunnel-b2h.pages.dev/"}}
```
