Skip to content

Changelog

New updates and improvements at Cloudflare.

Agents SDK now supports Pi 1.5 with fewer storage writes and lower memory use

Agents SDK v0.33.0 upgrades PiHarness to Pi 1.5 ↗︎. The release reduces storage transactions while streaming, improves throughput across many sessions, and reduces memory use when streaming large tool calls.

Performance improvements

  • Far fewer storage writes while streaming. Pi stores streamed answers and tool output in batches, within a second of each update, instead of on every update. Over SQLite, this cuts storage transactions by about 27x for long answers and 5.7x for turns with parallel tools, and CPU by about a quarter.
  • Higher throughput across many sessions. Pi's scheduler no longer rechecks every conversation on each commit. In a SQLite benchmark with 2,048 sessions, one Pi harness went from 88 to 459 agent runs per second.
  • Less memory on large answers. Streaming a 500 KB tool call used to take about 20 seconds of CPU and a 100 MB heap. Pi now appends new text instead of copying it on every update.

Streaming updates remain visible immediately, but are persisted in batches. With the default settings, a crash can lose up to about one second of streamed progress. Refer to Recovery to configure this interval.

Session and tool updates

  • A view of each session. session.watch() replaces session.events(). It returns the newest transcript entries and the session's live state, such as the answer being streamed, running tools, and why the last run ended without an answer.
  • Continue without adding a message. The new session.continue() API starts a new run using the existing transcript, for example after a model error or when a run reaches its turn limit.
  • Turn limit. defaults.maxTurns caps the tool rounds a run can take in new sessions.
  • Tasks that keep crashing end. Pi now ends a task cut off by its restart limit instead of parking it. retry() and the parked status are removed.
  • Browser in Pi's code mode. Scripts in Pi's code mode can call browserTool and pass its screenshots to image(). browserTool also stops when the harness aborts its call.

Continue an unanswered conversation

For an existing session and submission operationId, check the result before offering a continuation. For example, after resolving a model error:

const result = await session.wait(operationId);

if (result.status === "unanswered" && result.reason === "model_error") {
	const receipt = await session.continue({
		operationId: `${operationId}:continue`,
	});
	const continued = await session.wait(receipt.operationId);
	console.log(continued.status, continued.text);
}
const result = await session.wait(operationId);

if (result.status === "unanswered" && result.reason === "model_error") {
	const receipt = await session.continue({
		operationId: `${operationId}:continue`,
	});
	const continued = await session.wait(receipt.operationId);
	console.log(continued.status, continued.text);
}

This starts a new run without appending a user message. The session must be idle. If the transcript already ends in an answer, the operation returns unanswered with reason nothing_to_answer. Refer to Work with sessions.

Upgrade

Once a conversation runs on Pi 1.5, Pi 1.4 cannot read it. After upgrading, roll forward to fix deployment issues rather than rolling back to Pi 1.4.

Update callers of session.events() to use session.watch(), and remove uses of retry() and the parked status. Refer to the Pi Durable 1.5.0 changelog ↗︎ for the full list of breaking changes.

The Agents SDK v0.33.0 changelog ↗︎ has step-by-step upgrade instructions. Point your coding agent at them and upgrade today:

New AI Gateways require authentication

New AI Gateways now require authentication to prevent unauthorized requests. Once authentication is on, you cannot turn it off through the dashboard or API.

When you create a new AI Gateway through the API, authentication is on by default. You can leave out the authentication field or set it to true. If you set it to false, the API returns HTTP 400.

When you update an existing gateway, leaving out authentication keeps its current setting. If you try to turn off authentication after it is on, the API returns HTTP 400.

Existing gateways with authentication turned off can continue without it. You can turn it on in your gateway settings or include authentication: true in a gateway update request:

{
	"authentication": true
}

Before turning authentication on, configure HTTP clients to send a valid Cloudflare API token. Requests through Workers bindings remain pre-authenticated.

For setup instructions and supported authorization headers, refer to AI Gateway authentication.

