agents 0.0.0-7ff0509 → 0.0.0-80a8fbd0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +411 -291
- package/agents.tsconfig.json +18 -0
- package/dist/agent-tool-types-DEBXD2Ta.d.ts +6169 -0
- package/dist/agent-tool-types.d.ts +54 -0
- package/dist/agent-tool-types.js +20 -0
- package/dist/agent-tool-types.js.map +1 -0
- package/dist/agent-tools-krZpfAix.d.ts +133 -0
- package/dist/agent-tools-y7zLfw4Q.js +304 -0
- package/dist/agent-tools-y7zLfw4Q.js.map +1 -0
- package/dist/agent-tools.d.ts +70 -0
- package/dist/agent-tools.js +60 -0
- package/dist/agent-tools.js.map +1 -0
- package/dist/ai-chat-agent.d.ts +1 -36
- package/dist/ai-chat-agent.js +4 -165
- package/dist/ai-chat-agent.js.map +1 -1
- package/dist/ai-chat-v5-migration.d.ts +1 -0
- package/dist/ai-chat-v5-migration.js +6 -0
- package/dist/ai-chat-v5-migration.js.map +1 -0
- package/dist/ai-react.d.ts +1 -88
- package/dist/ai-react.js +4 -187
- package/dist/ai-react.js.map +1 -1
- package/dist/ai-types.d.ts +1 -69
- package/dist/ai-types.js +5 -0
- package/dist/ai-types.js.map +1 -1
- package/dist/browser/ai.d.ts +235 -0
- package/dist/browser/ai.js +265 -0
- package/dist/browser/ai.js.map +1 -0
- package/dist/browser/index.d.ts +146 -0
- package/dist/browser/index.js +3 -0
- package/dist/browser/tanstack-ai.d.ts +41 -0
- package/dist/browser/tanstack-ai.js +57 -0
- package/dist/browser/tanstack-ai.js.map +1 -0
- package/dist/chat/index.d.ts +3392 -0
- package/dist/chat/index.js +3408 -0
- package/dist/chat/index.js.map +1 -0
- package/dist/chat/react.d.ts +602 -0
- package/dist/chat/react.js +1517 -0
- package/dist/chat/react.js.map +1 -0
- package/dist/chat-sdk/index.d.ts +135 -0
- package/dist/chat-sdk/index.js +453 -0
- package/dist/chat-sdk/index.js.map +1 -0
- package/dist/classPrivateFieldGet2-DZBYAB34.js +27 -0
- package/dist/classPrivateMethodInitSpec-qMjJ6sHQ.js +7 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +26 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/client-D8tz8bn3.js +2233 -0
- package/dist/client-D8tz8bn3.js.map +1 -0
- package/dist/client-invoker-BNSZxAkv.d.ts +20 -0
- package/dist/client-invoker-oF0lZZtP.js +57 -0
- package/dist/client-invoker-oF0lZZtP.js.map +1 -0
- package/dist/client-tools-aIBO0Fk7.d.ts +53 -0
- package/dist/client.d.ts +251 -33
- package/dist/client.js +269 -133
- package/dist/client.js.map +1 -1
- package/dist/codemode/ai.d.ts +1 -0
- package/dist/codemode/ai.js +6 -0
- package/dist/codemode/ai.js.map +1 -0
- package/dist/compaction-helpers-iiKMr2TQ.js +340 -0
- package/dist/compaction-helpers-iiKMr2TQ.js.map +1 -0
- package/dist/compaction-helpers-wUz6M3us.d.ts +621 -0
- package/dist/connector-CdldGF3h.js +1291 -0
- package/dist/connector-CdldGF3h.js.map +1 -0
- package/dist/connector-v2M1zlZp.d.ts +659 -0
- package/dist/do-oauth-client-provider-VTZj2VtM.d.ts +110 -0
- package/dist/email-CL27preh.d.ts +157 -0
- package/dist/email.d.ts +30 -0
- package/dist/email.js +222 -0
- package/dist/email.js.map +1 -0
- package/dist/experimental/memory/session/index.d.ts +670 -0
- package/dist/experimental/memory/session/index.js +2374 -0
- package/dist/experimental/memory/session/index.js.map +1 -0
- package/dist/experimental/memory/utils/index.d.ts +96 -0
- package/dist/experimental/memory/utils/index.js +79 -0
- package/dist/experimental/memory/utils/index.js.map +1 -0
- package/dist/experimental/webmcp.d.ts +218 -0
- package/dist/experimental/webmcp.js +298 -0
- package/dist/experimental/webmcp.js.map +1 -0
- package/dist/index-BRnybD6X.d.ts +947 -0
- package/dist/index.d.ts +186 -302
- package/dist/index.js +7151 -20
- package/dist/index.js.map +1 -1
- package/dist/internal_context-Dg4Cgjcu.d.ts +37 -0
- package/dist/internal_context.d.ts +6 -0
- package/dist/internal_context.js +11 -0
- package/dist/internal_context.js.map +1 -0
- package/dist/mcp/client.d.ts +38 -0
- package/dist/mcp/client.js +2 -0
- package/dist/mcp/do-oauth-client-provider.d.ts +10 -0
- package/dist/mcp/do-oauth-client-provider.js +292 -0
- package/dist/mcp/do-oauth-client-provider.js.map +1 -0
- package/dist/mcp/index.d.ts +82 -0
- package/dist/mcp/index.js +2059 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/x402.d.ts +119 -0
- package/dist/mcp/x402.js +260 -0
- package/dist/mcp/x402.js.map +1 -0
- package/dist/message-builder-BymO4N_D.js +386 -0
- package/dist/message-builder-BymO4N_D.js.map +1 -0
- package/dist/observability/index.d.ts +16 -0
- package/dist/observability/index.js +88 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/react.d.ts +232 -21
- package/dist/react.js +479 -93
- package/dist/react.js.map +1 -1
- package/dist/retries-CAvxtG9d.d.ts +127 -0
- package/dist/retries.d.ts +22 -0
- package/dist/retries.js +229 -0
- package/dist/retries.js.map +1 -0
- package/dist/schedule.d.ts +123 -43
- package/dist/schedule.js +71 -23
- package/dist/schedule.js.map +1 -1
- package/dist/serializable.d.ts +141 -0
- package/dist/serializable.js +1 -0
- package/dist/skills/compile.d.ts +40 -0
- package/dist/skills/compile.js +65 -0
- package/dist/skills/compile.js.map +1 -0
- package/dist/skills/index.d.ts +244 -0
- package/dist/skills/index.js +1323 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/sub-routing.d.ts +14 -0
- package/dist/sub-routing.js +177 -0
- package/dist/sub-routing.js.map +1 -0
- package/dist/tool-output-truncation-CNnnGZQ3.js +98 -0
- package/dist/tool-output-truncation-CNnnGZQ3.js.map +1 -0
- package/dist/types-6Zo2zfoO.d.ts +17 -0
- package/dist/types.d.ts +2 -0
- package/dist/types.js +19 -0
- package/dist/types.js.map +1 -0
- package/dist/utils-CGtGDSgA.d.ts +34 -0
- package/dist/utils.d.ts +6 -0
- package/dist/utils.js +51 -0
- package/dist/utils.js.map +1 -0
- package/dist/vite.d.ts +25 -0
- package/dist/vite.js +310 -0
- package/dist/vite.js.map +1 -0
- package/dist/wire-types-nflOzNuU.js +240 -0
- package/dist/wire-types-nflOzNuU.js.map +1 -0
- package/dist/workflow-types-Baz_PO5v.d.ts +280 -0
- package/dist/workflow-types.d.ts +52 -0
- package/dist/workflow-types.js +16 -0
- package/dist/workflow-types.js.map +1 -0
- package/dist/workflows.d.ts +198 -0
- package/dist/workflows.js +343 -0
- package/dist/workflows.js.map +1 -0
- package/docs/adding-to-existing-project.md +450 -0
- package/docs/agent-class.md +503 -0
- package/docs/agent-tools.md +552 -0
- package/docs/browse-the-web.md +430 -0
- package/docs/callable-methods.md +627 -0
- package/docs/chat-agents.md +1696 -0
- package/docs/chat-sdk.md +181 -0
- package/docs/client-sdk.md +520 -0
- package/docs/client-tools-continuation.md +177 -0
- package/docs/codemode.md +440 -0
- package/docs/configuration.md +795 -0
- package/docs/cross-domain-authentication.md +171 -0
- package/docs/durable-execution.md +537 -0
- package/docs/email.md +663 -0
- package/docs/get-current-agent.md +204 -0
- package/docs/getting-started.md +305 -0
- package/docs/http-websockets.md +668 -0
- package/docs/human-in-the-loop.md +661 -0
- package/docs/index.md +151 -0
- package/docs/long-running-agents.md +730 -0
- package/docs/mcp-client.md +683 -0
- package/docs/mcp-servers.md +548 -0
- package/docs/mcp-transports.md +308 -0
- package/docs/migration-to-ai-sdk-v5.md +96 -0
- package/docs/migration-to-ai-sdk-v6.md +163 -0
- package/docs/observability.md +261 -0
- package/docs/push-notifications.md +367 -0
- package/docs/queue.md +329 -0
- package/docs/readonly-connections.md +278 -0
- package/docs/resumable-streaming.md +127 -0
- package/docs/retries.md +444 -0
- package/docs/routing.md +749 -0
- package/docs/scheduling.md +898 -0
- package/docs/securing-mcp-servers.md +362 -0
- package/docs/server-driven-messages.md +477 -0
- package/docs/sessions.md +1024 -0
- package/docs/state.md +512 -0
- package/docs/sub-agents.md +389 -0
- package/docs/webhooks.md +604 -0
- package/docs/workflows.md +877 -0
- package/package.json +279 -48
- package/skills-module.d.ts +22 -0
- package/dist/chunk-HMLY7DHA.js +0 -16
- package/dist/chunk-HMLY7DHA.js.map +0 -1
- package/dist/chunk-KRBQHBPA.js +0 -599
- package/dist/chunk-KRBQHBPA.js.map +0 -1
- package/dist/mcp.d.ts +0 -58
- package/dist/mcp.js +0 -945
- package/dist/mcp.js.map +0 -1
- package/src/index.ts +0 -925
package/README.md
CHANGED
|
@@ -1,428 +1,548 @@
|
|
|
1
|
-
|
|
1
|
+
# agents
|
|
2
2
|
|
|
3
|
-

