<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Durable-Objects on RockB</title><link>https://baeseokjae.github.io/tags/durable-objects/</link><description>Recent content in Durable-Objects on RockB</description><image><title>RockB</title><url>https://baeseokjae.github.io/images/og-default.png</url><link>https://baeseokjae.github.io/images/og-default.png</link></image><generator>Hugo</generator><language>en-us</language><lastBuildDate>Thu, 07 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://baeseokjae.github.io/tags/durable-objects/index.xml" rel="self" type="application/rss+xml"/><item><title>Cloudflare Project Think Guide 2026: Build Long-Running AI Agents with Durable Execution</title><link>https://baeseokjae.github.io/posts/cloudflare-project-think-ai-agents-guide/</link><pubDate>Thu, 07 May 2026 00:00:00 +0000</pubDate><guid>https://baeseokjae.github.io/posts/cloudflare-project-think-ai-agents-guide/</guid><description>Cloudflare Project Think 2026: build long-running AI agents with durable execution, Fibers, Facets, and Workers infrastructure.</description><content:encoded><![CDATA[<p>During Cloudflare Agents Week 2026, the internal AI engineering stack processed 20 million requests through AI Gateway and 241 billion tokens through Workers AI — the largest proof-of-concept for Cloudflare&rsquo;s own infrastructure as an AI agent runtime. Project Think is Cloudflare&rsquo;s answer to the question of how you build AI agents that run for minutes or hours, maintain state across tool calls, and spawn specialized sub-agents, all on serverless infrastructure. The framework provides a base class (<code>@cloudflare/think</code>) built on top of Durable Objects, giving agents persistent state, hibernation (zero billing during idle), and colocated sub-agent execution via RPC. As of April 2026, Project Think is in developer preview — APIs may change as feedback is incorporated. Here is a complete guide to the architecture and how to build with it.</p>
<h2 id="what-is-cloudflare-project-think">What is Cloudflare Project Think?</h2>
<p>Cloudflare Project Think is a TypeScript framework for building long-running AI agents on Cloudflare&rsquo;s serverless infrastructure. It extends Durable Objects — Cloudflare&rsquo;s stateful, actor-model compute primitive — with primitives specifically designed for AI agent patterns: parallel execution threads (Fibers), modular sub-agents (Facets), persistent conversation trees (Sessions), and sandboxed code execution. The core insight behind Project Think is that most AI agent frameworks treat each tool call as a new stateless HTTP request. This works for short tasks but breaks for agents that need to maintain context across hours of execution, accumulate state between tool calls, and spawn specialized sub-agents for parallel work. Dynamic Workers, which power Project Think&rsquo;s sandboxed execution, are approximately 100x faster to start and up to 100x more memory-efficient than traditional containers — critical when agents need to spin up isolated execution environments on demand. Project Think is part of a broader 2026 Cloudflare push into AI infrastructure alongside Workers AI (model inference) and AI Gateway (observability and routing), positioning Cloudflare as a full-stack AI agent deployment target.</p>
<h2 id="core-primitives-fibers-facets-sessions-and-sandboxed-execution">Core Primitives: Fibers, Facets, Sessions, and Sandboxed Execution</h2>
<p>Project Think introduces four primitives that extend the base Durable Object model for agent use:</p>
<p><strong>Fibers</strong> are isolated execution threads within a single agent instance. Each Fiber runs independently and can be awaited, cancelled, or monitored. When an agent needs to parallelize work — run three web searches simultaneously, or process multiple files concurrently — it spawns Fibers for each task. Fibers share the parent agent&rsquo;s state but execute independently, making them appropriate for fan-out patterns within a single agent.</p>
<p><strong>Facets</strong> are child Durable Objects (sub-agents) that are colocated with the parent agent. The key distinction from Fibers: Facets have their own persistent state, their own tool sets, and their own execution loops. RPC latency between a parent agent and its Facets is comparable to function calls, not HTTP round-trips. This makes Facets suitable for specialized sub-agents — a researcher Facet, an analyst Facet, a writer Facet — that maintain their own context and can be reused across multiple parent agent sessions.</p>
<p><strong>Sessions</strong> implement tree-structured conversation history with branching support. Instead of a flat conversation list, Sessions allow agents to explore multiple reasoning paths and branch back to earlier points. This supports &ldquo;what if&rdquo; reasoning: the agent can try one approach, observe the result, branch back to an earlier state, and try an alternative approach — without losing the history of either path.</p>
<p><strong>Sandboxed Execution</strong> provides isolated environments for running AI-generated code. Rather than executing model-generated code directly in the agent context, Project Think routes code execution through a sandboxed Dynamic Worker. The Execution Ladder (covered in its own section) controls which level of sandbox access an agent can escalate to, based on trust level.</p>
<h2 id="getting-started-with-the-think-base-class-cloudflarethink">Getting Started with the Think Base Class (@cloudflare/think)</h2>
<p>The Think base class wraps a Durable Object with the agent primitives. A basic agent implementation:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span><span style="color:#66d9ef">import</span> { <span style="color:#a6e22e">Think</span> } <span style="color:#66d9ef">from</span> <span style="color:#e6db74">&#39;@cloudflare/think&#39;</span>;
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">import</span> { <span style="color:#a6e22e">Anthropic</span> } <span style="color:#66d9ef">from</span> <span style="color:#e6db74">&#39;@anthropic-ai/sdk&#39;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">export</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">ResearchAgent</span> <span style="color:#66d9ef">extends</span> <span style="color:#a6e22e">Think</span> {
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">private</span> <span style="color:#a6e22e">client</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> <span style="color:#a6e22e">Anthropic</span>();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">async</span> <span style="color:#a6e22e">run</span>(<span style="color:#a6e22e">query</span>: <span style="color:#66d9ef">string</span>)<span style="color:#f92672">:</span> <span style="color:#a6e22e">Promise</span>&lt;<span style="color:#f92672">string</span>&gt; {
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// think() manages the tool call loop
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">result</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">await</span> <span style="color:#66d9ef">this</span>.<span style="color:#a6e22e">think</span>(<span style="color:#a6e22e">query</span>, {
</span></span><span style="display:flex;"><span>      <span style="color:#a6e22e">tools</span><span style="color:#f92672">:</span> [
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">this</span>.<span style="color:#a6e22e">webSearch</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">this</span>.<span style="color:#a6e22e">readFile</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">this</span>.<span style="color:#a6e22e">writeFile</span>,
</span></span><span style="display:flex;"><span>      ],
</span></span><span style="display:flex;"><span>      <span style="color:#a6e22e">maxSteps</span>: <span style="color:#66d9ef">20</span>,
</span></span><span style="display:flex;"><span>    });
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">result</span>.<span style="color:#a6e22e">output</span>;
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e">// Tool methods are automatically discovered and wrapped
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>  <span style="color:#66d9ef">async</span> <span style="color:#a6e22e">webSearch</span>(<span style="color:#a6e22e">query</span>: <span style="color:#66d9ef">string</span>)<span style="color:#f92672">:</span> <span style="color:#a6e22e">Promise</span>&lt;<span style="color:#f92672">string</span>&gt; {
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// implementation
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>  }
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// Worker export
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">export</span> <span style="color:#66d9ef">default</span> {
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">fetch</span>: <span style="color:#66d9ef">ResearchAgent.mount</span>(<span style="color:#e6db74">&#39;/agent&#39;</span>)
</span></span><span style="display:flex;"><span>};
</span></span></code></pre></div><p>The <code>think()</code> method manages the agent loop: it calls the LLM, executes tool calls, feeds results back to the model, and iterates until the task is complete or <code>maxSteps</code> is reached. The agent&rsquo;s state (conversation history, tool outputs, session tree) persists in the Durable Object&rsquo;s storage, surviving hibernation and resuming on the next wake event.</p>
<p>Wrangler configuration for a Think-based agent requires Durable Objects:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span><span style="color:#a6e22e">name</span> = <span style="color:#e6db74">&#34;my-agent&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">main</span> = <span style="color:#e6db74">&#34;src/index.ts&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">compatibility_date</span> = <span style="color:#e6db74">&#34;2026-04-01&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>[[<span style="color:#a6e22e">durable_objects</span>.<span style="color:#a6e22e">bindings</span>]]
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">name</span> = <span style="color:#e6db74">&#34;AGENT&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">class_name</span> = <span style="color:#e6db74">&#34;ResearchAgent&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>[[<span style="color:#a6e22e">migrations</span>]]
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">tag</span> = <span style="color:#e6db74">&#34;v1&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">new_classes</span> = [<span style="color:#e6db74">&#34;ResearchAgent&#34;</span>]
</span></span></code></pre></div><h2 id="the-execution-ladder-progressive-security-for-ai-generated-code">The Execution Ladder: Progressive Security for AI-Generated Code</h2>
<p>The Execution Ladder is Project Think&rsquo;s model for granting AI agents progressively more powerful code execution capabilities based on trust level and task requirements:</p>
<p><strong>Level 1 — Read-only execution</strong>: The agent can read files, query databases, and call external APIs. No write operations permitted. Default level for new agents.</p>
<p><strong>Level 2 — Isolated write access</strong>: The agent can write to temporary directories within a sandboxed Dynamic Worker. Changes don&rsquo;t persist to the host environment. Appropriate for data transformation tasks.</p>
<p><strong>Level 3 — Full system with audit trail</strong>: The agent can execute arbitrary code, modify files, and interact with the host system, but all operations are logged with full audit trail. Appropriate for code generation and deployment tasks where human review of the audit log is built into the workflow.</p>
<p>The Execution Ladder prevents runaway code execution by requiring explicit escalation. An agent that starts at Level 1 must request Level 2 access and receive approval (manual or automated, depending on configuration) before gaining write capability. This applies even to self-authored extensions — when an agent writes a new tool and wants to execute it, the execution goes through the Execution Ladder rather than running directly in the agent context.</p>
<h2 id="building-modular-agents-with-facets-sub-agents">Building Modular Agents with Facets (Sub-Agents)</h2>
<p>Facets enable multi-agent architectures where specialized agents collaborate. The orchestrator spawns Facets for specific subtasks; Facets maintain their own state and return results to the orchestrator via RPC:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span><span style="color:#66d9ef">export</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">OrchestratorAgent</span> <span style="color:#66d9ef">extends</span> <span style="color:#a6e22e">Think</span> {
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">async</span> <span style="color:#a6e22e">run</span>(<span style="color:#a6e22e">project</span>: <span style="color:#66d9ef">string</span>)<span style="color:#f92672">:</span> <span style="color:#a6e22e">Promise</span>&lt;<span style="color:#f92672">string</span>&gt; {
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Spawn specialized Facets
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">researcher</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">await</span> <span style="color:#66d9ef">this</span>.<span style="color:#a6e22e">facet</span>(<span style="color:#e6db74">&#39;ResearcherFacet&#39;</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">analyst</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">await</span> <span style="color:#66d9ef">this</span>.<span style="color:#a6e22e">facet</span>(<span style="color:#e6db74">&#39;AnalystFacet&#39;</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">writer</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">await</span> <span style="color:#66d9ef">this</span>.<span style="color:#a6e22e">facet</span>(<span style="color:#e6db74">&#39;WriterFacet&#39;</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Fan out to Facets in parallel using Fibers
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    <span style="color:#66d9ef">const</span> [<span style="color:#a6e22e">researchData</span>, <span style="color:#a6e22e">marketData</span>] <span style="color:#f92672">=</span> <span style="color:#66d9ef">await</span> <span style="color:#a6e22e">Promise</span>.<span style="color:#a6e22e">all</span>([
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">this</span>.<span style="color:#a6e22e">fiber</span>(() <span style="color:#f92672">=&gt;</span> <span style="color:#a6e22e">researcher</span>.<span style="color:#a6e22e">research</span>(<span style="color:#a6e22e">project</span>)),
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">this</span>.<span style="color:#a6e22e">fiber</span>(() <span style="color:#f92672">=&gt;</span> <span style="color:#a6e22e">analyst</span>.<span style="color:#a6e22e">marketAnalysis</span>(<span style="color:#a6e22e">project</span>)),
</span></span><span style="display:flex;"><span>    ]);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Writer Facet receives outputs from both
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">report</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">await</span> <span style="color:#a6e22e">writer</span>.<span style="color:#a6e22e">generate</span>({
</span></span><span style="display:flex;"><span>      <span style="color:#a6e22e">research</span>: <span style="color:#66d9ef">researchData</span>,
</span></span><span style="display:flex;"><span>      <span style="color:#a6e22e">market</span>: <span style="color:#66d9ef">marketData</span>,
</span></span><span style="display:flex;"><span>    });
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">report</span>;
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>Each Facet (ResearcherFacet, AnalystFacet, WriterFacet) is its own Durable Object with its own tool set, system prompt, and state. Colocated RPC means the latency between orchestrator and Facets is negligible — unlike HTTP-based multi-agent architectures where each agent-to-agent call adds network overhead.</p>
<h2 id="persistent-sessions-tree-structured-conversations-and-branching">Persistent Sessions: Tree-Structured Conversations and Branching</h2>
<p>The Sessions primitive implements conversation history as a tree rather than a flat array. This enables a key capability: the agent can &ldquo;branch&rdquo; to explore an alternative approach without losing the path not taken.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">session</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">await</span> <span style="color:#66d9ef">this</span>.<span style="color:#a6e22e">session</span>.<span style="color:#a6e22e">create</span>(<span style="color:#e6db74">&#39;task-001&#39;</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// Branch A: try approach 1
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">branchA</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">await</span> <span style="color:#a6e22e">session</span>.<span style="color:#a6e22e">branch</span>();
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">await</span> <span style="color:#a6e22e">branchA</span>.<span style="color:#a6e22e">execute</span>(<span style="color:#a6e22e">approach1</span>);
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">resultA</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">await</span> <span style="color:#a6e22e">branchA</span>.<span style="color:#a6e22e">evaluate</span>();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// Branch B: try approach 2 (from same starting point)
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">branchB</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">await</span> <span style="color:#a6e22e">session</span>.<span style="color:#a6e22e">branch</span>();
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">await</span> <span style="color:#a6e22e">branchB</span>.<span style="color:#a6e22e">execute</span>(<span style="color:#a6e22e">approach2</span>);
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">resultB</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">await</span> <span style="color:#a6e22e">branchB</span>.<span style="color:#a6e22e">evaluate</span>();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// Select the better result and continue from that branch
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">bestBranch</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">resultA</span>.<span style="color:#a6e22e">score</span> <span style="color:#f92672">&gt;</span> <span style="color:#a6e22e">resultB</span>.<span style="color:#a6e22e">score</span> <span style="color:#f92672">?</span> <span style="color:#a6e22e">branchA</span> : <span style="color:#66d9ef">branchB</span>;
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">await</span> <span style="color:#a6e22e">session</span>.<span style="color:#a6e22e">mergeBranch</span>(<span style="color:#a6e22e">bestBranch</span>);
</span></span></code></pre></div><p>Sessions persist in Durable Object storage, making them available across agent restarts and hibernation events. For long-running tasks that span hours, the session tree provides a complete audit trail of every reasoning path the agent explored, which approach was selected, and why — valuable for debugging and compliance.</p>
<h2 id="self-authored-extensions-agents-that-build-their-own-tools">Self-Authored Extensions: Agents That Build Their Own Tools</h2>
<p>Project Think enables agents to write and register new tools at runtime. When an agent encounters a capability it needs but doesn&rsquo;t have, it can generate the tool implementation, register it via the Extensions API, and use it in subsequent steps — without redeployment:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span><span style="color:#75715e">// Agent generates a tool when needed
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">toolCode</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">await</span> <span style="color:#66d9ef">this</span>.<span style="color:#a6e22e">model</span>.<span style="color:#a6e22e">generate</span>(
</span></span><span style="display:flex;"><span>  <span style="color:#e6db74">`Write a TypeScript function that parses CSV files and returns structured data`</span>
</span></span><span style="display:flex;"><span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// Register the generated tool
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">await</span> <span style="color:#66d9ef">this</span>.<span style="color:#a6e22e">extensions</span>.<span style="color:#a6e22e">register</span>({
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">name</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;parseCSV&#39;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">code</span>: <span style="color:#66d9ef">toolCode</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">sandbox</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;level-2&#39;</span>,  <span style="color:#75715e">// Execution Ladder level for this tool
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>});
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// The tool is now available for subsequent steps
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">data</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">await</span> <span style="color:#66d9ef">this</span>.<span style="color:#a6e22e">tools</span>.<span style="color:#a6e22e">parseCSV</span>(<span style="color:#a6e22e">csvContent</span>);
</span></span></code></pre></div><p>All self-authored extensions execute through the Execution Ladder at the specified level — Level 2 by default, requiring explicit escalation to Level 3 for system access. The extensions registry persists in Durable Object storage, so tools the agent creates in one session are available in subsequent sessions.</p>
<h2 id="project-think-vs-aws-bedrock-agentcore-vs-google-adk">Project Think vs AWS Bedrock AgentCore vs Google ADK</h2>
<table>
  <thead>
      <tr>
          <th></th>
          <th>Cloudflare Project Think</th>
          <th>AWS Bedrock AgentCore</th>
          <th>Google ADK</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>Infrastructure</strong></td>
          <td>Cloudflare Workers + Durable Objects</td>
          <td>AWS Lambda + Bedrock</td>
          <td>Google Cloud + Vertex</td>
      </tr>
      <tr>
          <td><strong>State model</strong></td>
          <td>Durable Object (actor model)</td>
          <td>Session service</td>
          <td>Session management</td>
      </tr>
      <tr>
          <td><strong>Sub-agents</strong></td>
          <td>Colocated Durable Objects (RPC)</td>
          <td>Lambda functions (HTTP)</td>
          <td>ADK agents (HTTP)</td>
      </tr>
      <tr>
          <td><strong>Cold start</strong></td>
          <td>~0ms (Durable Objects warm)</td>
          <td>100-500ms (Lambda)</td>
          <td>100-500ms</td>
      </tr>
      <tr>
          <td><strong>Idle billing</strong></td>
          <td>Zero (hibernation)</td>
          <td>Minimal (Lambda)</td>
          <td>Minimal</td>
      </tr>
      <tr>
          <td><strong>Code execution</strong></td>
          <td>Sandboxed Dynamic Workers</td>
          <td>AWS SageMaker/Batch</td>
          <td>Cloud Run</td>
      </tr>
      <tr>
          <td><strong>Best for</strong></td>
          <td>Teams on Cloudflare, latency-sensitive agents</td>
          <td>Teams on AWS, Bedrock models</td>
          <td>Teams on GCP, Gemini-native</td>
      </tr>
  </tbody>
</table>
<p>Project Think&rsquo;s primary advantage is the actor model: Durable Objects never have cold starts after first activation, making agent wake-from-hibernation nearly instant. For agents that sleep for hours between user interactions, this eliminates the cold start latency that Lambda-based architectures introduce.</p>
<h2 id="production-deployment-cost-scheduling-and-hibernation">Production Deployment: Cost, Scheduling, and Hibernation</h2>
<p><strong>Hibernation</strong> is the core cost-control mechanism. When a Think agent has no active requests or scheduled tasks, it hibernates — consuming zero compute billing. The next request or scheduled wake wakes the Durable Object, loading its state from storage. For agents that run tasks on user request rather than continuously, hibernation means you pay only during actual execution.</p>
<p><strong>Scheduling</strong> with Cron triggers runs agents on a schedule without keeping them alive:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span><span style="color:#75715e">// In wrangler.toml
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>[<span style="color:#a6e22e">triggers</span>]
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">crons</span> <span style="color:#f92672">=</span> [<span style="color:#e6db74">&#34;0 9 * * 1&#34;</span>]  <span style="color:#960050;background-color:#1e0010">#</span> <span style="color:#a6e22e">Every</span> <span style="color:#a6e22e">Monday</span> <span style="color:#a6e22e">at</span> <span style="color:#ae81ff">9</span><span style="color:#a6e22e">am</span> <span style="color:#a6e22e">UTC</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// In agent
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">async</span> <span style="color:#a6e22e">scheduled</span>(<span style="color:#a6e22e">event</span>: <span style="color:#66d9ef">ScheduledEvent</span>)<span style="color:#f92672">:</span> <span style="color:#a6e22e">Promise</span>&lt;<span style="color:#f92672">void</span>&gt; {
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">await</span> <span style="color:#66d9ef">this</span>.<span style="color:#a6e22e">run</span>(<span style="color:#e6db74">&#39;generate weekly report&#39;</span>);
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p><strong>Pricing</strong> for a Think-based agent on the Workers Paid plan ($5/month base): Durable Object requests at $0.15/million, Durable Object compute at $12.50/million GB-seconds, Workers AI inference at model-specific rates. For an agent that processes 100 requests per day with 30-second average execution at 128MB: roughly $15-25/month in Durable Object compute, plus model inference costs.</p>
<p><strong>SQLite storage</strong> is available in Durable Objects for agents needing structured state beyond key-value: conversation history, tool outputs, session trees, and extension registries can all use SQLite within the Durable Object, without external database dependencies.</p>
<hr>
<h2 id="faq">FAQ</h2>
<p><strong>What is Cloudflare Project Think?</strong></p>
<p>Project Think is a TypeScript framework in developer preview (April 2026) for building long-running AI agents on Cloudflare Workers infrastructure. It extends Durable Objects with agent-specific primitives: Fibers (parallel execution threads), Facets (colocated sub-agents), Sessions (tree-structured conversation history), and sandboxed code execution via the Execution Ladder. Agents built with Project Think persist state across tool calls and survive hibernation without losing context.</p>
<p><strong>How does Project Think differ from other agent frameworks like LangChain or CrewAI?</strong></p>
<p>Project Think is infrastructure-first rather than framework-first. LangChain and CrewAI provide high-level abstractions for agent logic that run on any infrastructure. Project Think provides lower-level infrastructure primitives (Durable Objects, Fibers, Facets) specifically designed for Cloudflare&rsquo;s deployment model. The advantage: zero cold starts via Durable Objects, zero idle billing via hibernation, and colocated sub-agent RPC. The tradeoff: tighter coupling to Cloudflare infrastructure.</p>
<p><strong>Is Project Think production-ready?</strong></p>
<p>As of April 2026, Project Think is in developer preview — Cloudflare explicitly notes APIs may change as feedback is incorporated. It&rsquo;s suitable for internal tools, prototypes, and teams willing to track API changes. Production deployments in regulated industries or with strict stability requirements should wait for general availability.</p>
<p><strong>What models does Project Think support?</strong></p>
<p>Project Think is model-agnostic. The <code>think()</code> loop works with any LLM that supports tool/function calling via an OpenAI-compatible API. Native integrations exist for Anthropic Claude, OpenAI GPT series, and models available via Cloudflare Workers AI. The agent implementation controls which model it calls; the framework handles state and execution management.</p>
<p><strong>How does billing work for hibernating agents?</strong></p>
<p>Durable Objects hibernate when idle, consuming zero compute billing. You pay only for the time the object is active: processing requests, executing tool calls, or running scheduled tasks. Storage costs (for persisted session state) continue during hibernation at Durable Object storage rates ($0.20/GB-month). For agents with low average utilization, this makes Project Think significantly cheaper than keeping a container or VM running continuously.</p>
]]></content:encoded></item></channel></rss>