Crawl results include URL outcomes and robots.txt diagnostics

Browser Run /crawl results now include more detailed diagnostics. Each URL record can include an outcome that identifies the specific processing result, such as success, robots_disallowed, timeout, or page_error.

The job-level robots array reports the robots.txt state for up to 50 origins encountered by the crawl. Each entry includes the origin, whether usable rules were available, and the HTTP status when the crawler received a response.

{
	"robots": [
		{
			"origin": "https://example.com",
			"state": "available",
			"status": 200
		}
	],
	"records": [
		{
			"url": "https://example.com/docs/",
			"status": "completed",
			"outcome": "success"
		}
	]
}

For field definitions and all possible outcome values, refer to URL outcomes and robots.txt diagnostics.

Request metrics breakdown by region and HTTP error code

You can now compare regional activity and errors by HTTP status code on the Metrics page for a R2 bucket in the Cloudflare dashboard.

Go to Bucket metrics ↗

Compare regions

Use Request Distribution by Region to compare request activity and filter by writes, reads, errors, or rate-limited errors (429).

R2 request distribution showing a globe, a list of regions, and the Writes filter

Inspect errors

Use Errors by Status Code to compare error counts and trends.

R2 error counts and time series grouped by HTTP status code

To troubleshoot errors, refer to the R2 error code reference.

Zero Wire, a hub for investigating critical Internet vulnerabilities

Cloudflare Radar now includes Zero Wire ↗︎, a hub for investigating critical Internet vulnerabilities and threats. Each briefing separates confirmed facts from open questions, lists remediation steps, and shows what Cloudflare observes about the threat.

Zero Wire page listing briefings under Needs attention, each with its recommended action, CVEs, tags, why it needs attention, and what to do now

Briefings

Briefings are grouped by urgency. Needs attention covers active incidents, new guidance, or unresolved scope that security teams should review now. Reference keeps stable briefings available, even if not every affected system has been patched. Each card shows the recommended action and summarizes what happened, why it matters, and what to do.

Each briefing page expands on the card with an update chronology and an overview, followed by:

  • What to do now: remediation steps, plus a prompt to copy into an AI agent with access to your infrastructure, asking for an evidence-based assessment of affected systems and exposure.
  • Cloudflare coverage: the Cloudflare products that protect against the threat, and any impact on Cloudflare's own services.
  • Evidence and sources: vendor advisories, CVE records, the CISA Known Exploited Vulnerabilities (KEV) catalog, and Radar charts, such as requests matching the related Cloudflare WAF rules.
Zero Wire briefing for the Linux IPv4 TCP use-after-free, showing its recommended action, CVE, tags, update chronology, overview, and table of contents

Follow updates

Search briefings by CVE, name, or tag, or browse every briefing with a given tag. To follow new briefings and updates, subscribe to the Zero Wire RSS feed ↗︎ or to the feed of a single tag. New briefings also appear in the Caught on Radar ↗︎ section of the Radar homepage.

Send questions or feedback from any briefing page, or at radar@cloudflare.com.

For more details, read the blog post ↗︎ or visit Zero Wire ↗︎.

WAF Release - 2026-11-03

This release introduces updates to the underlying rule expressions for PHP out-of-memory (OOM) vulnerabilities CVE-2026-109618, CVE-2026-109619 and CVE-2026-115560. The improvements are iterative changes based on reports from Security Researchers as part of PHP Capture the Flag (CTF) challenge ↗︎.

RulesetRule IDLegacy Rule IDDescriptionPrevious ActionNew ActionComments
Cloudflare Free RulesetN/APHP Remote Code Execution Attack (CVE-2026-109618, CVE-2026-109619) #2BlockBlockRule detection updated.
Cloudflare Free RulesetN/APHP Remote Code Execution Attack (CVE-2026-109618, CVE-2026-109619) #3BlockBlockRule detection updated.
Cloudflare Managed RulesetN/APHP Remote Code Execution Attack (CVE-2026-109618, CVE-2026-109619) #2BlockBlockRule detection updated.
Cloudflare Managed RulesetN/APHP Remote Code Execution Attack (CVE-2026-109618, CVE-2026-109619) #3BlockBlockRule detection updated.
Cloudflare Managed RulesetN/AphpMyAdmin - Authentication BypassN/ADisabledThis is a new detection.

