We are refreshing the Workers AI model catalog to make room for new releases and updated models. Update your apps to remove references to the models listed below before November 15, 2026.
We recommend moving to newer models for the best token efficiency and throughput. For pricing, refer to the Workers AI pricing page.
AI Gateway now supports model aliases. A model alias is a pool of models that your application calls by one name, such as custom/support-fast. AI Gateway tries the models in the order you set and falls back to the next one if a request fails, or uses smart routing to choose a model for each request.
Because your application only references the alias, you can swap models or change the routing algorithm on your gateway without redeploying. Create and manage aliases on your gateway's Routing page, alongside dynamic routes.
To call an alias through the REST API, use its name as the model. For example, send this body to /accounts/{account_id}/ai/run:
{ "model": "custom/support-fast", "input": { "messages": [{ "role": "user", "content": "Reply with a short greeting." }] }}
Include the cf-aig-gateway-id header to select the gateway where you created the alias. Aliases are scoped to individual gateways.
For setup instructions and routing options, refer to Model aliases.
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:
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 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.
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.
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.
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.
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.
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.
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.
Agents that build websites need to check their work in a real browser. Internal hostnames let your agent's browser preview a dev server running in a container without exposing that server to the public Internet.
With internal hostnames, the persistent browser in the Cloudflare Agents SDK can open sites that only your agent serves. Give the browser hostnames such as preview.internal, and its requests to them go to your agent instead of the Internet. The model can check a dev server in its sandbox, a folder in its workspace, or another Worker in the same browser it uses for the web, and nothing is exposed publicly.
Each internal host has a fetch function that runs in your Durable Object, so it can use the object's bindings and state. A host can also send its requests straight to another Worker through a service binding. Add a target schema to a host, and the model chooses what it serves, such as which port or which folder.
Internal hostnames are a capability of the browser, independent of your agent harness. Use the built-in adapters for Pi Durable, AI SDK, and TanStack AI, or connect another harness by implementing a tool with browser.session(). No prebuilt adapter is required.
This example adds a private dev-server preview to a Pi Durable agent. Start with that guide's packages, bindings, and request handler, and install Agents SDK v0.31.0 ↗︎ or later. The example has three parts:
Browser configuration:internalHosts defines how the browser reaches the dev server.
Durable Object wiring: Lifecycle and fetchInternalHost() connect the browser to your application.
Harness integration:browserTool from agents/browser/pi registers the tool with Pi.
import { DurableObject } from "cloudflare:workers";import { createModels } from "@earendil-works/pi-ai/models";import { createRegistry, Harness } from "@earendil-works/pi-durable";import { Browser, browserRun } from "agents/browser";import { browserTool } from "agents/browser/pi";import { PiHarness } from "agents/harness/pi";import { Lifecycle } from "agents/lifecycle";import { createAI } from "agents/models/pi-ai";import { z } from "zod";// Your own code: reach a port on your sandbox and return its Response.import { fetchSandboxPort } from "./hosts";// Browser Run calls back into your Worker through this entrypoint.export { InternalHostRouter } from "agents/browser";export class BrowserAssistant extends DurableObject { ai = createAI({ binding: this.env.AI }); registry = createRegistry(); browser = new Browser({ provider: browserRun(this.env.BROWSER, { internalHosts: { router: this.ctx.exports.InternalHostRouter, hosts: { "preview.internal": { description: "Your dev servers", // What the model passes to browser.assignHost() to choose // what this host serves. fetch receives it as its second argument. target: z.object({ port: z.number().int().min(1024) }), fetch: (request, { port }) => fetchSandboxPort(port, request), }, }, }, }), }); harness = new PiHarness({ harness: ({ storage, context, onWake }) => { const models = createModels(); models.setProvider(this.ai.provider); this.registry.install({ name: "browser", tools: [ browserTool({ browser: this.browser, loader: this.env.LOADER }), ], }); return Harness.open( storage, { models, registry: this.registry, onWake }, context, ); }, defaults: { model: this.ai("@cf/zai-org/glm-5.3-flash") }, }); lifecycle = Lifecycle.install(this).use(this.browser).use(this.harness); // InternalHostRouter calls this method to reach your Browser. fetchInternalHost(message) { return this.browser.fetchInternalHost(message); } async ask(prompt) { const { text } = await this.harness.prompt(prompt); return text; }}
import { DurableObject } from "cloudflare:workers";import { createModels } from "@earendil-works/pi-ai/models";import { createRegistry, Harness } from "@earendil-works/pi-durable";import { Browser, browserRun, type InternalHostMessage } from "agents/browser";import { browserTool } from "agents/browser/pi";import { PiHarness } from "agents/harness/pi";import { Lifecycle } from "agents/lifecycle";import { createAI } from "agents/models/pi-ai";import { z } from "zod";// Your own code: reach a port on your sandbox and return its Response.import { fetchSandboxPort } from "./hosts";// Browser Run calls back into your Worker through this entrypoint.export { InternalHostRouter } from "agents/browser";export class BrowserAssistant extends DurableObject<Env> { ai = createAI({ binding: this.env.AI }); registry = createRegistry(); browser = new Browser({ provider: browserRun(this.env.BROWSER, { internalHosts: { router: this.ctx.exports.InternalHostRouter, hosts: { "preview.internal": { description: "Your dev servers", // What the model passes to browser.assignHost() to choose // what this host serves. fetch receives it as its second argument. target: z.object({ port: z.number().int().min(1024) }), fetch: (request, { port }) => fetchSandboxPort(port, request), }, }, }, }), }); harness = new PiHarness({ harness: ({ storage, context, onWake }) => { const models = createModels(); models.setProvider(this.ai.provider); this.registry.install({ name: "browser", tools: [ browserTool({ browser: this.browser, loader: this.env.LOADER }), ], }); return Harness.open( storage, { models, registry: this.registry, onWake }, context, ); }, defaults: { model: this.ai("@cf/zai-org/glm-5.3-flash") }, }); lifecycle = Lifecycle.install(this).use(this.browser).use(this.harness); // InternalHostRouter calls this method to reach your Browser. fetchInternalHost(message: InternalHostMessage) { return this.browser.fetchInternalHost(message); } async ask(prompt: string) { const { text } = await this.harness.prompt(prompt); return text; }}
To use another harness, keep the browser configuration. Choose a browser-tool adapter if one is available, or implement a tool using browser.session().
browserTool tells the model about each host, including the schema of its target. Because preview.internal has a target schema, the model can choose which port it serves. To check its dev server, the model calls browser.assignHost() with a target that matches the schema, such as { port: 5173 }, and opens the URL it gets back:
The target is checked against the schema and stored, so it lasts across turns, browser restarts, and redeploys. Each request to http://preview.internal/ then calls the host's fetch function with { port: 5173 }.
This release also simplifies browserTool. It runs the model's code in its own Dynamic Worker and no longer needs a CodemodeRuntime export. Refer to the v0.31.0 upgrade notes ↗︎ if you already use browserTool.
For the complete example, limits, and security guidance, refer to Internal hostnames.
@cloudflare/computer ↗︎ gives your agent a workspace to run code in. From v0.7.0, that code can resume after a deploy or crash, and pause on an external action, for example to approve a tool call.
Resume interrupted runs
Set onInterrupt: "replay" on WorkerJavaScriptBackend, or on a single run.
import { DurableObject } from "cloudflare:workers";import { Workspace } from "@cloudflare/computer";import { WorkerJavaScriptBackend } from "@cloudflare/computer/backends/worker-javascript";export class MyAgent extends DurableObject { workspace = new Workspace({ storage: this.ctx.storage, backends: [ new WorkerJavaScriptBackend({ loader: this.env.LOADER, onInterrupt: "replay", }), ], });}
import { DurableObject } from "cloudflare:workers";import { Workspace } from "@cloudflare/computer";import { WorkerJavaScriptBackend } from "@cloudflare/computer/backends/worker-javascript";export class MyAgent extends DurableObject<Env> { workspace = new Workspace({ storage: this.ctx.storage, backends: [ new WorkerJavaScriptBackend({ loader: this.env.LOADER, onInterrupt: "replay", }), ], });}
When recovery is triggered, the JavaScript runs again from the beginning, reusing recorded results for completed calls without printing previously recorded output again. If a call's result was not recorded before the interruption, recovery may repeat the call — even if its action already succeeded. For retry handling, including unsafeToRepeat() for operations that cannot safely repeat, refer to Calls that must not run twice.
Recovery starts on the next call to workspace.runtime. To recover without waiting for traffic, call workspace.runtime.recover() from a Durable Object alarm.
Wait for approvals
Expose your application functions through custom modules. A function can call ctx.interrupt() to pause the run until your application supplies an approval decision.
Require approval before posting a comment
For example, to provide a GitHub module that allows an agent to post a comment on an issue with approval, an implementation of postComment could look like this:
new WorkerJavaScriptBackend({ loader: this.env.LOADER, onInterrupt: "replay", modules: { // The agent's code imports this with `import { postComment } from "ws:github"`. "ws:github": { postComment: async ([issue, body], ctx) => { const { approved } = await ctx.interrupt({ issue, body, }); if (!approved) throw new Error("The comment was rejected."); return github.comment(issue, body, { idempotencyKey: ctx.callId }); }, }, },});
new WorkerJavaScriptBackend({ loader: this.env.LOADER, onInterrupt: "replay", modules: { // The agent's code imports this with `import { postComment } from "ws:github"`. "ws:github": { postComment: async ([issue, body], ctx) => { const { approved } = await ctx.interrupt<{ approved: boolean }>({ issue, body, }); if (!approved) throw new Error("The comment was rejected."); return github.comment(issue, body, { idempotencyKey: ctx.callId }); }, }, },});
Call it from agent code
When the agent's code calls postComment(), the run pauses at ctx.interrupt() until your app responds. The agent's code calls it like any other function:
import { postComment } from "ws:github";export default async function ({ issue }) { return postComment(issue, "Hello world");}
Respond to the approval request
The time spent waiting does not count toward its timeout. The wait also survives deploys. Fetch the pending calls with workspace.runtime.pending() and resolve them with respond():
for (const call of await workspace.runtime.pending()) { await workspace.runtime.respond(call.id, call.callId, { approved: true });}
for (const call of await workspace.runtime.pending()) { await workspace.runtime.respond(call.id, call.callId, { approved: true });}
The run continues once all pending calls are resolved.
Cloudflare's product-specific MCP servers now serve only /mcp. A request to /sse returns 410 Gone with the server's /mcp URL, which most MCP clients show in their connection error.
If your MCP client is configured with an /sse URL, change it to /mcp, for example https://docs.mcp.cloudflare.com/mcp. If you signed in through /sse, your client asks you to sign in again. Connections that already use /mcp are not affected.
Agents SDK v0.30.0 runs PiHarness on Pi 1.4 ↗︎, and makes it recover more reliably from evictions, crashes, and storage errors.
Hibernation while Pi's tasks sleep.PiHarness passes Pi's new onWake callback to your harness factory. While a task sleeps, such as during a model retry backoff, the Durable Object can hibernate until the task is due instead of staying in memory.
Parked tasks. Pi 1.4 parks a task that keeps crashing the object instead of restarting it forever. Parked operations show as parked in pending(), and session.retry() runs them again.
Recovery from storage errors.PiHarness reopens Pi after a storage error instead of failing every call until the object restarts. Its wake-up job retries failed steps with a backoff instead of being dropped.
Retried model streams.agents/models/pi-ai reports a cut-off or idle model stream as a transient error, so Pi retries the turn instead of failing it.
Upgrade
The Agents SDK v0.30.0 changelog ↗︎ has step-by-step upgrade instructions. Point your coding agent at them and upgrade today:
Pi 1.4 migrates the session storage in the object's SQLite database to a schema that Pi 1.3 cannot open, so a deployment cannot roll back past this upgrade. Refer to the Pi Durable 1.4.0 changelog ↗︎ for Pi's own breaking changes.
The private keys of eight eMudhra intermediate certificate authorities ↗︎ can be recovered, so anyone can forge a certificate for any hostname that chains to them. Sandbox SDK images before 0.12.14 trust these certificates. An HTTPS connection that leaves the container directly, such as one from mountBucket(), backups, gitCheckout(), tunnels, or code that runs in the sandbox, can be intercepted with a forged certificate.
What you need to do
Sandbox SDK 0.x
Update immediately. Install @cloudflare/sandbox@0.12.14, change the FROM line in your Dockerfile to the matching image, and redeploy. Keep any -python, -opencode, or -musl suffix on the image tag. The deployment's rollout replaces running sandboxes with ones that use the new image.
Dockerfiledockerfile
FROM docker.io/cloudflare/sandbox:0.12.14
If you use the next prerelease, update to 0.13.0-next.825.1 or later.
If you cannot update yet and use 0.8.7 or later, send all HTTPS through your Worker, so that Cloudflare checks every certificate on port 443 whatever your image trusts:
Deploy, then stop running sandboxes so that they restart with the interception certificate. This does not cover TLS on other ports, such as cloudflared tunnels, and clients that ignore the injected certificate fail to connect. For more information, refer to HTTPS traffic.
Sandbox SDK 1.x
You do not need to update the SDK, because it makes no TLS connections of its own. Your image decides which certificates your sandboxes trust, so rebuild it and replace the sandboxes that run the old one:
Run docker pull for each base image in your Dockerfile, then clear the Docker build cache with docker builder prune --all. wrangler deploy builds with your local images and build cache, so without these steps it can ship the old CA certificates and runtimes. If your Wrangler configuration references an image by digest, build and push a new image and update the digest instead.
Deploy your Worker.
Stop sandboxes that are still running, for example with this.ctx.container.destroy(). A running sandbox keeps the image it started with until it stops. To restart only the sandboxes whose image is out of date, refer to Roll out a named image update.
If you use snapshots, create new ones from sandboxes that run the updated image. A snapshot restores the image it was created from, so an older snapshot brings back the old certificates.
Check your sandboxes
From inside a sandbox, connect to one of the test hosts listed at emudhra.we-have-a-problem.com ↗︎ with each TLS client your code uses, such as curl, node, or bun. Every request should fail:
In the 0.12.13 images, the system CA bundle, Node.js, cloudflared, and pip reject certificates from the compromised intermediates. The images ship updated Ubuntu and Alpine CA certificates, Node.js 22.23.4, cloudflared 2026.10.2, and pip 26.2.2 in the -python image.
0.12.14 updates Bun to 1.4.4, so the bun command and createBackup() uploads of archives of 10 MiB or more reject these certificates too. The -opencode image ships OpenCode 1.19.4 or later, which also runs on Bun 1.4.4.
The Agents SDK has a new createAI function for the AI SDK and Pi AI. It unifies what workers-ai-provider and ai-gateway-provider did: Workers AI models, AI Gateway catalog models, dynamic routes, and vendor models, through the AI binding or an account id and API token.
workers-ai-provider and ai-gateway-provider are now feature frozen and marked as deprecated. Please migrate at your convenience.
npm i agents
import { createAI } from "agents/models/ai-sdk";import { streamText } from "ai";export default { async fetch(request, env) { const ai = createAI({ binding: env.AI, id: "my-gateway" }); const result = streamText({ model: ai("anthropic/claude-opus-5.5", { fallback: ["@cf/zai-org/glm-4.7-flash"], }), prompt: "Write a haiku about Durable Objects", }); return result.toTextStreamResponse(); },};
import { createAI } from "agents/models/ai-sdk";import { streamText } from "ai";export default { async fetch(request: Request, env: Env) { const ai = createAI({ binding: env.AI, id: "my-gateway" }); const result = streamText({ model: ai("anthropic/claude-opus-5.5", { fallback: ["@cf/zai-org/glm-4.7-flash"], }), prompt: "Write a haiku about Durable Objects", }); return result.toTextStreamResponse(); },};
Vendor model objects. Pass a model from the vendor's own package, such as ai(anthropic("claude-opus-5-5")). It goes unchanged to AI Gateway's provider-native endpoint.
The binding, or an account id and API token. Use a gateway in another account, or call from outside a Worker.
Gateway options, fallback, and BYOK. Caching, logging, metadata, retries, byokAlias, zdr, and vendorKey.
Stream resume. Through the binding, a catalog or dynamic route stream that drops mid-answer resumes.
Other model types. Embeddings, images, speech, transcription, and reranking in the AI SDK provider, and images in Pi AI.
Think and Agent Skills now use the workspace from @cloudflare/computer ↗︎ as well as the filesystem tools. A JavaScript execution environment can be configured by adding the WorkerJavaScriptBackend.
@cloudflare/shell is deprecated, and so is Think's createExecuteTool. These will no longer be developed nor supported from today onwards.
import { Think } from "@cloudflare/think";import { Workspace } from "@cloudflare/computer";import { WorkerJavaScriptBackend } from "@cloudflare/computer/backends/worker-javascript";export class MyAgent extends Think { workspace = new Workspace({ storage: this.ctx.storage, backends: [ new WorkerJavaScriptBackend({ id: "js", loader: this.env.LOADER }), ], });}
import { Think } from "@cloudflare/think";import { Workspace } from "@cloudflare/computer";import { WorkerJavaScriptBackend } from "@cloudflare/computer/backends/worker-javascript";export class MyAgent extends Think<Env> { override workspace = new Workspace({ storage: this.ctx.storage, backends: [ new WorkerJavaScriptBackend({ id: "js", loader: this.env.LOADER }), ], });}
Migrate your workspace data
This is a breaking change. @cloudflare/computer stores files in different tables from @cloudflare/shell, and there is no automatic data migration between workspace formats. To keep an existing workspace, copy its files with the script in Migrating from @cloudflare/shell to @cloudflare/computer ↗︎. Otherwise your agent will start with an empty workspace, though the original data will still be present in the existing tables.
Grant only the required scopes when you connect, then authorize more on demand as your agent performs a task. When a tool call needs a scope you have not granted, the server returns an insufficient_scope challenge ↗︎ naming it, and your MCP client asks you to approve it. Scopes you already granted are kept.
To start with the least access, choose Minimal on the consent page when you connect https://mcp.cloudflare.com/mcp. Refer to authorization in MCP.
Available now in all MCP clients that support step-up authorization.
@cf/cloudflare/clairic is now available on Workers AI as a preview. Clairic is the first extraction model: a System One model that answers with values instead of text. We intend to release the model with open weights soon.
Decision models such as Clef choose among options you define up front. Many structured-output tasks do not have answers you can list in advance: an invoice total, a delivery date, the number of days a shipment is late, or what a repair will cost. Clairic handles these. You send a state and a schema of typed fields, and it returns one typed value per field. A value is read from the input, computed from it, or predicted beyond it.
Clairic does not generate tokens. It reads your input in one pass and decodes each answer under the rules of its type, so every answer is a valid value of the type you asked for, or null when the input does not determine it.
Typed fields
Define as many fields as you need. Fields that do not fit beside the input in one pass are split across parallel passes, so there is no upper limit.
Type
Returns
text
An exact span of the input, with its character offsets
number
A number read or worked out from the input, honoring integer and decimals
date, time, datetime
Real calendar dates and valid times, in ISO form
duration
A length of time in the unit you choose
list
Every matching text, number, or date, in input order
estimate
A distribution inside your min and max, on your step grid, on a linear or log scale
forecast
One estimate per future step of a series, up to 64 steps
Every scalar answer includes p_null, the probability that the input does not determine the value, and a confidence score. Estimates and forecasts include a median and an 80% interval (p10 to p90). Set options.include_quantiles to also get all 99 percentiles. Use these to decide what to automate and what to send to review.
You can also pass up to four images alongside the state.
const response = await env.AI.run("@cf/cloudflare/clairic", { model: "clairic", state: "Invoice INV-2291 from Northwind Supply, issued 2026-09-02, net 30. 4 pallets at $250.00 each, shipping $80.00. Contact: Dana Ruiz, Priya Shah.", fields: { invoice_number: { type: "text" }, issued: { type: "date" }, due_date: { type: "date", instructions: "Issue date plus the net payment days", }, total: { type: "number", decimals: 2, unit: "USD", instructions: "Amount due including shipping", }, contacts: { type: "list", items: "text" }, },});// response.answers.invoice_number.value -> "INV-2291", with its span in the state// response.answers.total.value -> the amount due, with p_null and confidence
const response = await env.AI.run("@cf/cloudflare/clairic", { model: "clairic", state: "Invoice INV-2291 from Northwind Supply, issued 2026-09-02, net 30. 4 pallets at $250.00 each, shipping $80.00. Contact: Dana Ruiz, Priya Shah.", fields: { invoice_number: { type: "text" }, issued: { type: "date" }, due_date: { type: "date", instructions: "Issue date plus the net payment days", }, total: { type: "number", decimals: 2, unit: "USD", instructions: "Amount due including shipping", }, contacts: { type: "list", items: "text" }, },});// response.answers.invoice_number.value -> "INV-2291", with its span in the state// response.answers.total.value -> the amount due, with p_null and confidence
Preview
The current endpoint is an early checkpoint, and we expect it to improve:
Arithmetic: One- and two-step calculations, such as totals, differences, conversions, and date arithmetic, are reliable. Long chains of dependent steps and aggregations across many table rows are not yet. Extract the inputs with Clairic and do the math in code.
Estimates: Clairic estimates best when the input contains evidence such as comparables, history, or descriptive text. Without evidence, the interval is wide.
Forecasts: Forecasting is basic. Next-step forecasts follow recent patterns, but forecasts several steps out flatten toward the average, and Clairic does not anticipate events the series does not show, such as holidays. It does not replace a time-series model trained on your data.
Calibration: Intervals are trained to be calibrated and are on most held-out sets, but they can run narrow on unfamiliar data.
Confidence: Every answer is well formed, not necessarily correct. Use confidence, p_null, and the intervals to decide what to automate and what to send to review.
Dates: Dates without a year are resolved from context. If a field depends on the current date, set reference_date or add a line such as Today: 2026-10-19 to the state.
Pricing
Clairic costs $0.10 per million input tokens. Because it generates no tokens, there is no output token charge.
Get started
Use Clairic through the Workers AI binding (env.AI.run()) or the REST API at /ai/run. You can also use AI Gateway with these endpoints.
@cf/deepseek-ai/deepseek-v4.1-flash-1017 is now available on Workers AI. DeepSeek V4.1 Flash is a multimodal Mixture-of-Experts model with 552B backbone parameters. It activates 8B parameters per token during prefill and 16B during decode, which keeps input-heavy agentic workloads fast and low-cost.
The 1017 release is an update to DeepSeek V4.1 Flash with improvements across reasoning, coding, agentic tasks, and visual benchmarks, and it completes tasks with shorter outputs.
Key capabilities:
Vision: Send images alongside text in the same request.
Reasoning: Reasoning is on by default at high effort. Set reasoning_effort to low or max to change the effort, or to none to turn reasoning off.
Function calling: Build agents that invoke tools and APIs across multiple conversation turns.
Long context: A full 1,048,576 token context window.
DeepSeek V4.1 Flash requires the Workers Paid plan or prepaid AI Gateway credits. The default rate limit is 20 requests per minute with standard Workers AI billing and 50 requests per minute with prepaid AI Gateway credits. For details, refer to limits.
AI Search keyword search with the trigram tokenizer now matches Japanese, Chinese, and Korean queries, including full natural-language questions such as 経費精算の締め日はいつですか?. Previously, a query without spaces was treated as a single exact phrase and usually returned no keyword results.
The porter tokenizer does not work well for these languages. If your content is in Japanese, Chinese, or Korean, set keyword_tokenizer to trigram. Changing the tokenizer triggers a full reindex.
@cf/daily-co/phonellm-mini-alpha-2, a model from the Pipecat ↗︎ team at Daily, is now available on Workers AI. PhoneLLM is built for voice agents and other realtime AI applications, where a model has to reply quickly and call the right tool mid-conversation.
In a voice agent, the language model sits between speech-to-text and text-to-speech, so every second it takes adds to the caller's wait. Developers usually choose between a fast model without reasoning mode, which can miss instructions or tool calls, and a slower model in reasoning mode, which handles both well. Pipecat post-trained NVIDIA Nemotron 3 Nano 30B on phone and customer support scenarios so PhoneLLM follows instructions and calls tools better without reasoning mode.
You can use PhoneLLM through the Workers AI binding (env.AI.run()) or the REST API at /ai/run. Pipecat recommends temperature: 0. Also set chat_template_kwargs: { enable_thinking: false }.
Run a voice agent with Pipecat on Workers
Pipecat ↗︎ is an open-source Python framework for building voice agents. Now that Python Workers are generally available, you can run a Pipecat voice agent on Cloudflare.
Workers Issues provides built-in error monitoring for Cloudflare Workers. It detects production failures and groups related failures into issues without an SDK or application wrapper.
The Cloudflare API MCP server now sends these issues as MCP Events ↗︎, the first event it exposes. MCP clients discover cloudflare.alert.workers_observability_real_time_issue with events/list and subscribe with events/subscribe, scoped to an account or a single Worker. When Issues detects a new or recurring issue, the server posts a signed event to the client's webhook, so an agent can start investigating without polling.
To use it, enable Issues on your Worker and connect https://mcp.cloudflare.com/mcp with the Notifications Write and Workers Observability Write permissions to a client that supports MCP Events webhooks.
The Cloudflare Agents SDK now provides a browserTool that gives your agent a Browser Run browser it can return to on later turns. Your agent can open a website, inspect a page, and come back to it with its tabs, cookies, and login session intact while the browser session remains alive.
When you give browserTool to your agent, the model writes code that drives the browser through the Chrome DevTools Protocol (CDP). Screenshots return as images that an image-capable model can inspect and your UI can display.
Each Pi conversation gets its own active tab by default. Cookies and logins remain shared within the browser.
The browser stays alive between turns, including when the Durable Object hibernates. Its default idle timeout is 10 minutes. If the session expires or crashes, the tool creates a fresh browser and reports restarted: true. The old tabs and login state are gone.
You can also use the persistent browser with the AI SDK and TanStack AI adapters, or connect another harness through the public Browser and CDP APIs.
Refer to persistent browser tools for the complete Pi Durable example, required bindings, and behavior when a tool call is interrupted.
The Cloudflare Agents SDK now provides a web_fetch tool that reads webpages, PDFs, and supported Office documents, using Workers AI Markdown Conversion to turn them into text the model can read. The tool requests Markdown directly from sites that support Markdown for Agents and formats JSON for the model.
When you give the web_fetch tool to your agent, the model provides a URL and receives back the page content, along with the final URL, HTTP status, and content type. Long pages come back in smaller sections, with an offset the model can use to continue reading. You control which hosts the agent can fetch, response size, timeouts, and redirects.
When you also provide the web_search tool to your agent, the model is told to use web_fetch to read the pages that web_search returns.
The web_fetch tool works with any harness. The SDK includes AI SDK and TanStack AI adapters. If you use a different harness, or need to fetch a page without calling a model, use fetchWeb(), windowWebFetchPage(), and renderWebFetchPage() from agents/webfetch. Direct fetching does not require a Durable Object or browser.
For setup, examples, and request controls, refer to Web fetch.
The Agents SDK now supports OpenCode 2.0 ↗︎ through the experimental OpenCodeHarness. Run OpenCode inside a plain Durable Object, with sessions stored in SQLite and Lifecycle jobs that wake interrupted work after eviction.
The agents/models/opencode provider connects OpenCode to Workers AI through the AI binding. OpenCode plugins extend the harness with custom tools, remote MCP servers, and skills. Refer to OpenCode's Cloudflare SDK documentation ↗︎ for the embedded host API.
Install Agents SDK 0.28.0 or later with the OpenCode packages:
npm i agents@latest @opencode/sdk@2 @opencode/plugin@2
The OpenCode harness guide includes the workerTools plugin, Wrangler configuration, and session APIs. The working example ↗︎ adds a browser UI, WebSocket streaming, and Workspace tools from @cloudflare/computer for files and code execution.
When you give the web_search tool to your agent, the model provides a query and max results, and receives back a short numbered list of titles, URLs, and trimmed descriptions. When you also provide the web_fetch tool to your agent, the model is told to use it to read the pages that the web_search tool returns.
The SDK also includes AI SDK and TanStack AI adapters. To search without a model, such as from a scheduled job, use createAIWebSearch() or createHTTPWebSearch() from agents/websearch.
For setup, options, and error handling, refer to Web search.