|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**Build software that thinks and does.**
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Persistent AI agents on Cloudflare's global network. They remember context, reason through problems, schedule their own work, and take action—all without you managing servers.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
```sh
|
|
10
|
+
npm create cloudflare@latest -- --template cloudflare/agents-starter
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Or add to an existing project:
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
npm install agents
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
---
|
|
10
20
|
|
|
11
|
-
|
|
21
|
+
## Why Agents, Why Now
|
|
12
22
|
|
|
13
|
-
|
|
14
|
-
- **Agency**: Acts autonomously within its defined purpose
|
|
15
|
-
- **Connection**: Communicates through multiple channels with both humans and other agents
|
|
16
|
-
- **Growth**: Learns and adapts through its interactions
|
|
23
|
+
LLMs can reason, plan, and use tools—but they need infrastructure that matches their capabilities. Traditional serverless is stateless and ephemeral. Agents are persistent and purposeful.
|
|
17
24
|
|
|
18
|
-
|
|
25
|
+
```
|
|
26
|
+
From request handlers → to autonomous entities
|
|
27
|
+
From stateless functions → to persistent intelligence
|
|
28
|
+
|
|
29
|
+
Traditional serverless: Request → Response → Gone
|
|
30
|
+
Agents: Thinking, remembering, acting — continuously
|
|
31
|
+
```
|
|
19
32
|
|
|
20
|
-
|
|
33
|
+
**Pay only when active.** Agents hibernate between requests. You can have millions of agents—one per user, per session, per game room—each costs nothing when idle.
|
|
21
34
|
|
|
22
|
-
|
|
23
|
-
2. **Long-lived Presence**: Agents can run for extended periods, resting when idle
|
|
24
|
-
3. **Natural Communication**: Interact through HTTP, WebSockets, or direct calls
|
|
25
|
-
4. **Global Distribution**: Leverage Cloudflare's network for worldwide presence
|
|
26
|
-
5. **Resource Harmony**: Efficient hibernation and awakening as needed
|
|
35
|
+
Built on Cloudflare Durable Objects, agents run globally, close to your users, with persistent state that survives restarts.
|
|
27
36
|
|
|
28
37
|
---
|
|
29
38
|
|
|
30
|
-
|
|
39
|
+
## Quick Example
|
|
31
40
|
|
|
32
|
-
|
|
41
|
+
A counter agent with real-time state sync and callable methods:
|
|
33
42
|
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
|
|
43
|
+
```typescript
|
|
44
|
+
// server.ts
|
|
45
|
+
import { Agent, callable } from "agents";
|
|
37
46
|
|
|
38
|
-
|
|
39
|
-
|
|
47
|
+
type State = { count: number };
|
|
48
|
+
|
|
49
|
+
export class CounterAgent extends Agent<Env, State> {
|
|
50
|
+
initialState: State = { count: 0 };
|
|
51
|
+
|
|
52
|
+
@callable()
|
|
53
|
+
increment() {
|
|
54
|
+
this.setState({ count: this.state.count + 1 });
|
|
55
|
+
return this.state.count;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@callable()
|
|
59
|
+
decrement() {
|
|
60
|
+
this.setState({ count: this.state.count - 1 });
|
|
61
|
+
return this.state.count;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
40
64
|
```
|
|
41
65
|
|
|
42
|
-
|
|
66
|
+
```tsx
|
|
67
|
+
// client.tsx
|
|
68
|
+
import { useAgent } from "agents/react";
|
|
69
|
+
import { useState } from "react";
|
|
43
70
|
|
|
44
|
-
|
|
71
|
+
function Counter() {
|
|
72
|
+
const [count, setCount] = useState(0);
|
|
45
73
|
|
|
46
|
-
|
|
47
|
-
|
|
74
|
+
const agent = useAgent<State>({
|
|
75
|
+
agent: "counter-agent",
|
|
76
|
+
name: "my-counter",
|
|
77
|
+
onStateUpdate: (state) => setCount(state.count)
|
|
78
|
+
});
|
|
48
79
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
80
|
+
return (
|
|
81
|
+
<div>
|
|
82
|
+
<span>{count}</span>
|
|
83
|
+
<button onClick={() => agent.stub.increment()}>+</button>
|
|
84
|
+
<button onClick={() => agent.stub.decrement()}>-</button>
|
|
85
|
+
</div>
|
|
86
|
+
);
|
|
54
87
|
}
|
|
55
88
|
```
|
|
56
89
|
|
|
57
|
-
|
|
90
|
+
State changes sync to all connected clients automatically. Call methods like they're local functions.
|
|
58
91
|
|
|
59
|
-
|
|
92
|
+
---
|
|
60
93
|
|
|
61
|
-
|
|
62
|
-
import { Agent } from "agents";
|
|
63
|
-
import { OpenAI } from "openai";
|
|
94
|
+
## What You Can Build
|
|
64
95
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
96
|
+
| Use Case | Why Agents |
|
|
97
|
+
| ---------------------- | ----------------------------------------------------- |
|
|
98
|
+
| Multiplayer game rooms | Per-room state, real-time sync, hibernates when empty |
|
|
99
|
+
| Customer support bots | Remembers conversation history, escalates to humans |
|
|
100
|
+
| Collaborative editors | Presence, cursors, document state |
|
|
101
|
+
| Approval workflows | Long-running, pauses for human input, durable |
|
|
102
|
+
| Personal AI assistants | Per-user memory, tool access via MCP |
|
|
103
|
+
| Notification systems | Scheduled delivery, user preferences, retry logic |
|
|
71
104
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Features
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
Core State sync · Routing · HTTP & WebSockets · @callable RPC · Sub-agents (facets)
|
|
111
|
+
Clients React hook · Vanilla JS · Real-time state sync
|
|
112
|
+
Channels WebSocket · HTTP · Email · (coming: SMS, Voice, Messengers)
|
|
113
|
+
Background Queue · Scheduling · Managed fibers · Workflows · Human-in-the-loop
|
|
114
|
+
AI Chat agents · Agent tools · Tool calling · MCP servers & clients
|
|
115
|
+
Platform Observability · Cross-domain auth · Resumable streams
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### State Management
|
|
77
119
|
|
|
78
|
-
|
|
120
|
+
State persists across requests and syncs to all connected clients:
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
export class MyAgent extends Agent<Env, { items: string[] }> {
|
|
124
|
+
initialState = { items: [] };
|
|
125
|
+
|
|
126
|
+
@callable()
|
|
127
|
+
addItem(item: string) {
|
|
128
|
+
this.setState({ items: [...this.state.items, item] });
|
|
79
129
|
}
|
|
80
130
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
await this.act();
|
|
84
|
-
await this.reflect();
|
|
131
|
+
onStateChanged(state: State, source: Connection | "server") {
|
|
132
|
+
// Called after state is persisted and broadcast
|
|
85
133
|
}
|
|
86
134
|
}
|
|
87
135
|
```
|
|
88
136
|
|
|
89
|
-
###
|
|
137
|
+
### Callable Methods
|
|
90
138
|
|
|
91
|
-
|
|
139
|
+
Expose methods to clients with the `@callable()` decorator:
|
|
92
140
|
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
"class_name": "AIAgent",
|
|
100
|
-
},
|
|
101
|
-
],
|
|
102
|
-
},
|
|
103
|
-
"migrations": [
|
|
104
|
-
{
|
|
105
|
-
"tag": "v1",
|
|
106
|
-
// Mandatory for the Agent to store state
|
|
107
|
-
"new_sqlite_classes": ["AIAgent"],
|
|
108
|
-
},
|
|
109
|
-
],
|
|
141
|
+
```typescript
|
|
142
|
+
@callable()
|
|
143
|
+
async processOrder(orderId: string, items: Item[]) {
|
|
144
|
+
// Full type safety - clients call this like a local function
|
|
145
|
+
const result = await this.validateAndProcess(orderId, items);
|
|
146
|
+
return result;
|
|
110
147
|
}
|
|
111
148
|
```
|
|
112
149
|
|
|
113
|
-
|
|
150
|
+
```typescript
|
|
151
|
+
// Client
|
|
152
|
+
const result = await agent.stub.processOrder("order-123", items);
|
|
153
|
+
```
|
|
114
154
|
|
|
115
|
-
|
|
155
|
+
### Scheduling
|
|
116
156
|
|
|
117
|
-
|
|
118
|
-
// Create a new instance
|
|
119
|
-
const id = env.AIAgent.newUniqueId();
|
|
120
|
-
const agent = env.AIAgent.get(id);
|
|
157
|
+
Run tasks later, on intervals, or with cron expressions:
|
|
121
158
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
context: "incoming_data",
|
|
126
|
-
parameters: initialConfig,
|
|
127
|
-
});
|
|
159
|
+
```typescript
|
|
160
|
+
// In 60 seconds
|
|
161
|
+
this.schedule(60, "sendReminder", { userId: "123" });
|
|
128
162
|
|
|
129
|
-
//
|
|
130
|
-
|
|
131
|
-
```
|
|
163
|
+
// Every hour
|
|
164
|
+
this.scheduleEvery(3600, "syncData");
|
|
132
165
|
|
|
133
|
-
|
|
166
|
+
// Daily at 9am UTC
|
|
167
|
+
this.schedule("0 9 * * *", "dailyReport");
|
|
134
168
|
|
|
135
|
-
|
|
169
|
+
// At a specific date
|
|
170
|
+
this.schedule(new Date("2025-12-31"), "yearEndTask");
|
|
171
|
+
```
|
|
136
172
|
|
|
137
|
-
|
|
173
|
+
### Background Tasks
|
|
138
174
|
|
|
139
|
-
|
|
140
|
-
export class APIAgent extends Agent {
|
|
141
|
-
async onRequest(request) {
|
|
142
|
-
const data = await request.json();
|
|
175
|
+
Queue immediate background work:
|
|
143
176
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
}
|
|
177
|
+
```typescript
|
|
178
|
+
await this.queue("processUpload", { fileId: "abc" });
|
|
179
|
+
// Returns immediately, task runs in background
|
|
150
180
|
```
|
|
151
181
|
|
|
152
|
-
|
|
182
|
+
### Sub-agents
|
|
153
183
|
|
|
154
|
-
|
|
184
|
+
Spawn child Durable Objects (facets) from a parent agent. Each child has
|
|
185
|
+
its own SQLite storage and runs in parallel, but is addressed under the
|
|
186
|
+
parent's URL:
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
export class Inbox extends Agent {
|
|
190
|
+
@callable()
|
|
191
|
+
async createChat() {
|
|
192
|
+
const id = crypto.randomUUID();
|
|
193
|
+
await this.subAgent(Chat, id);
|
|
194
|
+
return id;
|
|
195
|
+
}
|
|
155
196
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
197
|
+
override async onBeforeSubAgent(_req, { className, name }) {
|
|
198
|
+
if (!this.hasSubAgent(className, name)) {
|
|
199
|
+
return new Response("Not found", { status: 404 });
|
|
200
|
+
}
|
|
160
201
|
}
|
|
202
|
+
}
|
|
161
203
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
await this.
|
|
204
|
+
export class Chat extends Agent {
|
|
205
|
+
async writePreview(text: string) {
|
|
206
|
+
const inbox = await this.parentAgent(Inbox);
|
|
207
|
+
await inbox.savePreview(this.name, text);
|
|
165
208
|
}
|
|
166
209
|
}
|
|
167
210
|
```
|
|
168
211
|
|
|
169
|
-
|
|
212
|
+
Client-side, connect to a child with `useAgent({ sub: [...] })`:
|
|
170
213
|
|
|
171
|
-
|
|
214
|
+
```tsx
|
|
215
|
+
const inbox = useAgent({ agent: "Inbox", name: userId });
|
|
216
|
+
const chat = useAgent({
|
|
217
|
+
agent: "Inbox",
|
|
218
|
+
name: userId,
|
|
219
|
+
sub: [{ agent: "Chat", name: chatId }]
|
|
220
|
+
});
|
|
221
|
+
```
|
|
172
222
|
|
|
173
|
-
|
|
174
|
-
import { AgentClient } from "agents/client";
|
|
223
|
+
The routed URL becomes `/agents/inbox/{userId}/sub/chat/{chatId}`.
|
|
175
224
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
225
|
+
Child WebSocket clients can use the same URL shape. The parent remains the
|
|
226
|
+
public address, while child agents still receive `onConnect`, `onMessage`,
|
|
227
|
+
`onClose`, `broadcast()`, and `getConnections()` calls scoped to their own
|
|
228
|
+
clients. Parent broadcasts do not leak to child-targeted sockets, and child
|
|
229
|
+
connection tags, readonly state, and protocol-message settings are preserved
|
|
230
|
+
when a connection is resumed from hibernation.
|
|
180
231
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
});
|
|
232
|
+
Nested sub-agent URLs are supported using repeated `/sub/{agent}/{name}`
|
|
233
|
+
segments, subject to the platform's current facet nesting limits.
|
|
184
234
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
235
|
+
### Agent Tools
|
|
236
|
+
|
|
237
|
+
Run chat-capable sub-agents as tools from a parent chat agent. Think agents and
|
|
238
|
+
`AIChatAgent` subclasses are supported. The child keeps its own messages, tools,
|
|
239
|
+
SQLite storage, and resumable stream, while the parent broadcasts
|
|
240
|
+
`agent-tool-event` frames so the UI can render the child timeline inline.
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
import { Think } from "@cloudflare/think";
|
|
244
|
+
import { agentTool } from "agents/agent-tools";
|
|
245
|
+
import { z } from "zod";
|
|
246
|
+
|
|
247
|
+
export class Researcher extends Think<Env> {
|
|
248
|
+
getSystemPrompt() {
|
|
249
|
+
return "Research the requested topic and end with a concise summary.";
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
export class Assistant extends Think<Env> {
|
|
254
|
+
getTools() {
|
|
255
|
+
return {
|
|
256
|
+
research: agentTool(Researcher, {
|
|
257
|
+
description: "Research one topic in depth.",
|
|
258
|
+
inputSchema: z.object({ query: z.string().min(3) })
|
|
259
|
+
})
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
}
|
|
191
263
|
```
|
|
192
264
|
|
|
193
|
-
|
|
265
|
+
For deterministic fan-out, call `this.runAgentTool(Researcher, { input })`
|
|
266
|
+
directly. Parent recovery reconciles stale child rows after restarts and marks
|
|
267
|
+
unrecoverable runs `interrupted` instead of hanging. In React, use
|
|
268
|
+
`useAgentToolEvents({ agent })` to render retained and replayed child timelines.
|
|
269
|
+
AIChatAgent children run headlessly, so browser client tools require a separate
|
|
270
|
+
bridge; server-side tools work normally. See the full
|
|
271
|
+
[Agent Tools guide](../../docs/agents/agent-tools.md).
|
|
194
272
|
|
|
195
|
-
|
|
273
|
+
### WebSocket Connections
|
|
196
274
|
|
|
197
|
-
|
|
198
|
-
import { useAgent } from "agents/react";
|
|
275
|
+
Handle real-time communication:
|
|
199
276
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
onMessage: (message) => {
|
|
205
|
-
console.log("Understanding received:", message.data);
|
|
206
|
-
},
|
|
207
|
-
onOpen: () => console.log("Connection established"),
|
|
208
|
-
onClose: () => console.log("Connection closed"),
|
|
209
|
-
});
|
|
277
|
+
```typescript
|
|
278
|
+
async onConnect(connection: Connection) {
|
|
279
|
+
console.log(`Client ${connection.id} connected`);
|
|
280
|
+
}
|
|
210
281
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
content: "What insights have you gathered?",
|
|
216
|
-
})
|
|
217
|
-
);
|
|
218
|
-
};
|
|
282
|
+
async onMessage(connection: Connection, message: unknown) {
|
|
283
|
+
// Handle incoming messages
|
|
284
|
+
connection.send(JSON.stringify({ received: true }));
|
|
285
|
+
}
|
|
219
286
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
<button onClick={inquire}>Seek Understanding</button>
|
|
223
|
-
</div>
|
|
224
|
-
);
|
|
287
|
+
async onClose(connection: Connection) {
|
|
288
|
+
console.log(`Client ${connection.id} disconnected`);
|
|
225
289
|
}
|
|
226
290
|
```
|
|
227
291
|
|
|
228
|
-
###
|
|
229
|
-
|
|
230
|
-
Maintain and evolve your agent's understanding:
|
|
292
|
+
### Email
|
|
231
293
|
|
|
232
|
-
|
|
233
|
-
export class ThinkingAgent extends Agent {
|
|
234
|
-
async evolve(newInsight) {
|
|
235
|
-
this.setState({
|
|
236
|
-
...this.state,
|
|
237
|
-
insights: [...(this.state.insights || []), newInsight],
|
|
238
|
-
understanding: this.state.understanding + 1,
|
|
239
|
-
});
|
|
240
|
-
}
|
|
294
|
+
Agents can receive and respond to emails:
|
|
241
295
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
}
|
|
296
|
+
```typescript
|
|
297
|
+
async onEmail(email: EmailMessage) {
|
|
298
|
+
const from = email.from;
|
|
299
|
+
const subject = email.headers.get("subject");
|
|
300
|
+
// Process incoming email
|
|
248
301
|
}
|
|
249
302
|
```
|
|
250
303
|
|
|
251
|
-
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## Client SDK
|
|
307
|
+
|
|
308
|
+
### React
|
|
252
309
|
|
|
253
310
|
```tsx
|
|
254
|
-
import { useState } from "react";
|
|
255
311
|
import { useAgent } from "agents/react";
|
|
312
|
+
import { useState } from "react";
|
|
256
313
|
|
|
257
|
-
function
|
|
258
|
-
const [state, setState] = useState
|
|
314
|
+
function App() {
|
|
315
|
+
const [state, setState] = useState<MyState | null>(null);
|
|
259
316
|
|
|
260
|
-
const agent = useAgent({
|
|
261
|
-
agent: "
|
|
262
|
-
|
|
317
|
+
const agent = useAgent<MyState>({
|
|
318
|
+
agent: "my-agent",
|
|
319
|
+
name: "instance-name",
|
|
320
|
+
onStateUpdate: (newState) => setState(newState)
|
|
263
321
|
});
|
|
264
322
|
|
|
265
|
-
const increment = () => {
|
|
266
|
-
agent.setState({ counter: state.counter + 1 });
|
|
267
|
-
};
|
|
268
|
-
|
|
269
323
|
return (
|
|
270
324
|
<div>
|
|
271
|
-
<
|
|
272
|
-
<button onClick={
|
|
325
|
+
<pre>{JSON.stringify(state, null, 2)}</pre>
|
|
326
|
+
<button onClick={() => agent.stub.doSomething()}>Call Agent</button>
|
|
273
327
|
</div>
|
|
274
328
|
);
|
|
275
329
|
}
|
|
276
330
|
```
|
|
277
331
|
|
|
278
|
-
|
|
332
|
+
### Vanilla JavaScript
|
|
279
333
|
|
|
280
|
-
|
|
334
|
+
```typescript
|
|
335
|
+
import { AgentClient } from "agents/client";
|
|
281
336
|
|
|
282
|
-
|
|
337
|
+
const client = new AgentClient({
|
|
338
|
+
agent: "my-agent",
|
|
339
|
+
name: "instance-name",
|
|
340
|
+
onStateUpdate: (state) => console.log("State:", state)
|
|
341
|
+
});
|
|
283
342
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
async initialize() {
|
|
287
|
-
// Quick reflection
|
|
288
|
-
this.schedule(10, "quickInsight", { focus: "patterns" });
|
|
343
|
+
// Call methods
|
|
344
|
+
const result = await client.call("processData", [payload]);
|
|
289
345
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
});
|
|
346
|
+
// Or use the stub
|
|
347
|
+
const result = await client.stub.processData(payload);
|
|
348
|
+
```
|
|
294
349
|
|
|
295
|
-
|
|
296
|
-
this.schedule(new Date("2024-12-31"), "yearlyAnalysis");
|
|
297
|
-
}
|
|
350
|
+
---
|
|
298
351
|
|
|
299
|
-
|
|
300
|
-
await this.analyze(data.focus);
|
|
301
|
-
}
|
|
352
|
+
## Workflows Integration
|
|
302
353
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
354
|
+
For durable, multi-step tasks that survive failures and can pause for human approval, integrate with [Cloudflare Workflows](https://developers.cloudflare.com/workflows/):
|
|
355
|
+
|
|
356
|
+
```typescript
|
|
357
|
+
import { AgentWorkflow } from "agents";
|
|
358
|
+
|
|
359
|
+
export class OrderWorkflow extends AgentWorkflow<OrderAgent, OrderParams> {
|
|
360
|
+
async run(event, step) {
|
|
361
|
+
// Step 1: Validate (retries automatically on failure)
|
|
362
|
+
const validated = await step.do("validate", async () => {
|
|
363
|
+
return validateOrder(event.payload);
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
// Step 2: Wait for human approval
|
|
367
|
+
await this.reportProgress({ step: "approval", status: "pending" });
|
|
368
|
+
const approval = await this.waitForApproval(step, { timeout: "7 days" });
|
|
306
369
|
|
|
307
|
-
|
|
308
|
-
await
|
|
370
|
+
// Step 3: Process the approved order
|
|
371
|
+
await step.do("process", async () => {
|
|
372
|
+
return processOrder(validated, approval);
|
|
373
|
+
});
|
|
309
374
|
}
|
|
310
375
|
}
|
|
311
376
|
```
|
|
312
377
|
|
|
313
|
-
|
|
378
|
+
Workflows provide:
|
|
379
|
+
|
|
380
|
+
- **Durable execution** — steps retry automatically, state persists across failures
|
|
381
|
+
- **Human-in-the-loop** — pause for approval with `waitForApproval()`
|
|
382
|
+
- **Long-running tasks** — run for days or weeks
|
|
383
|
+
- **Progress tracking** — report status back to the agent
|
|
384
|
+
|
|
385
|
+
See [Workflows](../../docs/agents/workflows.md) and [Human in the Loop](../../docs/agents/human-in-the-loop.md).
|
|
386
|
+
|
|
387
|
+
---
|
|
388
|
+
|
|
389
|
+
## AI Chat Integration
|
|
314
390
|
|
|
315
|
-
|
|
391
|
+
For AI-powered chat experiences with persistent conversations, streaming responses, and tool support, see [`@cloudflare/ai-chat`](../ai-chat/README.md).
|
|
316
392
|
|
|
317
|
-
```
|
|
318
|
-
import { AIChatAgent } from "
|
|
319
|
-
import { openai } from "@ai-sdk/openai";
|
|
393
|
+
```typescript
|
|
394
|
+
import { AIChatAgent } from "@cloudflare/ai-chat";
|
|
320
395
|
|
|
321
|
-
export class
|
|
396
|
+
export class ChatAgent extends AIChatAgent<Env> {
|
|
322
397
|
async onChatMessage(onFinish) {
|
|
323
|
-
return
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
onFinish, // call onFinish so that messages get saved
|
|
329
|
-
});
|
|
330
|
-
|
|
331
|
-
stream.mergeIntoDataStream(dataStream);
|
|
332
|
-
},
|
|
398
|
+
return streamText({
|
|
399
|
+
model: openai("gpt-4o"),
|
|
400
|
+
messages: this.messages,
|
|
401
|
+
tools: this.tools,
|
|
402
|
+
onFinish
|
|
333
403
|
});
|
|
334
404
|
}
|
|
335
405
|
}
|
|
336
406
|
```
|
|
337
407
|
|
|
338
|
-
|
|
408
|
+
```tsx
|
|
409
|
+
// Client
|
|
410
|
+
import { useAgentChat } from "@cloudflare/ai-chat/react";
|
|
339
411
|
|
|
340
|
-
|
|
412
|
+
const { messages, input, handleSubmit } = useAgentChat({
|
|
413
|
+
agent: useAgent({ agent: "chat-agent" })
|
|
414
|
+
});
|
|
415
|
+
```
|
|
341
416
|
|
|
342
|
-
|
|
343
|
-
import { useAgent } from "agents/react";
|
|
344
|
-
import { useAgentChat } from "agents/ai-react";
|
|
417
|
+
Features:
|
|
345
418
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
});
|
|
419
|
+
- Automatic message persistence
|
|
420
|
+
- Resumable streaming (survives disconnections)
|
|
421
|
+
- Server and client-side tool execution
|
|
422
|
+
- Human-in-the-loop approval for sensitive tools
|
|
351
423
|
|
|
352
|
-
|
|
353
|
-
const { messages, input, handleInputChange, handleSubmit, clearHistory } =
|
|
354
|
-
useAgentChat({
|
|
355
|
-
agent,
|
|
356
|
-
maxSteps: 5,
|
|
357
|
-
});
|
|
424
|
+
---
|
|
358
425
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
426
|
+
## MCP (Model Context Protocol)
|
|
427
|
+
|
|
428
|
+
Agents integrate with MCP to act as servers (providing tools to AI assistants) or clients (using tools from other services).
|
|
429
|
+
|
|
430
|
+
### Creating an MCP Server
|
|
431
|
+
|
|
432
|
+
```typescript
|
|
433
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
434
|
+
import { McpAgent } from "agents/mcp";
|
|
435
|
+
|
|
436
|
+
export class MyMCP extends McpAgent<Env, State, {}> {
|
|
437
|
+
server = new McpServer({ name: "my-tools", version: "1.0.0" });
|
|
438
|
+
|
|
439
|
+
async init() {
|
|
440
|
+
this.server.registerTool(
|
|
441
|
+
"lookup",
|
|
442
|
+
{ description: "Look up data", inputSchema: { query: z.string() } },
|
|
443
|
+
async ({ query }) => {
|
|
444
|
+
const result = await this.search(query);
|
|
445
|
+
return { content: [{ type: "text", text: result }] };
|
|
446
|
+
}
|
|
447
|
+
);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
export default MyMCP.serve("/mcp", { binding: "MyMCP" });
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
### Using MCP Tools
|
|
455
|
+
|
|
456
|
+
```typescript
|
|
457
|
+
// Connect to external MCP servers
|
|
458
|
+
await this.addMcpServer(
|
|
459
|
+
"weather-service",
|
|
460
|
+
"https://weather-mcp.example.com/mcp",
|
|
461
|
+
{
|
|
462
|
+
transport: { type: "streamable-http" }
|
|
463
|
+
}
|
|
464
|
+
);
|
|
465
|
+
|
|
466
|
+
// Use with AI SDK
|
|
467
|
+
const result = await generateText({
|
|
468
|
+
model: openai("gpt-4o"),
|
|
469
|
+
tools: this.mcp.getTools(),
|
|
470
|
+
prompt: "What's the weather in Tokyo?"
|
|
471
|
+
});
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
---
|
|
475
|
+
|
|
476
|
+
## Configuration
|
|
477
|
+
|
|
478
|
+
Add your agent to `wrangler.jsonc`:
|
|
479
|
+
|
|
480
|
+
```jsonc
|
|
481
|
+
{
|
|
482
|
+
"durable_objects": {
|
|
483
|
+
"bindings": [{ "name": "MyAgent", "class_name": "MyAgent" }]
|
|
484
|
+
},
|
|
485
|
+
"migrations": [{ "tag": "v1", "new_sqlite_classes": ["MyAgent"] }]
|
|
386
486
|
}
|
|
387
487
|
```
|
|
388
488
|
|
|
389
|
-
|
|
489
|
+
Route requests to your agent:
|
|
390
490
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
491
|
+
```typescript
|
|
492
|
+
import { routeAgentRequest } from "agents";
|
|
493
|
+
|
|
494
|
+
export default {
|
|
495
|
+
async fetch(request: Request, env: Env) {
|
|
496
|
+
return (
|
|
497
|
+
(await routeAgentRequest(request, env)) ??
|
|
498
|
+
new Response("Not found", { status: 404 })
|
|
499
|
+
);
|
|
500
|
+
}
|
|
501
|
+
};
|
|
502
|
+
```
|
|
395
503
|
|
|
396
|
-
|
|
504
|
+
---
|
|
397
505
|
|
|
398
|
-
|
|
506
|
+
## Coming Soon
|
|
399
507
|
|
|
400
|
-
|
|
508
|
+
- **Browse the Web** — Headless browser for web scraping and automation
|
|
509
|
+
- **Cloudflare Sandboxes** — Isolated environments for code execution
|
|
510
|
+
- **SMS, Voice, Messengers** — Multi-channel communication
|
|
401
511
|
|
|
402
|
-
|
|
403
|
-
- **Email Discourse**: Automated email interaction and response
|
|
404
|
-
- **Deep Memory**: Long-term context and relationship understanding
|
|
512
|
+
---
|
|
405
513
|
|
|
406
|
-
|
|
514
|
+
## Learn More
|
|
407
515
|
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
- **Private Realms**: Complete self-hosting guide
|
|
516
|
+
The published package includes the complete documentation tree at
|
|
517
|
+
`docs/index.md`.
|
|
411
518
|
|
|
412
|
-
|
|
519
|
+
[Getting Started](../../docs/agents/getting-started.md) ·
|
|
520
|
+
[State Management](../../docs/agents/state.md) ·
|
|
521
|
+
[Scheduling](../../docs/agents/scheduling.md) ·
|
|
522
|
+
[Callable Methods](../../docs/agents/callable-methods.md) ·
|
|
523
|
+
[MCP Integration](../../docs/agents/mcp-client.md) ·
|
|
524
|
+
[Full Documentation](../../docs/agents/index.md)
|
|
413
525
|
|
|
414
|
-
|
|
526
|
+
---
|
|
415
527
|
|
|
416
|
-
|
|
528
|
+
## Contributing
|
|
417
529
|
|
|
418
|
-
Contributions are welcome,
|
|
530
|
+
Contributions are welcome, especially when:
|
|
419
531
|
|
|
420
|
-
- You
|
|
421
|
-
-
|
|
422
|
-
- You're
|
|
532
|
+
- You've opened an issue as an RFC to discuss your proposal
|
|
533
|
+
- The contribution isn't "AI slop" — LLMs are tools, but vibe-coded PRs won't meet the quality bar
|
|
534
|
+
- You're open to feedback to ensure changes fit the SDK's goals
|
|
423
535
|
|
|
424
536
|
Small fixes, type bugs, and documentation improvements can be raised directly as PRs.
|
|
425
537
|
|
|
426
|
-
|
|
538
|
+
---
|
|
539
|
+
|
|
540
|
+
## License
|
|
541
|
+
|
|
542
|
+
MIT licensed. See the [LICENSE](../../LICENSE) file for details.
|
|
543
|
+
|
|
544
|
+
---
|
|
427
545
|
|
|
428
|
-
|
|
546
|
+
<p align="center">
|
|
547
|
+
<i>Build something that thinks. Ship something that does.</i>
|
|
548
|
+
</p>
|