WAF Release - Scheduled changes for 2026-11-10

Announcement DateRelease DateRelease BehaviorLegacy Rule IDRule IDDescriptionComments
2026-10-122026-11-10LogN/ABroken Access Control - Directory Traversal (Beta)

This rule will be merged into the original rule "Broken Access Control - Directory Traversal" (ID: ).

2026-11-032026-11-10LogN/AGeneric Rules - Dangerous File Upload

This is a new detection.

AI Search billing postponed to December 1, 2026, and default sync interval is now 24 hours

Billing postponed to December 1, 2026

AI Search billing has been postponed by one month and now begins on December 1, 2026, instead of November 1, 2026. You will not be charged for AI Search usage before December 1, 2026. Pricing and included usage are unchanged.

For rates and included usage, refer to Limits & pricing.

Default sync interval is now 24 hours

The default sync interval for AI Search instances is changing from 6 hours to 24 hours. You can still choose any supported interval, from 15 minutes to 24 hours, with the Sync interval setting in your instance settings or the sync_interval field in the API.

For details, refer to Sync interval.

Organize and authorize Access service tokens with tags

You can now assign key-value tags to Access service tokens and use those tags to organize credentials or control application access. Each token supports up to five tags, such as environment: production or team: payments.

Add or edit tags when you create or update a token in the dashboard or service token API. You can search and filter by tag on the Service Tokens page. Tags also appear in Resource Tagging, where you can query them alongside other tagged resources.

The Service Token Tag policy selector matches valid tokens with an exact key-value pair. Use it in a Service Auth policy to authorize tokens by environment or team without listing each token individually. For example, this API policy configuration accepts valid tokens tagged environment: production:

{
	"name": "Production service tokens",
	"decision": "non_identity",
	"include": [
		{
			"service_token_tag": {
				"key": "environment",
				"value": "production"
			}
		}
	]
}

For setup instructions, refer to Tag service tokens and Authorize service tokens by tag.

Evaluate Flagship flags locally

Flagship bindings now evaluate flags against a local flag store during local development, instead of calling your remote app. You can develop offline and test flag changes without affecting production. This applies to wrangler dev, the Cloudflare Vite plugin, the Vitest integration, and cf dev.

The local store starts empty, so evaluations return the default value you pass in code. Add and manage local flags in any of these ways:

  • Wrangler — Add --local to wrangler flagship flags commands, such as create, update, and evaluate. To copy all flags from your remote app, run npx wrangler flagship flags pull <APP_ID>.
  • Local Explorer — Create, edit, toggle, and evaluate flags in Local Explorer while your dev server runs.
  • cf CLI — Add --local to cf flagship commands.

To keep evaluating against your remote app instead, set remote: true on the binding.

The local flag store requires Wrangler v4.135.0 or @cloudflare/vite-plugin v1.56.0 or later. Flagship in Local Explorer requires Wrangler v4.148.0 or @cloudflare/vite-plugin v1.63.0 or later.

Refer to Flagship local development for details.

Workers will use the new module registry by default on November 17

Starting November 17, 2026, JavaScript Workers with a compatibility date of 2026-11-17 or later will use the new module registry by default. You will no longer need the new_module_registry flag for these dates. Python Workers keep using the legacy registry.

The module registry finds and loads JavaScript modules in your Worker. We announced the new registry in September 2026 ↗︎. It improves compatibility with JavaScript standards and Node.js. In Workers using Node.js compatibility, you can use require() to load ES modules. The module and its dependencies must not use top-level await.

You can also use import.meta to get information about the current module and find the URL of another module without loading it:

