agents 0.16.2 → 0.17.0
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 +11 -8
- package/dist/{agent-tool-types-CTw3UJUP.d.ts → agent-tool-types-Cd1TZPfB.d.ts} +587 -137
- package/dist/agent-tool-types.d.ts +34 -18
- package/dist/agent-tool-types.js +20 -1
- package/dist/agent-tool-types.js.map +1 -0
- package/dist/agent-tools-BXlsuX0d.js +304 -0
- package/dist/agent-tools-BXlsuX0d.js.map +1 -0
- package/dist/agent-tools-_E8wxUIK.d.ts +119 -0
- package/dist/agent-tools.d.ts +24 -18
- package/dist/agent-tools.js.map +1 -1
- package/dist/ai-chat-agent.d.ts +1 -1
- package/dist/ai-chat-agent.js +1 -2
- package/dist/ai-chat-agent.js.map +1 -1
- package/dist/ai-chat-v5-migration.d.ts +1 -1
- package/dist/ai-chat-v5-migration.js +1 -2
- package/dist/ai-chat-v5-migration.js.map +1 -1
- package/dist/ai-react.d.ts +1 -1
- package/dist/ai-react.js +1 -2
- package/dist/ai-react.js.map +1 -1
- package/dist/ai-types.d.ts +1 -7
- package/dist/ai-types.js +2 -8
- package/dist/ai-types.js.map +1 -1
- package/dist/browser/ai.js +1 -1
- package/dist/browser/index.js +1 -1
- package/dist/chat/index.d.ts +1918 -72
- package/dist/chat/index.js +1730 -245
- package/dist/chat/index.js.map +1 -1
- package/dist/chat/react.d.ts +602 -0
- package/dist/chat/react.js +1506 -0
- package/dist/chat/react.js.map +1 -0
- package/dist/chat-sdk/index.d.ts +4 -4
- package/dist/{classPrivateFieldGet2-CZ7QjTXN.js → classPrivateFieldGet2-DZBYAB34.js} +5 -5
- package/dist/{classPrivateMethodInitSpec-D-0__zd9.js → classPrivateMethodInitSpec-qMjJ6sHQ.js} +2 -2
- package/dist/{client-BXJ9n2f7.js → client-BZ-B3NhC.js} +2 -2
- package/dist/client-BZ-B3NhC.js.map +1 -0
- package/dist/client-tools-aIBO0Fk7.d.ts +53 -0
- package/dist/client.d.ts +76 -57
- package/dist/client.js +33 -5
- package/dist/client.js.map +1 -1
- package/dist/{connector-CrKhowfD.js → connector-CdldGF3h.js} +5 -5
- package/dist/{connector-CrKhowfD.js.map → connector-CdldGF3h.js.map} +1 -1
- package/dist/email.js +1 -1
- package/dist/email.js.map +1 -1
- package/dist/{index-B7IbEeze.d.ts → index-CcbnKkNh.d.ts} +188 -14
- package/dist/index.d.ts +91 -71
- package/dist/index.js +562 -24
- package/dist/index.js.map +1 -1
- package/dist/mcp/client.d.ts +18 -14
- package/dist/mcp/client.js +1 -1
- package/dist/mcp/index.d.ts +30 -30
- package/dist/mcp/index.js +7 -7
- package/dist/mcp/index.js.map +1 -1
- package/dist/{agent-tools-3zLG7MgA.js → message-builder-BymO4N_D.js} +45 -126
- package/dist/message-builder-BymO4N_D.js.map +1 -0
- package/dist/observability/index.d.ts +1 -1
- package/dist/observability/index.js +4 -2
- package/dist/observability/index.js.map +1 -1
- package/dist/react.d.ts +123 -110
- package/dist/react.js +44 -11
- package/dist/react.js.map +1 -1
- package/dist/serializable.d.ts +1 -1
- package/dist/skills/compile.js +1 -1
- package/dist/skills/compile.js.map +1 -1
- package/dist/skills/index.js +5 -5
- package/dist/skills/index.js.map +1 -1
- package/dist/sub-routing.d.ts +6 -6
- package/dist/utils.js +1 -1
- package/dist/utils.js.map +1 -1
- package/dist/vite.js +5 -5
- package/dist/vite.js.map +1 -1
- package/dist/wire-types-nflOzNuU.js +240 -0
- package/dist/wire-types-nflOzNuU.js.map +1 -0
- package/dist/{workflow-types-SrZK_o9p.d.ts → workflow-types-Baz_PO5v.d.ts} +42 -22
- package/dist/workflow-types.d.ts +25 -21
- package/dist/workflow-types.js.map +1 -1
- package/dist/workflows.d.ts +22 -21
- package/dist/workflows.js +31 -7
- package/dist/workflows.js.map +1 -1
- 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 +1687 -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 +775 -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 +620 -0
- package/docs/mcp-servers.md +526 -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 +359 -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 +41 -14
- package/dist/agent-tools-3zLG7MgA.js.map +0 -1
- package/dist/agent-tools-DZhI5F6Q.d.ts +0 -14
- package/dist/client-BXJ9n2f7.js.map +0 -1
|
@@ -0,0 +1,775 @@
|
|
|
1
|
+
# Configuration
|
|
2
|
+
|
|
3
|
+
This guide covers everything you need to configure agents for local development and production deployment, including wrangler.jsonc setup, type generation, environment variables, and the Cloudflare dashboard.
|
|
4
|
+
|
|
5
|
+
## wrangler.jsonc
|
|
6
|
+
|
|
7
|
+
The `wrangler.jsonc` file configures your Cloudflare Worker and its bindings. Here's a complete example for an agents project:
|
|
8
|
+
|
|
9
|
+
```jsonc
|
|
10
|
+
{
|
|
11
|
+
"$schema": "node_modules/wrangler/config-schema.json",
|
|
12
|
+
"name": "my-agent-app",
|
|
13
|
+
"main": "src/server.ts",
|
|
14
|
+
"compatibility_date": "2025-01-01",
|
|
15
|
+
"compatibility_flags": ["nodejs_compat"],
|
|
16
|
+
|
|
17
|
+
// Static assets (optional)
|
|
18
|
+
"assets": {
|
|
19
|
+
"directory": "public",
|
|
20
|
+
"binding": "ASSETS"
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
// Durable Object bindings for agents
|
|
24
|
+
"durable_objects": {
|
|
25
|
+
"bindings": [
|
|
26
|
+
{
|
|
27
|
+
"name": "MyAgent",
|
|
28
|
+
"class_name": "MyAgent"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"name": "ChatAgent",
|
|
32
|
+
"class_name": "ChatAgent"
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
// Required: Enable SQLite storage for agents
|
|
38
|
+
"migrations": [
|
|
39
|
+
{
|
|
40
|
+
"tag": "v1",
|
|
41
|
+
"new_sqlite_classes": ["MyAgent", "ChatAgent"]
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
|
|
45
|
+
// AI binding (optional, for Workers AI)
|
|
46
|
+
"ai": {
|
|
47
|
+
"binding": "AI"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Key Fields
|
|
53
|
+
|
|
54
|
+
#### compatibility_flags
|
|
55
|
+
|
|
56
|
+
The `nodejs_compat` flag is **required** for agents:
|
|
57
|
+
|
|
58
|
+
```jsonc
|
|
59
|
+
"compatibility_flags": ["nodejs_compat"]
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
This enables Node.js compatibility mode, which agents depend on for crypto, streams, and other Node.js APIs.
|
|
63
|
+
|
|
64
|
+
#### durable_objects.bindings
|
|
65
|
+
|
|
66
|
+
Each agent class needs a binding:
|
|
67
|
+
|
|
68
|
+
```jsonc
|
|
69
|
+
"durable_objects": {
|
|
70
|
+
"bindings": [
|
|
71
|
+
{
|
|
72
|
+
"name": "Counter", // Property name on `env` (env.Counter)
|
|
73
|
+
"class_name": "Counter" // Exported class name (must match exactly)
|
|
74
|
+
}
|
|
75
|
+
]
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
| Field | Description |
|
|
80
|
+
| ------------ | ----------------------------------------------------------- |
|
|
81
|
+
| `name` | The property name on `env`. Use this in code: `env.Counter` |
|
|
82
|
+
| `class_name` | Must match the exported class name exactly |
|
|
83
|
+
|
|
84
|
+
**When name and class_name differ:**
|
|
85
|
+
|
|
86
|
+
```jsonc
|
|
87
|
+
{
|
|
88
|
+
"name": "COUNTER_DO", // env.COUNTER_DO
|
|
89
|
+
"class_name": "CounterAgent" // export class CounterAgent
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
This is useful when you want environment variable-style naming (`COUNTER_DO`) but more descriptive class names (`CounterAgent`).
|
|
94
|
+
|
|
95
|
+
#### migrations
|
|
96
|
+
|
|
97
|
+
Migrations tell Cloudflare how to set up storage for your Durable Objects:
|
|
98
|
+
|
|
99
|
+
```jsonc
|
|
100
|
+
"migrations": [
|
|
101
|
+
{
|
|
102
|
+
"tag": "v1",
|
|
103
|
+
"new_sqlite_classes": ["MyAgent"]
|
|
104
|
+
}
|
|
105
|
+
]
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
| Field | Description |
|
|
109
|
+
| -------------------- | ------------------------------------------------------------- |
|
|
110
|
+
| `tag` | Version identifier (e.g., "v1", "v2"). Must be unique |
|
|
111
|
+
| `new_sqlite_classes` | Agent classes that use SQLite storage (state persistence) |
|
|
112
|
+
| `deleted_classes` | Classes being removed |
|
|
113
|
+
| `renamed_classes` | Classes being renamed (see [Migrations](#migrations-1) below) |
|
|
114
|
+
|
|
115
|
+
#### assets
|
|
116
|
+
|
|
117
|
+
For serving static files (HTML, CSS, JS):
|
|
118
|
+
|
|
119
|
+
```jsonc
|
|
120
|
+
"assets": {
|
|
121
|
+
"directory": "public", // Folder containing static files
|
|
122
|
+
"binding": "ASSETS" // Optional: binding for programmatic access
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
With a binding, you can serve assets programmatically:
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
export default {
|
|
130
|
+
async fetch(request: Request, env: Env) {
|
|
131
|
+
// static assets are served by the worker automatically by default
|
|
132
|
+
|
|
133
|
+
// route the request to the appropriate agent
|
|
134
|
+
const agentResponse = await routeAgentRequest(request, env);
|
|
135
|
+
if (agentResponse) return agentResponse;
|
|
136
|
+
|
|
137
|
+
// add your own routing logic here if you want to handle requests that are not for agents
|
|
138
|
+
return new Response("Not found", { status: 404 });
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
#### ai
|
|
144
|
+
|
|
145
|
+
For Workers AI integration:
|
|
146
|
+
|
|
147
|
+
```jsonc
|
|
148
|
+
"ai": {
|
|
149
|
+
"binding": "AI",
|
|
150
|
+
"remote": true // Mandatory: use remote inference (for local dev)
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Access in your agent:
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
const response = await this.env.AI.run("@cf/moonshotai/kimi-k2.7-code", {
|
|
158
|
+
prompt: "Hello!"
|
|
159
|
+
});
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## TypeScript Configuration
|
|
163
|
+
|
|
164
|
+
The Agents SDK ships a shared `tsconfig.json` that sets all the compiler options needed for agents projects — including the `ES2021` target required for `@callable()` decorators, strict mode, bundler module resolution, and Workers types.
|
|
165
|
+
|
|
166
|
+
Extend it in your `tsconfig.json`:
|
|
167
|
+
|
|
168
|
+
```json
|
|
169
|
+
{
|
|
170
|
+
"extends": "agents/tsconfig"
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
This is equivalent to:
|
|
175
|
+
|
|
176
|
+
```json
|
|
177
|
+
{
|
|
178
|
+
"compilerOptions": {
|
|
179
|
+
"target": "ES2021",
|
|
180
|
+
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
181
|
+
"jsx": "react-jsx",
|
|
182
|
+
"module": "ES2022",
|
|
183
|
+
"moduleResolution": "bundler",
|
|
184
|
+
"types": ["node", "@cloudflare/workers-types", "vite/client"],
|
|
185
|
+
"allowImportingTsExtensions": true,
|
|
186
|
+
"noEmit": true,
|
|
187
|
+
"isolatedModules": true,
|
|
188
|
+
"verbatimModuleSyntax": true,
|
|
189
|
+
"esModuleInterop": true,
|
|
190
|
+
"forceConsistentCasingInFileNames": true,
|
|
191
|
+
"strict": true,
|
|
192
|
+
"skipLibCheck": true
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
You can override individual options as needed:
|
|
198
|
+
|
|
199
|
+
```json
|
|
200
|
+
{
|
|
201
|
+
"extends": "agents/tsconfig",
|
|
202
|
+
"compilerOptions": {
|
|
203
|
+
"jsx": "preserve"
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
> **Warning:** Do not set `"experimentalDecorators": true`. The Agents SDK uses [TC39 standard decorators](https://github.com/tc39/proposal-decorators), not TypeScript legacy decorators. Enabling `experimentalDecorators` applies an incompatible transform that silently breaks `@callable()` at runtime.
|
|
209
|
+
|
|
210
|
+
## Vite Configuration
|
|
211
|
+
|
|
212
|
+
The Agents SDK provides a Vite plugin that handles TC39 decorator transforms. Vite 8 uses Oxc for transpilation, which does not yet support TC39 decorators — without this plugin, `@callable()` and other decorators will fail at runtime.
|
|
213
|
+
|
|
214
|
+
Add the plugin to your `vite.config.ts`:
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
import { cloudflare } from "@cloudflare/vite-plugin";
|
|
218
|
+
import react from "@vitejs/plugin-react";
|
|
219
|
+
import agents from "agents/vite";
|
|
220
|
+
import { defineConfig } from "vite";
|
|
221
|
+
|
|
222
|
+
export default defineConfig({
|
|
223
|
+
plugins: [agents(), react(), cloudflare()]
|
|
224
|
+
});
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
The `agents()` plugin is safe to include even if your project does not use decorators. It only runs the transform on files that contain `@` syntax.
|
|
228
|
+
|
|
229
|
+
The starter template and all examples include this plugin by default.
|
|
230
|
+
|
|
231
|
+
## Generating Types
|
|
232
|
+
|
|
233
|
+
Wrangler can generate TypeScript types for your bindings.
|
|
234
|
+
|
|
235
|
+
### Automatic Generation
|
|
236
|
+
|
|
237
|
+
Run the types command:
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
npx wrangler types
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
This creates or updates `worker-configuration.d.ts` with your `Env` type.
|
|
244
|
+
|
|
245
|
+
### Custom Output Path
|
|
246
|
+
|
|
247
|
+
Specify a custom path:
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
npx wrangler types env.d.ts
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Without Runtime Types
|
|
254
|
+
|
|
255
|
+
For cleaner output (recommended for agents):
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
npx wrangler types env.d.ts --include-runtime false
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
This generates just your bindings without Cloudflare runtime types.
|
|
262
|
+
|
|
263
|
+
### Example Generated Output
|
|
264
|
+
|
|
265
|
+
```typescript
|
|
266
|
+
// env.d.ts (generated)
|
|
267
|
+
declare namespace Cloudflare {
|
|
268
|
+
interface Env {
|
|
269
|
+
OPENAI_API_KEY: string;
|
|
270
|
+
Counter: DurableObjectNamespace<import("./src/server").Counter>;
|
|
271
|
+
ChatAgent: DurableObjectNamespace<import("./src/server").ChatAgent>;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
interface Env extends Cloudflare.Env {}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Manual Type Definition
|
|
278
|
+
|
|
279
|
+
You can also define types manually:
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
// env.d.ts
|
|
283
|
+
import type { Counter } from "./src/agents/counter";
|
|
284
|
+
import type { ChatAgent } from "./src/agents/chat";
|
|
285
|
+
|
|
286
|
+
interface Env {
|
|
287
|
+
// Secrets
|
|
288
|
+
OPENAI_API_KEY: string;
|
|
289
|
+
WEBHOOK_SECRET: string;
|
|
290
|
+
|
|
291
|
+
// Agent bindings
|
|
292
|
+
Counter: DurableObjectNamespace<Counter>;
|
|
293
|
+
ChatAgent: DurableObjectNamespace<ChatAgent>;
|
|
294
|
+
|
|
295
|
+
// Other bindings
|
|
296
|
+
AI: Ai;
|
|
297
|
+
ASSETS: Fetcher;
|
|
298
|
+
MY_KV: KVNamespace;
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### Adding to package.json
|
|
303
|
+
|
|
304
|
+
Add a script for easy regeneration:
|
|
305
|
+
|
|
306
|
+
```json
|
|
307
|
+
{
|
|
308
|
+
"scripts": {
|
|
309
|
+
"types": "wrangler types env.d.ts --include-runtime false"
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
## Environment Variables & Secrets
|
|
315
|
+
|
|
316
|
+
### Local Development (.env)
|
|
317
|
+
|
|
318
|
+
Create a `.env` file for local secrets (add to `.gitignore`):
|
|
319
|
+
|
|
320
|
+
```bash
|
|
321
|
+
# .env
|
|
322
|
+
OPENAI_API_KEY=sk-...
|
|
323
|
+
GITHUB_WEBHOOK_SECRET=whsec_...
|
|
324
|
+
DATABASE_URL=postgres://...
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
Access in your agent:
|
|
328
|
+
|
|
329
|
+
```typescript
|
|
330
|
+
class MyAgent extends Agent<Env> {
|
|
331
|
+
async onStart() {
|
|
332
|
+
const apiKey = process.env.OPENAI_API_KEY;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Production Secrets
|
|
338
|
+
|
|
339
|
+
Use `wrangler secret` for production:
|
|
340
|
+
|
|
341
|
+
```bash
|
|
342
|
+
# Add a secret
|
|
343
|
+
wrangler secret put OPENAI_API_KEY
|
|
344
|
+
# Enter value when prompted
|
|
345
|
+
|
|
346
|
+
# List secrets
|
|
347
|
+
wrangler secret list
|
|
348
|
+
|
|
349
|
+
# Delete a secret
|
|
350
|
+
wrangler secret delete OPENAI_API_KEY
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### Non-Secret Variables
|
|
354
|
+
|
|
355
|
+
For non-sensitive configuration, use `vars` in wrangler.jsonc:
|
|
356
|
+
|
|
357
|
+
```jsonc
|
|
358
|
+
{
|
|
359
|
+
"vars": {
|
|
360
|
+
"API_BASE_URL": "https://api.example.com",
|
|
361
|
+
"MAX_RETRIES": "3",
|
|
362
|
+
"DEBUG_MODE": "false"
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
Note: All values must be strings. Parse numbers/booleans in code:
|
|
368
|
+
|
|
369
|
+
```typescript
|
|
370
|
+
const maxRetries = parseInt(process.env.MAX_RETRIES, 10);
|
|
371
|
+
const debugMode = process.env.DEBUG_MODE === "true";
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### Environment-Specific Variables
|
|
375
|
+
|
|
376
|
+
Use `[env.{name}]` sections for different environments (e.g. staging, production):
|
|
377
|
+
|
|
378
|
+
```jsonc
|
|
379
|
+
{
|
|
380
|
+
"name": "my-agent",
|
|
381
|
+
"vars": {
|
|
382
|
+
"API_URL": "https://api.example.com"
|
|
383
|
+
},
|
|
384
|
+
|
|
385
|
+
"env": {
|
|
386
|
+
"staging": {
|
|
387
|
+
"vars": {
|
|
388
|
+
"API_URL": "https://staging-api.example.com"
|
|
389
|
+
}
|
|
390
|
+
},
|
|
391
|
+
"production": {
|
|
392
|
+
"vars": {
|
|
393
|
+
"API_URL": "https://api.example.com"
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
Deploy to specific environment:
|
|
401
|
+
|
|
402
|
+
```bash
|
|
403
|
+
wrangler deploy --env staging
|
|
404
|
+
wrangler deploy --env production
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
## Local Development
|
|
408
|
+
|
|
409
|
+
### Starting the Dev Server
|
|
410
|
+
|
|
411
|
+
With Vite (recommended for full stack apps):
|
|
412
|
+
|
|
413
|
+
```bash
|
|
414
|
+
npx vite dev
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
Without Vite:
|
|
418
|
+
|
|
419
|
+
```bash
|
|
420
|
+
npx wrangler dev
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
### Local State Persistence
|
|
424
|
+
|
|
425
|
+
Durable Object state is persisted locally in `.wrangler/state/`:
|
|
426
|
+
|
|
427
|
+
```
|
|
428
|
+
.wrangler/
|
|
429
|
+
└── state/
|
|
430
|
+
└── v3/
|
|
431
|
+
└── d1/
|
|
432
|
+
└── miniflare-D1DatabaseObject/
|
|
433
|
+
└── ... (SQLite files)
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
### Clearing Local State
|
|
437
|
+
|
|
438
|
+
To reset all local Durable Object state:
|
|
439
|
+
|
|
440
|
+
```bash
|
|
441
|
+
rm -rf .wrangler/state
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
Or restart with fresh state:
|
|
445
|
+
|
|
446
|
+
```bash
|
|
447
|
+
npx wrangler dev --persist-to=""
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
### Inspecting Local SQLite
|
|
451
|
+
|
|
452
|
+
You can inspect agent state directly:
|
|
453
|
+
|
|
454
|
+
```bash
|
|
455
|
+
# Find the SQLite file
|
|
456
|
+
ls .wrangler/state/v3/d1/
|
|
457
|
+
|
|
458
|
+
# Open with sqlite3
|
|
459
|
+
sqlite3 .wrangler/state/v3/d1/miniflare-D1DatabaseObject/*.sqlite
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
## Dashboard Setup
|
|
463
|
+
|
|
464
|
+
### Automatic Resources
|
|
465
|
+
|
|
466
|
+
When you deploy, Cloudflare automatically creates:
|
|
467
|
+
|
|
468
|
+
- **Worker** - Your deployed code
|
|
469
|
+
- **Durable Object namespaces** - One per agent class
|
|
470
|
+
- **SQLite storage** - Attached to each namespace
|
|
471
|
+
|
|
472
|
+
### Viewing Durable Objects
|
|
473
|
+
|
|
474
|
+
1. Go to [dash.cloudflare.com](https://dash.cloudflare.com)
|
|
475
|
+
2. Select your account → Workers & Pages
|
|
476
|
+
3. Click your Worker
|
|
477
|
+
4. Go to **Durable Objects** tab
|
|
478
|
+
|
|
479
|
+
Here you can:
|
|
480
|
+
|
|
481
|
+
- See all Durable Object namespaces
|
|
482
|
+
- View individual object instances
|
|
483
|
+
- Inspect storage (keys and values)
|
|
484
|
+
- Delete objects
|
|
485
|
+
|
|
486
|
+
### Real-time Logs
|
|
487
|
+
|
|
488
|
+
View live logs from your agents:
|
|
489
|
+
|
|
490
|
+
```bash
|
|
491
|
+
npx wrangler tail
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
Or in the dashboard:
|
|
495
|
+
|
|
496
|
+
1. Go to your Worker
|
|
497
|
+
2. Click **Logs** tab
|
|
498
|
+
3. Enable real-time logs
|
|
499
|
+
|
|
500
|
+
Filter by:
|
|
501
|
+
|
|
502
|
+
- Status (success, error)
|
|
503
|
+
- Search text
|
|
504
|
+
- Sampling rate
|
|
505
|
+
|
|
506
|
+
### Analytics
|
|
507
|
+
|
|
508
|
+
The dashboard shows:
|
|
509
|
+
|
|
510
|
+
- Request count
|
|
511
|
+
- Error rate
|
|
512
|
+
- CPU time
|
|
513
|
+
- Duration percentiles
|
|
514
|
+
- Durable Object metrics
|
|
515
|
+
|
|
516
|
+
## Production Deployment
|
|
517
|
+
|
|
518
|
+
### Basic Deploy
|
|
519
|
+
|
|
520
|
+
```bash
|
|
521
|
+
npx wrangler deploy
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
This:
|
|
525
|
+
|
|
526
|
+
1. Bundles your code
|
|
527
|
+
2. Uploads to Cloudflare
|
|
528
|
+
3. Applies migrations
|
|
529
|
+
4. Makes it live on `*.workers.dev`
|
|
530
|
+
|
|
531
|
+
### Custom Domain
|
|
532
|
+
|
|
533
|
+
Add a route in wrangler.jsonc:
|
|
534
|
+
|
|
535
|
+
```jsonc
|
|
536
|
+
{
|
|
537
|
+
"routes": [
|
|
538
|
+
{
|
|
539
|
+
"pattern": "agents.example.com/*",
|
|
540
|
+
"zone_name": "example.com"
|
|
541
|
+
}
|
|
542
|
+
]
|
|
543
|
+
}
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
Or use a custom domain (simpler):
|
|
547
|
+
|
|
548
|
+
```jsonc
|
|
549
|
+
{
|
|
550
|
+
"routes": [
|
|
551
|
+
{
|
|
552
|
+
"pattern": "agents.example.com",
|
|
553
|
+
"custom_domain": true
|
|
554
|
+
}
|
|
555
|
+
]
|
|
556
|
+
}
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
### Preview Deployments
|
|
560
|
+
|
|
561
|
+
Deploy without affecting production:
|
|
562
|
+
|
|
563
|
+
```bash
|
|
564
|
+
npx wrangler deploy --dry-run # See what would be uploaded
|
|
565
|
+
npx wrangler versions upload # Upload new version
|
|
566
|
+
npx wrangler versions deploy # Gradually roll out
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
### Rollbacks
|
|
570
|
+
|
|
571
|
+
Roll back to a previous version:
|
|
572
|
+
|
|
573
|
+
```bash
|
|
574
|
+
npx wrangler rollback
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
## Multi-Environment Setup
|
|
578
|
+
|
|
579
|
+
### Environment Configuration
|
|
580
|
+
|
|
581
|
+
Define environments in wrangler.jsonc:
|
|
582
|
+
|
|
583
|
+
```jsonc
|
|
584
|
+
{
|
|
585
|
+
"name": "my-agent",
|
|
586
|
+
"main": "src/server.ts",
|
|
587
|
+
|
|
588
|
+
// Base configuration (shared)
|
|
589
|
+
"compatibility_date": "2025-01-01",
|
|
590
|
+
"compatibility_flags": ["nodejs_compat"],
|
|
591
|
+
"durable_objects": {
|
|
592
|
+
"bindings": [{ "name": "MyAgent", "class_name": "MyAgent" }]
|
|
593
|
+
},
|
|
594
|
+
"migrations": [{ "tag": "v1", "new_sqlite_classes": ["MyAgent"] }],
|
|
595
|
+
|
|
596
|
+
// Environment overrides
|
|
597
|
+
"env": {
|
|
598
|
+
"staging": {
|
|
599
|
+
"name": "my-agent-staging",
|
|
600
|
+
"vars": {
|
|
601
|
+
"ENVIRONMENT": "staging"
|
|
602
|
+
}
|
|
603
|
+
},
|
|
604
|
+
"production": {
|
|
605
|
+
"name": "my-agent-production",
|
|
606
|
+
"vars": {
|
|
607
|
+
"ENVIRONMENT": "production"
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
### Deploying to Environments
|
|
615
|
+
|
|
616
|
+
```bash
|
|
617
|
+
# Deploy to staging
|
|
618
|
+
npx wrangler deploy --env staging
|
|
619
|
+
|
|
620
|
+
# Deploy to production
|
|
621
|
+
npx wrangler deploy --env production
|
|
622
|
+
|
|
623
|
+
# Set secrets per environment
|
|
624
|
+
npx wrangler secret put OPENAI_API_KEY --env staging
|
|
625
|
+
npx wrangler secret put OPENAI_API_KEY --env production
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
### Separate Durable Objects
|
|
629
|
+
|
|
630
|
+
Each environment gets its own Durable Objects. Staging agents don't share state with production agents.
|
|
631
|
+
|
|
632
|
+
To explicitly separate:
|
|
633
|
+
|
|
634
|
+
```jsonc
|
|
635
|
+
{
|
|
636
|
+
"env": {
|
|
637
|
+
"staging": {
|
|
638
|
+
"durable_objects": {
|
|
639
|
+
"bindings": [
|
|
640
|
+
{
|
|
641
|
+
"name": "MyAgent",
|
|
642
|
+
"class_name": "MyAgent",
|
|
643
|
+
"script_name": "my-agent-staging" // Different namespace
|
|
644
|
+
}
|
|
645
|
+
]
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
## Migrations
|
|
653
|
+
|
|
654
|
+
Migrations manage Durable Object storage schema changes.
|
|
655
|
+
|
|
656
|
+
### Adding a New Agent
|
|
657
|
+
|
|
658
|
+
Add to `new_sqlite_classes` in a new migration:
|
|
659
|
+
|
|
660
|
+
```jsonc
|
|
661
|
+
"migrations": [
|
|
662
|
+
{
|
|
663
|
+
"tag": "v1",
|
|
664
|
+
"new_sqlite_classes": ["ExistingAgent"]
|
|
665
|
+
},
|
|
666
|
+
{
|
|
667
|
+
"tag": "v2",
|
|
668
|
+
"new_sqlite_classes": ["NewAgent"]
|
|
669
|
+
}
|
|
670
|
+
]
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
### Renaming an Agent Class
|
|
674
|
+
|
|
675
|
+
Use `renamed_classes`:
|
|
676
|
+
|
|
677
|
+
```jsonc
|
|
678
|
+
"migrations": [
|
|
679
|
+
{
|
|
680
|
+
"tag": "v1",
|
|
681
|
+
"new_sqlite_classes": ["OldName"]
|
|
682
|
+
},
|
|
683
|
+
{
|
|
684
|
+
"tag": "v2",
|
|
685
|
+
"renamed_classes": [
|
|
686
|
+
{
|
|
687
|
+
"from": "OldName",
|
|
688
|
+
"to": "NewName"
|
|
689
|
+
}
|
|
690
|
+
]
|
|
691
|
+
}
|
|
692
|
+
]
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
**Important:** Also update:
|
|
696
|
+
|
|
697
|
+
1. The class name in code
|
|
698
|
+
2. The `class_name` in bindings
|
|
699
|
+
3. Export statements
|
|
700
|
+
|
|
701
|
+
### Deleting an Agent Class
|
|
702
|
+
|
|
703
|
+
Use `deleted_classes`:
|
|
704
|
+
|
|
705
|
+
```jsonc
|
|
706
|
+
"migrations": [
|
|
707
|
+
{
|
|
708
|
+
"tag": "v1",
|
|
709
|
+
"new_sqlite_classes": ["AgentToDelete", "AgentToKeep"]
|
|
710
|
+
},
|
|
711
|
+
{
|
|
712
|
+
"tag": "v2",
|
|
713
|
+
"deleted_classes": ["AgentToDelete"]
|
|
714
|
+
}
|
|
715
|
+
]
|
|
716
|
+
```
|
|
717
|
+
|
|
718
|
+
**Warning:** This permanently deletes all data for that class.
|
|
719
|
+
|
|
720
|
+
### Migration Best Practices
|
|
721
|
+
|
|
722
|
+
1. **Never modify existing migrations** - Always add new ones
|
|
723
|
+
2. **Use sequential tags** - v1, v2, v3 (or use dates: 2025-01-15)
|
|
724
|
+
3. **Test locally first** - Migrations run on deploy
|
|
725
|
+
4. **Back up production data** - Before renaming or deleting
|
|
726
|
+
|
|
727
|
+
## Troubleshooting
|
|
728
|
+
|
|
729
|
+
### "No such Durable Object class"
|
|
730
|
+
|
|
731
|
+
The class isn't in migrations:
|
|
732
|
+
|
|
733
|
+
```jsonc
|
|
734
|
+
"migrations": [
|
|
735
|
+
{
|
|
736
|
+
"tag": "v1",
|
|
737
|
+
"new_sqlite_classes": ["MissingClassName"] // Add it here
|
|
738
|
+
}
|
|
739
|
+
]
|
|
740
|
+
```
|
|
741
|
+
|
|
742
|
+
### "Cannot find module" in types
|
|
743
|
+
|
|
744
|
+
Regenerate types:
|
|
745
|
+
|
|
746
|
+
```bash
|
|
747
|
+
npx wrangler types env.d.ts --include-runtime false
|
|
748
|
+
```
|
|
749
|
+
|
|
750
|
+
### Secrets not loading locally
|
|
751
|
+
|
|
752
|
+
Check that `.env` exists and contains the variable:
|
|
753
|
+
|
|
754
|
+
```bash
|
|
755
|
+
cat .env
|
|
756
|
+
# Should show: MY_SECRET=value
|
|
757
|
+
```
|
|
758
|
+
|
|
759
|
+
### Migration tag conflict
|
|
760
|
+
|
|
761
|
+
Migration tags must be unique. If you see conflicts:
|
|
762
|
+
|
|
763
|
+
```jsonc
|
|
764
|
+
// Wrong - duplicate tags
|
|
765
|
+
"migrations": [
|
|
766
|
+
{ "tag": "v1", "new_sqlite_classes": ["A"] },
|
|
767
|
+
{ "tag": "v1", "new_sqlite_classes": ["B"] } // Error!
|
|
768
|
+
]
|
|
769
|
+
|
|
770
|
+
// Correct - sequential tags
|
|
771
|
+
"migrations": [
|
|
772
|
+
{ "tag": "v1", "new_sqlite_classes": ["A"] },
|
|
773
|
+
{ "tag": "v2", "new_sqlite_classes": ["B"] }
|
|
774
|
+
]
|
|
775
|
+
```
|