Skip to main content
Cloudflare Workers with Durable Objects provide a unique serverless environment where state is local, persistent, and transactional. This makes it an ideal platform for running “Stateful Agents” that remember conversation history and can perform long-running background tasks. ai-query abstracts away the complexity of Durable Objects via the AgentDO adapter, letting you write standard Python agent logic that automatically inherits distributed durability. Note: AgentDO inherits from workers.DurableObject (from the cloudflare:workers runtime). This ensures full compatibility with the Cloudflare Python runtime.

Architecture

When you deploy an ai-query agent to a Durable Object:
  1. State is Local: self.state and self.messages are backed by the DO’s transactional storage.
  2. Access is Serial: Each agent runs in a single-threaded environment (Actor Model), preventing race conditions.
  3. Communication is Internal: Agents can call other agents using self.call(), which routes traffic internally within Cloudflare’s network (zero latency, high security).

Quick Start

1. Define your Agent

Write your agent as usual. No Cloudflare-specific code is needed here.

2. Create the Adapter

Create a worker.py file. This connects your Agent to the Durable Object lifecycle.

3. Configure wrangler.toml

You need to tell Cloudflare about your Durable Object class.

Advanced Features

Inter-Agent Communication (call)

Agents running in different Durable Objects can communicate directly. ai-query detects it is running on Cloudflare and uses stub.fetch() for efficient internal routing. Important: Your agent logic (ManagerAgent below) still inherits from the standard Agent class. The AgentDO adapter (see Quick Start) handles the Cloudflare-specific transport injection at runtime.

Hibernation & Alarms

Cloudflare DOs are aggressive about saving costs by “sleeping” (hibernating) when idle. ai-query handles this automatically:
  • When you enqueue a task, AgentDO sets a Cloudflare Alarm.
  • If the DO sleeps, the Alarm wakes it up to finish processing the mailbox.
  • You don’t need to manually manage alarms or strict timeouts.

WebSocket Support

Real-time streaming is supported out of the box.
The AgentDO adapter automatically upgrades the connection and bridges events to your agent’s on_connect and on_message handlers.

Troubleshooting

”Class not found”

Ensure your wrangler.toml’s new_classes list matches the class name exported in worker.py.

”No binding found”

The registry string registry.register("researcher-.*", env.RESEARCHER) must reference a binding defined in [durable_objects.bindings].

”State not saving”

Ensure you are awaiting operations if you override handle_request manually. Inheriting from AgentDO handles this for you.