src/index.jsjs
export default {
	fetch() {
		return Response.json({
			moduleUrl: import.meta.url,
			isEntrypoint: import.meta.main,
			helperUrl: import.meta.resolve("./helper.js"),
		});
	},
};
src/index.tsts
export default {
	fetch(): Response {
		return Response.json({
			moduleUrl: import.meta.url,
			isEntrypoint: import.meta.main,
			helperUrl: import.meta.resolve("./helper.js"),
		});
	},
} satisfies ExportedHandler;

When deployed with src/index.ts as the unbundled entrypoint, isEntrypoint is true. helperUrl is a URL within your Worker bundle. Resolving the URL does not check whether the module exists or load it over the network. Build tools may transform import.meta. To try this example directly, refer to unbundled deployments.

Existing Workers keep their current behavior until you change their compatibility date or flags. To try the new registry before November 17, keep your current date and add new_module_registry to your compatibility flags.

Before updating, check your dependencies for invalid import attributes and changes to require() behavior. The new registry rejects invalid import attributes. Calls to require() also fail if the module or any of its dependencies use top-level await. To keep the legacy registry with a compatibility date of 2026-11-17 or later, add legacy_module_registry.

For migration details, refer to the new module registry compatibility flag, bundling documentation, and Node.js compatibility documentation.

Request.signal will be enabled by default in Workers on November 17

Starting November 17, 2026, Workers with a compatibility date of 2026-11-17 or later will receive client disconnection events through request.signal by default. Use these events to stop unnecessary work when a client leaves. You will no longer need the enable_request_signal compatibility flag for these dates.

We introduced this feature in May 2025. You can log cancellations, clean up resources, or cancel operations that accept an AbortSignal.

For example, this Worker logs a client disconnection and cancels an outgoing request:

src/index.jsjs
export default {
	async fetch(request) {
		request.signal.addEventListener(
			"abort",
			() => {
				console.log("Client disconnected");
			},
			{ once: true },
		);

		return fetch("https://example.com/slow-response", {
			signal: request.signal,
		});
	},
};
src/index.tsts
export default {
	async fetch(request): Promise<Response> {
		request.signal.addEventListener(
			"abort",
			() => {
				console.log("Client disconnected");
			},
			{ once: true },
		);

		return fetch("https://example.com/slow-response", {
			signal: request.signal,
		});
	},
} satisfies ExportedHandler;

Existing Workers keep their current behavior until you change their compatibility date or flags. To try this feature before November 17, keep your current date and add enable_request_signal to your compatibility flags.

With a compatibility date of 2026-11-17 or later, add disable_request_signal to opt out. This change does not enable request_signal_passthrough. Pass the signal explicitly, as the example does.

For more information, refer to the Request API and the Request.signal compatibility flag.

Inspect provisioned users and groups with the SCIM population viewer

The SCIM population viewer lets you inspect the users and groups provisioned to Cloudflare One by each identity provider. You can check which resources Cloudflare has received without making API requests or opening a support ticket.

In Zero Trust > Integrations > Identity providers, select a user or group count in SCIM resources to open the viewer. You can:

  • Search users by username, email, name, or resource ID, and groups by name or resource ID.
  • Inspect resource attributes in formatted or JSON views.
  • View group members and compare Cloudflare and IdP resource IDs with provisioning logs.
  • Delete individual resources from the Cloudflare SCIM population when you have edit permission.
SCIM users table with search controls and blurred personal information

The viewer shows provisioned resources rather than provisioning event history. Use SCIM provisioning logs to investigate failed requests. Existing SCIM deprovisioning and policy behavior remain unchanged.

For dashboard instructions and API examples, refer to View SCIM users and groups.

Audit Logs v2: Account analytics

Audit Logs v2 now includes analytics for account-level audit logs in the Cloudflare dashboard. The Actions over time chart separates successful and failed actions for the selected time range.

Summary cards show Total actions, Unique actors, Products impacted, and Failure rate. Select a card to investigate action types, authentication methods, top actors, top products, or failed actions. You can apply or exclude values as filters to update both the analytics and audit log table.

