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.
Files changed (122) hide show
  1. package/README.md +11 -8
  2. package/dist/{agent-tool-types-CTw3UJUP.d.ts → agent-tool-types-Cd1TZPfB.d.ts} +587 -137
  3. package/dist/agent-tool-types.d.ts +34 -18
  4. package/dist/agent-tool-types.js +20 -1
  5. package/dist/agent-tool-types.js.map +1 -0
  6. package/dist/agent-tools-BXlsuX0d.js +304 -0
  7. package/dist/agent-tools-BXlsuX0d.js.map +1 -0
  8. package/dist/agent-tools-_E8wxUIK.d.ts +119 -0
  9. package/dist/agent-tools.d.ts +24 -18
  10. package/dist/agent-tools.js.map +1 -1
  11. package/dist/ai-chat-agent.d.ts +1 -1
  12. package/dist/ai-chat-agent.js +1 -2
  13. package/dist/ai-chat-agent.js.map +1 -1
  14. package/dist/ai-chat-v5-migration.d.ts +1 -1
  15. package/dist/ai-chat-v5-migration.js +1 -2
  16. package/dist/ai-chat-v5-migration.js.map +1 -1
  17. package/dist/ai-react.d.ts +1 -1
  18. package/dist/ai-react.js +1 -2
  19. package/dist/ai-react.js.map +1 -1
  20. package/dist/ai-types.d.ts +1 -7
  21. package/dist/ai-types.js +2 -8
  22. package/dist/ai-types.js.map +1 -1
  23. package/dist/browser/ai.js +1 -1
  24. package/dist/browser/index.js +1 -1
  25. package/dist/chat/index.d.ts +1918 -72
  26. package/dist/chat/index.js +1730 -245
  27. package/dist/chat/index.js.map +1 -1
  28. package/dist/chat/react.d.ts +602 -0
  29. package/dist/chat/react.js +1506 -0
  30. package/dist/chat/react.js.map +1 -0
  31. package/dist/chat-sdk/index.d.ts +4 -4
  32. package/dist/{classPrivateFieldGet2-CZ7QjTXN.js → classPrivateFieldGet2-DZBYAB34.js} +5 -5
  33. package/dist/{classPrivateMethodInitSpec-D-0__zd9.js → classPrivateMethodInitSpec-qMjJ6sHQ.js} +2 -2
  34. package/dist/{client-BXJ9n2f7.js → client-BZ-B3NhC.js} +2 -2
  35. package/dist/client-BZ-B3NhC.js.map +1 -0
  36. package/dist/client-tools-aIBO0Fk7.d.ts +53 -0
  37. package/dist/client.d.ts +76 -57
  38. package/dist/client.js +33 -5
  39. package/dist/client.js.map +1 -1
  40. package/dist/{connector-CrKhowfD.js → connector-CdldGF3h.js} +5 -5
  41. package/dist/{connector-CrKhowfD.js.map → connector-CdldGF3h.js.map} +1 -1
  42. package/dist/email.js +1 -1
  43. package/dist/email.js.map +1 -1
  44. package/dist/{index-B7IbEeze.d.ts → index-CcbnKkNh.d.ts} +188 -14
  45. package/dist/index.d.ts +91 -71
  46. package/dist/index.js +562 -24
  47. package/dist/index.js.map +1 -1
  48. package/dist/mcp/client.d.ts +18 -14
  49. package/dist/mcp/client.js +1 -1
  50. package/dist/mcp/index.d.ts +30 -30
  51. package/dist/mcp/index.js +7 -7
  52. package/dist/mcp/index.js.map +1 -1
  53. package/dist/{agent-tools-3zLG7MgA.js → message-builder-BymO4N_D.js} +45 -126
  54. package/dist/message-builder-BymO4N_D.js.map +1 -0
  55. package/dist/observability/index.d.ts +1 -1
  56. package/dist/observability/index.js +4 -2
  57. package/dist/observability/index.js.map +1 -1
  58. package/dist/react.d.ts +123 -110
  59. package/dist/react.js +44 -11
  60. package/dist/react.js.map +1 -1
  61. package/dist/serializable.d.ts +1 -1
  62. package/dist/skills/compile.js +1 -1
  63. package/dist/skills/compile.js.map +1 -1
  64. package/dist/skills/index.js +5 -5
  65. package/dist/skills/index.js.map +1 -1
  66. package/dist/sub-routing.d.ts +6 -6
  67. package/dist/utils.js +1 -1
  68. package/dist/utils.js.map +1 -1
  69. package/dist/vite.js +5 -5
  70. package/dist/vite.js.map +1 -1
  71. package/dist/wire-types-nflOzNuU.js +240 -0
  72. package/dist/wire-types-nflOzNuU.js.map +1 -0
  73. package/dist/{workflow-types-SrZK_o9p.d.ts → workflow-types-Baz_PO5v.d.ts} +42 -22
  74. package/dist/workflow-types.d.ts +25 -21
  75. package/dist/workflow-types.js.map +1 -1
  76. package/dist/workflows.d.ts +22 -21
  77. package/dist/workflows.js +31 -7
  78. package/dist/workflows.js.map +1 -1
  79. package/docs/adding-to-existing-project.md +450 -0
  80. package/docs/agent-class.md +503 -0
  81. package/docs/agent-tools.md +552 -0
  82. package/docs/browse-the-web.md +430 -0
  83. package/docs/callable-methods.md +627 -0
  84. package/docs/chat-agents.md +1687 -0
  85. package/docs/chat-sdk.md +181 -0
  86. package/docs/client-sdk.md +520 -0
  87. package/docs/client-tools-continuation.md +177 -0
  88. package/docs/codemode.md +440 -0
  89. package/docs/configuration.md +775 -0
  90. package/docs/cross-domain-authentication.md +171 -0
  91. package/docs/durable-execution.md +537 -0
  92. package/docs/email.md +663 -0
  93. package/docs/get-current-agent.md +204 -0
  94. package/docs/getting-started.md +305 -0
  95. package/docs/http-websockets.md +668 -0
  96. package/docs/human-in-the-loop.md +661 -0
  97. package/docs/index.md +151 -0
  98. package/docs/long-running-agents.md +730 -0
  99. package/docs/mcp-client.md +620 -0
  100. package/docs/mcp-servers.md +526 -0
  101. package/docs/mcp-transports.md +308 -0
  102. package/docs/migration-to-ai-sdk-v5.md +96 -0
  103. package/docs/migration-to-ai-sdk-v6.md +163 -0
  104. package/docs/observability.md +261 -0
  105. package/docs/push-notifications.md +367 -0
  106. package/docs/queue.md +329 -0
  107. package/docs/readonly-connections.md +278 -0
  108. package/docs/resumable-streaming.md +127 -0
  109. package/docs/retries.md +444 -0
  110. package/docs/routing.md +749 -0
  111. package/docs/scheduling.md +898 -0
  112. package/docs/securing-mcp-servers.md +359 -0
  113. package/docs/server-driven-messages.md +477 -0
  114. package/docs/sessions.md +1024 -0
  115. package/docs/state.md +512 -0
  116. package/docs/sub-agents.md +389 -0
  117. package/docs/webhooks.md +604 -0
  118. package/docs/workflows.md +877 -0
  119. package/package.json +41 -14
  120. package/dist/agent-tools-3zLG7MgA.js.map +0 -1
  121. package/dist/agent-tools-DZhI5F6Q.d.ts +0 -14
  122. 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
+ ```