Account analytics in Audit Logs v2

Account analytics are not available for organization-level audit logs.

For more information, refer to the account analytics documentation.

Browser Run now runs Chrome 152

Browser Run now runs Chrome 152 by default. Your sessions get current web platform features, rendering fixes, and security patches. You do not need to change your code.

This release also includes the following improvements:

  • Updated default User-Agent. The default User-Agent for Quick Actions now reports Chrome 152 instead of Chrome 119. If you allowlist or match the Browser Run User-Agent, update your rules. You can still set your own value with the userAgent parameter. Refer to Automatic request headers.
  • Better site compatibility. Quick Actions requests now look more like requests from a regular Chrome browser, so fewer sites block them.
  • Large response headers. Pages that return large response headers now load correctly.
  • Updated root certificates. Browser Run removed distrusted root certificates from its trust store.
  • Absolute links. /links now returns absolute URLs, and links-only crawls now follow relative links.
  • Better Markdown output. /markdown and crawl Markdown output now keep code block languages.
  • Clearer errors. Quick Actions that time out now return a consistent error. Outbound Workers that throw an exception now return an HTTP error to the browser.

For more information, refer to the Browser Run documentation.

D1 will enforce a maximum query result size of 50 MB

Beginning Wednesday, November 4, 2026, D1 will enforce a maximum query result size of 50 MB. Queries that return a result larger than 50 MB will fail and return the following error:

D1 query result exceeded the maximum response size limit of 50 MB

The 50 MB limit covers the 99.999th percentile of requests across D1, so most D1 users will not be impacted.

Import and export operations via the REST API are not subject to this limit and will continue to work as they do today.

If your queries return large results, reduce the result size before the enforcement date. For example, select only the columns you need instead of using SELECT *, and paginate large result sets with LIMIT and OFFSET.

For more information, refer to D1 limits and the D1 error list.

Cloudflare WAN supports regional Gateway HTTP inspection

Cloudflare WAN traffic can now use a Gateway processing region with Regional Services. HTTPS traffic enters a Cloudflare data center (that may be outside the selected region) via an IPsec or GRE tunnel, or through Direct CNI, and remains encrypted until Gateway forwards it to the selected region for TLS decryption and HTTP inspection. This feature gives organizations control over where their sensitive traffic is processed, supporting their data sovereignty goals.

This feature requires unified routing. The processing region applies to Gateway HTTP traffic and does not apply to Gateway DNS or network policy processing.

Contact your account team to configure a processing region. For supported regions, configuration details, and limitations, refer to Data residency for Cloudflare One.

New DNS records experience is now the default for everyone

The new DNS records experience announced in May is now the default for all users on all plans, including Enterprise. The classic DNS records page has been retired and is no longer available in the Cloudflare dashboard.

Changing a record's type

When the new experience first launched, it did not support changing the type of an existing DNS record. Based on your feedback, we have since added this, so you can now change a record's type (for example, from A to CNAME) directly from the DNS records page. Under the hood, the dashboard uses the batch DNS records endpoint for this.

Questions or feedback

If you run into an issue with the new experience, contact your account team or Cloudflare Support.

Durable Objects now defer code updates by default

Durable Objects can stay active across requests, allowing you to run long-running agents, maintain long-lived WebSocket connections and coordinate state across many clients. This is possible because each Durable Object is globally unique, and this means it must run only one version of your code at a time. Previously, when you deployed a change to your Durable Objects code, that change would be applied immediately, which could interrupt in-flight work and terminate open connections.

Durable Objects now defer code updates by default. When you deploy, an active Durable Object can keep running its current code for up to 5 minutes (300 seconds) while it waits to hibernate. This gives in-flight work time to finish. WebSocket connections that use the Hibernation API remain connected when an object adopts new code after hibernating.

For an active Durable Object, a code update follows this flow:

flowchart TD
    accTitle: Code updates for an active Durable Object
    accDescr: By default, an active object can keep running its current code until it hibernates or the delay ends. After hibernating, it starts on new code on the next request. If the delay ends first, or immediate mode is selected, it resets and adopts the new code. Deferral is best effort.
    A["You deploy new code"] -->|"Default: deferred"| B["The object can keep running<br/>its current code"]
    B --> C{"Hibernates before<br/>the delay ends?"}
    C -->|Yes| D["Starts on the new code<br/>on the next request"]
    C -->|No| E["The object resets<br/>and adopts the new code"]
    A -.->|"Override: immediate"| E

To change the delay, add code_update_strategy to durable_objects in your Wrangler configuration:

{
	"durable_objects": {
		"bindings": [
			{
				"name": "CHAT_ROOM",
				"class_name": "ChatRoom",
			},
		],
		"code_update_strategy": {
			"mode": "deferred",
			"max_delay": 60,
		},
	},
}
[[durable_objects.bindings]]
name = "CHAT_ROOM"
class_name = "ChatRoom"

[durable_objects.code_update_strategy]
mode = "deferred"
max_delay = 60

max_delay is in seconds, from 0 to 86400 (24 hours), with millisecond precision. Omit it to use the default of 300 seconds.

To set the strategy for a single deployment, pass --durable-objects-code-update-mode with immediate or deferred <duration>. For example, apply an update right away during an incident, or when your deployment tooling calls a Durable Object right after deploying and needs the new code:

npx wrangler versions deploy <VERSION_ID>@100% --durable-objects-code-update-mode immediate

A deferred code update is best effort and does not guarantee that every operation finishes. The object can still reset before max_delay is reached, for example during a Cloudflare runtime update.

For more information, including how this interacts with gradual deployments and the REST API, refer to Durable Objects code updates.

WAF Release - 2026-10-30 - Emergency

This emergency release adds a new rule to the Cloudflare Managed Ruleset, disabled by default, for a vulnerability in Nuxt Image and IPX. The rule offers partial coverage. Please follow the advisory and patch to the latest version.

RulesetRule IDLegacy Rule IDDescriptionPrevious ActionNew ActionComments
Cloudflare Managed RulesetN/ANuxt Image / IPX - Explicit GIF or Animation Modifier ExposureN/ADisabledThis is a new detection.

WAF Release - 2026-10-30

This release introduces updates to the underlying rule expressions for PHP out-of-memory (OOM) vulnerabilities CVE-2026-109618, CVE-2026-109619 and CVE-2026-115560. The improvements are iterative changes based on reports from Security Researchers as part of PHP Capture the Flag (CTF) challenge ↗︎.

RulesetRule IDLegacy Rule IDDescriptionPrevious ActionNew ActionComments
Cloudflare Free RulesetN/APHP Remote Code Execution Attack (CVE-2026-109618, CVE-2026-109619) #3BlockBlockRule detection updated.
Cloudflare Free RulesetN/APHP Remote Code Execution Attack (CVE-2026-109618, CVE-2026-109619) #4BlockBlockRule detection updated.
Cloudflare Managed RulesetN/APHP Remote Code Execution Attack (CVE-2026-109618, CVE-2026-109619) #3BlockBlockRule detection updated.
Cloudflare Managed RulesetN/APHP Remote Code Execution Attack (CVE-2026-109618, CVE-2026-109619) #4BlockBlockRule detection updated.
Cloudflare Response RulesetN/ADefault block for High confidence SignaturesBlockBlockRule detection updated.

Workers subrequests now preserve context for BYOIP destinations

Cloudflare now preserves Workers context when a subrequest targets a Cloudflare-proxied hostname using Bring Your Own IP (BYOIP). These requests are identified as Cloudflare-to-Cloudflare traffic instead of external Internet traffic.

Previously, some BYOIP subrequests could lose Workers context and original client signals. This could cause security rules to behave unexpectedly, Bot Management to evaluate an internal Cloudflare connection instead of the original client, or affected requests to return false 403 responses.

Workers subrequests to BYOIP destinations now preserve the CF-Worker header and cf.worker.upstream_zone field. This supports consistent security rule evaluation across same-zone and cross-zone subrequests.

Bot Management fields on the destination zone now represent the original end-user connection for affected BYOIP subrequests. Bot scores, verified bot status, and JA3/JA4 fingerprints no longer represent the internal connection between Cloudflare services.

Because Cloudflare-proxied BYOIP destinations now follow standard Workers subrequest handling, cross-zone requests set CF-Connecting-IP to the Workers client IP address 2a06:98c0:3600::103 for security reasons. This applies when a Worker in one Cloudflare zone sends a subrequest to a hostname in another Cloudflare zone. Same-zone subrequests continue to reflect the client IP through CF-Connecting-IP.

For more information, refer to Cloudflare BYOIP, Workers subrequests, and CF-Connecting-IP in Worker subrequests.

Agents SDK: Agent Skills are files in your agent's Workspace

Agent Skills in the Cloudflare Agents SDK are now files. Write a folder with a SKILL.md into your agent's Computer ↗︎ Workspace, under /workspace/.agents/skills/, and the agent can use it on its next turn. You do not need a build step or a deploy, and the agent can write its own skills.

src/server.jsjs
import { Think, skills } from "@cloudflare/think";

export class MyAgent extends Think {
	getSkills() {
		return [
			skills.workspace(this.workspace), // /workspace/.agents/skills
			skills.r2(this.env.SKILLS_BUCKET, { prefix: "skills/" }),
		];
	}
}
src/server.tsts
import { Think, skills } from "@cloudflare/think";

export class MyAgent extends Think<Env> {
	getSkills() {
		return [
			skills.workspace(this.workspace), // /workspace/.agents/skills
			skills.r2(this.env.SKILLS_BUCKET, { prefix: "skills/" }),
		];
	}
}

This release includes:

  • Three sources. Load skills from a Computer Workspace, an R2 bucket, or code. Think lists every source again before each turn.
  • The open format. Every SKILL.md is checked against the Agent Skills specification ↗︎. As the specification's guide for agents recommends, a skill that breaks a rule still loads, with a logged warning. Use parseSkill() to check a skill before you write it.
  • Scripts in the Workspace. Skill scripts are Workspace files, and the model runs them with the Workspace exec tool. Refer to Execution.
  • Skill tools for any harness. Use the same activate_skill and read_skill_resource tools in Think, Pi Durable, or the AI SDK. Refer to Skills tools.
  • Warm prompt caches. When a skill changes mid-conversation, Think sends the new catalog as a reminder instead of rebuilding the cached system prompt. An overridden getSystemPrompt() now stays at the top of the system prompt, above context blocks.

This is a breaking change for code that uses agents/skills directly. The agents:skills Vite import, agents/skills/compile, SkillRegistry, and Think's skillWorkspace are removed, and runner() moved to agents/skills/runner. Install Agents SDK v0.32.0 ↗︎ and Think v0.23.0 ↗︎ or later. Refer to the computer-skills ↗︎ and r2-skills ↗︎ examples.

View your data localization settings in one dashboard page

The Cloudflare dashboard now includes a Data Localization Suite Overview, a read-only view of the data localization settings on your account. It shows your Regional Services, Customer Metadata Boundary, and Geo Key Manager settings in one place, so you no longer need to check several dashboard pages and APIs to see where your traffic is processed and where your logs and private keys are stored.

To find it, go to Application Security > Data Localization Suite, or search for "DLS" in the dashboard.

The Overview has a tab for each product:

  • Regional Services: regionalized hostnames (filter by region or zone), regionalized IP bindings, and regionalized Spectrum applications, each with its region.
  • Customer Metadata Boundary: whether the boundary is on, the region (US or EU), and whether out-of-region access is allowed.
  • Geo Key Manager: every custom certificate with a geo policy, with its hostname, zone, region, and status.

Each item links to the dashboard page where you change its setting, and each tab links to the product's documentation.

To learn more, refer to the Data Localization Suite documentation.