agents 0.22.0 → 0.24.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 (215) hide show
  1. package/README.md +20 -1
  2. package/dist/{agent-routing-CnkaHb-v.d.ts → agent-routing-B2XLNMxq.d.ts} +1094 -443
  3. package/dist/agent-routing.d.ts +1 -1
  4. package/dist/agent-tool-types.d.ts +26 -26
  5. package/dist/{agent-tools-C0XJqWzB.d.ts → agent-tools-Dj5Mzlw7.d.ts} +7 -7
  6. package/dist/agent-tools.d.ts +21 -21
  7. package/dist/browser/ai.js +4 -1
  8. package/dist/browser/ai.js.map +1 -1
  9. package/dist/browser/tanstack-ai.js.map +1 -1
  10. package/dist/callable-decorator-DP__HhBA.d.ts +72 -0
  11. package/dist/callable-decorator.d.ts +18 -0
  12. package/dist/callable-decorator.js +71 -0
  13. package/dist/callable-decorator.js.map +1 -0
  14. package/dist/{capability-BjSKYpzg.js → capability-B4WbF81e.js} +2 -1
  15. package/dist/capability-B4WbF81e.js.map +1 -0
  16. package/dist/capability-runner-BUBa6Ake.d.ts +484 -0
  17. package/dist/channel-Bnm4S7T2.d.ts +491 -0
  18. package/dist/channels/ai-sdk.d.ts +46 -0
  19. package/dist/channels/ai-sdk.js +120 -0
  20. package/dist/channels/ai-sdk.js.map +1 -0
  21. package/dist/channels/email.d.ts +95 -0
  22. package/dist/channels/email.js +323 -0
  23. package/dist/channels/email.js.map +1 -0
  24. package/dist/channels/index.d.ts +233 -0
  25. package/dist/channels/index.js +608 -0
  26. package/dist/channels/index.js.map +1 -0
  27. package/dist/channels/slack.d.ts +140 -0
  28. package/dist/channels/slack.js +614 -0
  29. package/dist/channels/slack.js.map +1 -0
  30. package/dist/channels/tanstack-ai.d.ts +39 -0
  31. package/dist/channels/tanstack-ai.js +17 -0
  32. package/dist/channels/tanstack-ai.js.map +1 -0
  33. package/dist/channels/telegram.d.ts +106 -0
  34. package/dist/channels/telegram.js +427 -0
  35. package/dist/channels/telegram.js.map +1 -0
  36. package/dist/channels/voice.d.ts +45 -0
  37. package/dist/channels/voice.js +122 -0
  38. package/dist/channels/voice.js.map +1 -0
  39. package/dist/chat/index.d.ts +2319 -2010
  40. package/dist/chat/index.js +892 -518
  41. package/dist/chat/index.js.map +1 -1
  42. package/dist/chat-sdk/index.d.ts +7 -7
  43. package/dist/chat-sdk/index.js +1 -1
  44. package/dist/client-BxdkCuVy.d.ts +411 -0
  45. package/dist/client-C9DAjZIY.js +518 -0
  46. package/dist/client-C9DAjZIY.js.map +1 -0
  47. package/dist/{client-jagG8a9_.js → client-fyQrLGkD.js} +2 -2
  48. package/dist/{client-jagG8a9_.js.map → client-fyQrLGkD.js.map} +1 -1
  49. package/dist/client.d.ts +27 -283
  50. package/dist/client.js +2 -274
  51. package/dist/context/index.d.ts +216 -0
  52. package/dist/context/index.js +454 -0
  53. package/dist/context/index.js.map +1 -0
  54. package/dist/current-agent-C4w86kcN.d.ts +93 -0
  55. package/dist/current-agent-DhoDkSnH.js.map +1 -1
  56. package/dist/{diagnostics-CaBjfz4J.js → diagnostics-BzvaX2UT.js} +5 -1
  57. package/dist/diagnostics-BzvaX2UT.js.map +1 -0
  58. package/dist/diagnostics-C4jcz3VK.js +360 -0
  59. package/dist/diagnostics-C4jcz3VK.js.map +1 -0
  60. package/dist/durable-object-lifecycle-ei7M7lqB.d.ts +157 -0
  61. package/dist/index-BB0kqhIz.d.ts +101 -0
  62. package/dist/index-BVVgDSdq.d.ts +1 -0
  63. package/dist/index-Dlgtd3Mj.d.ts +78 -0
  64. package/dist/index-XDkuQ7zm.d.ts +89 -0
  65. package/dist/{index-DcSAZKsB.d.ts → index-YSKgfgg9.d.ts} +3 -1
  66. package/dist/index.d.ts +92 -83
  67. package/dist/index.js +4 -3
  68. package/dist/ingress-BfetZbMO.js +83 -0
  69. package/dist/ingress-BfetZbMO.js.map +1 -0
  70. package/dist/internal-CYlgHl1l.js +59 -0
  71. package/dist/internal-CYlgHl1l.js.map +1 -0
  72. package/dist/internal_context.d.ts +1 -1
  73. package/dist/lifecycle/index.d.ts +39 -19
  74. package/dist/lifecycle/index.js +2 -2
  75. package/dist/lifecycle-Mm_jQh7r.js +1314 -0
  76. package/dist/lifecycle-Mm_jQh7r.js.map +1 -0
  77. package/dist/mcp/client/index.d.ts +20 -20
  78. package/dist/mcp/client/index.js +1 -1
  79. package/dist/mcp/index.d.ts +35 -35
  80. package/dist/mcp/index.js +2 -2
  81. package/dist/observability/index.d.ts +1 -1
  82. package/dist/observability/index.js +1 -1
  83. package/dist/queue/index.d.ts +123 -0
  84. package/dist/queue/index.js +2 -0
  85. package/dist/queue-BC9F5cUo.js +406 -0
  86. package/dist/queue-BC9F5cUo.js.map +1 -0
  87. package/dist/react.d.ts +34 -16
  88. package/dist/react.js +31 -8
  89. package/dist/react.js.map +1 -1
  90. package/dist/{retries-CAvxtG9d.d.ts → retries-D9B2UCq3.d.ts} +23 -6
  91. package/dist/retries.d.ts +10 -6
  92. package/dist/retries.js +21 -1
  93. package/dist/retries.js.map +1 -1
  94. package/dist/routing/index.d.ts +137 -0
  95. package/dist/routing/index.js +244 -0
  96. package/dist/routing/index.js.map +1 -0
  97. package/dist/sanitize-D9TujEK8.js +79 -0
  98. package/dist/sanitize-D9TujEK8.js.map +1 -0
  99. package/dist/{scheduler-DQoTGoAW.d.ts → scheduler-BGq6M5Kd.d.ts} +20 -21
  100. package/dist/scheduler-D_KHqxBa.js +658 -0
  101. package/dist/scheduler-D_KHqxBa.js.map +1 -0
  102. package/dist/schedules/index.d.ts +1 -1
  103. package/dist/schedules/index.js +1 -1
  104. package/dist/sentence-chunker-BAidJ4DA.d.ts +68 -0
  105. package/dist/serializable.d.ts +1 -1
  106. package/dist/sessions/index.d.ts +441 -0
  107. package/dist/sessions/index.js +2063 -0
  108. package/dist/sessions/index.js.map +1 -0
  109. package/dist/skills/index.d.ts +99 -0
  110. package/dist/skills/index.js +254 -5
  111. package/dist/skills/index.js.map +1 -1
  112. package/dist/{src-5W6JNKVb.js → src-BNU3ZiJM.js} +1524 -1441
  113. package/dist/src-BNU3ZiJM.js.map +1 -0
  114. package/dist/state/index.d.ts +6 -0
  115. package/dist/state/index.js +137 -0
  116. package/dist/state/index.js.map +1 -0
  117. package/dist/streams/index.d.ts +120 -0
  118. package/dist/streams/index.js +107 -0
  119. package/dist/streams/index.js.map +1 -0
  120. package/dist/streams-BcE8JP2X.d.ts +370 -0
  121. package/dist/streams-CCPRV6dt.js +709 -0
  122. package/dist/streams-CCPRV6dt.js.map +1 -0
  123. package/dist/sub-routing.d.ts +12 -12
  124. package/dist/surface-bZZJqBka.js +17 -0
  125. package/dist/surface-bZZJqBka.js.map +1 -0
  126. package/dist/tasks/index.d.ts +64 -0
  127. package/dist/tasks/index.js +2 -0
  128. package/dist/tasks-D4nLqVSI.js +1656 -0
  129. package/dist/tasks-D4nLqVSI.js.map +1 -0
  130. package/dist/tasks-V2lCT8ZV.d.ts +517 -0
  131. package/dist/text-segment-joiner-BtAFQSA_.js +57 -0
  132. package/dist/text-segment-joiner-BtAFQSA_.js.map +1 -0
  133. package/dist/text-stream-CpdiKrJB.js +272 -0
  134. package/dist/text-stream-CpdiKrJB.js.map +1 -0
  135. package/dist/tokens-nHAKcN6M.js +52 -0
  136. package/dist/tokens-nHAKcN6M.js.map +1 -0
  137. package/dist/tool-schema-CBjGPrsQ.js +31 -0
  138. package/dist/tool-schema-CBjGPrsQ.js.map +1 -0
  139. package/dist/transport-protocol-BxyngQ_R.js +25 -0
  140. package/dist/transport-protocol-BxyngQ_R.js.map +1 -0
  141. package/dist/transport-protocol-ZTew5Wso.d.ts +27 -0
  142. package/dist/types-B7LojTe4.d.ts +202 -0
  143. package/dist/types-DCD6BNZH.d.ts +70 -0
  144. package/dist/types-_Faxb570.d.ts +439 -0
  145. package/dist/voice/client.d.ts +226 -0
  146. package/dist/voice/client.js +932 -0
  147. package/dist/voice/client.js.map +1 -0
  148. package/dist/voice/errors.d.ts +43 -0
  149. package/dist/voice/errors.js +41 -0
  150. package/dist/voice/errors.js.map +1 -0
  151. package/dist/voice/index.d.ts +271 -0
  152. package/dist/voice/index.js +1812 -0
  153. package/dist/voice/index.js.map +1 -0
  154. package/dist/voice/react.d.ts +167 -0
  155. package/dist/voice/react.js +234 -0
  156. package/dist/voice/react.js.map +1 -0
  157. package/dist/voice/sfu.d.ts +71 -0
  158. package/dist/voice/sfu.js +157 -0
  159. package/dist/voice/sfu.js.map +1 -0
  160. package/dist/voice/text.d.ts +6 -0
  161. package/dist/voice/text.js +2 -0
  162. package/dist/voice/types.d.ts +58 -0
  163. package/dist/voice/types.js +18 -0
  164. package/dist/voice/types.js.map +1 -0
  165. package/dist/voice/workers-ai.d.ts +136 -0
  166. package/dist/voice/workers-ai.js +568 -0
  167. package/dist/voice/workers-ai.js.map +1 -0
  168. package/dist/websockets/index.d.ts +301 -0
  169. package/dist/websockets/index.js +3 -0
  170. package/dist/websockets-D7IzWbZb.js +1005 -0
  171. package/dist/websockets-D7IzWbZb.js.map +1 -0
  172. package/dist/workflow-types.d.ts +25 -25
  173. package/dist/workflows.d.ts +21 -21
  174. package/dist/workflows.js +1 -1
  175. package/docs/agent-class.md +4 -4
  176. package/docs/agent-tools.md +2 -1
  177. package/docs/channels.md +323 -0
  178. package/docs/chat-agents.md +6 -13
  179. package/docs/client-sdk.md +30 -0
  180. package/docs/context.md +131 -0
  181. package/docs/index.md +16 -13
  182. package/docs/lifecycle.md +179 -57
  183. package/docs/long-running-agents.md +2 -2
  184. package/docs/mcp-servers.md +5 -1
  185. package/docs/queue.md +135 -241
  186. package/docs/resumable-streaming.md +1 -1
  187. package/docs/retries.md +1 -1
  188. package/docs/routing.md +105 -0
  189. package/docs/sessions.md +237 -871
  190. package/docs/streams.md +213 -0
  191. package/docs/sub-agents.md +184 -124
  192. package/docs/tasks.md +246 -0
  193. package/docs/voice.md +745 -0
  194. package/package.json +126 -14
  195. package/dist/capability-BjSKYpzg.js.map +0 -1
  196. package/dist/capability-runner-CvHGZqUu.d.ts +0 -150
  197. package/dist/client.js.map +0 -1
  198. package/dist/compaction-helpers-iiKMr2TQ.js +0 -340
  199. package/dist/compaction-helpers-iiKMr2TQ.js.map +0 -1
  200. package/dist/compaction-helpers-wUz6M3us.d.ts +0 -621
  201. package/dist/current-agent-CuMErtly.d.ts +0 -283
  202. package/dist/diagnostics-CaBjfz4J.js.map +0 -1
  203. package/dist/durable-object-lifecycle-D6nNQJJd.js +0 -862
  204. package/dist/durable-object-lifecycle-D6nNQJJd.js.map +0 -1
  205. package/dist/experimental/memory/session/index.d.ts +0 -671
  206. package/dist/experimental/memory/session/index.js +0 -2379
  207. package/dist/experimental/memory/session/index.js.map +0 -1
  208. package/dist/experimental/memory/utils/index.d.ts +0 -96
  209. package/dist/experimental/memory/utils/index.js +0 -79
  210. package/dist/experimental/memory/utils/index.js.map +0 -1
  211. package/dist/scheduler-CR9RHGos.js +0 -857
  212. package/dist/scheduler-CR9RHGos.js.map +0 -1
  213. package/dist/src-5W6JNKVb.js.map +0 -1
  214. package/dist/tool-output-truncation-CNnnGZQ3.js +0 -98
  215. package/dist/tool-output-truncation-CNnnGZQ3.js.map +0 -1
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "durable objects"
10
10
  ],
11
11
  "type": "module",
12
- "version": "0.22.0",
12
+ "version": "0.24.0",
13
13
  "license": "MIT",
14
14
  "repository": {
15
15
  "directory": "packages/agents",
@@ -24,17 +24,19 @@
24
24
  "@babel/plugin-proposal-decorators": "^8.0.2",
25
25
  "@cfworker/json-schema": "^4.1.1",
26
26
  "@rolldown/plugin-babel": "^0.2.3",
27
+ "capnweb": "^0.12.0",
27
28
  "cron-schedule": "^6.0.0",
28
29
  "esbuild": "^0.28.1",
29
30
  "mimetext": "^3.0.28",
30
31
  "nanoid": "^5.1.16",
31
32
  "partysocket": "1.3.0",
33
+ "postal-mime": "^2.7.5",
32
34
  "yaml": "^2.9.0"
33
35
  },
34
36
  "devDependencies": {
35
37
  "@ai-sdk/react": "^4.0.0",
36
38
  "@ai-sdk/valibot": "3.0.6",
37
- "@cloudflare/codemode": "^0.5.1",
39
+ "@cloudflare/codemode": "^0.5.2",
38
40
  "@modelcontextprotocol/client": "2.0.0",
39
41
  "@modelcontextprotocol/conformance-v2": "npm:@modelcontextprotocol/conformance@0.2.0-alpha.10",
40
42
  "@modelcontextprotocol/sdk": "1.30.0",
@@ -49,8 +51,9 @@
49
51
  "glob": "^13.0.6",
50
52
  "just-bash": "^3.0.2",
51
53
  "react": "^19.2.7",
52
- "valibot": "1.4.1",
53
- "zod": "^4.4.3"
54
+ "teleproto": "^1.228.5",
55
+ "valibot": "1.4.2",
56
+ "zod": "^4.5.4"
54
57
  },
55
58
  "peerDependencies": {
56
59
  "@ai-sdk/react": "^3.0.0 || ^4.0.0",
@@ -117,6 +120,31 @@
117
120
  "import": "./dist/client.js",
118
121
  "require": "./dist/client.js"
119
122
  },
123
+ "./routing": {
124
+ "types": "./dist/routing/index.d.ts",
125
+ "import": "./dist/routing/index.js",
126
+ "require": "./dist/routing/index.js"
127
+ },
128
+ "./streams": {
129
+ "types": "./dist/streams/index.d.ts",
130
+ "import": "./dist/streams/index.js",
131
+ "require": "./dist/streams/index.js"
132
+ },
133
+ "./context": {
134
+ "types": "./dist/context/index.d.ts",
135
+ "import": "./dist/context/index.js",
136
+ "require": "./dist/context/index.js"
137
+ },
138
+ "./sessions": {
139
+ "types": "./dist/sessions/index.d.ts",
140
+ "import": "./dist/sessions/index.js",
141
+ "require": "./dist/sessions/index.js"
142
+ },
143
+ "./tasks": {
144
+ "types": "./dist/tasks/index.d.ts",
145
+ "import": "./dist/tasks/index.js",
146
+ "require": "./dist/tasks/index.js"
147
+ },
120
148
  "./lifecycle": {
121
149
  "types": "./dist/lifecycle/index.d.ts",
122
150
  "import": "./dist/lifecycle/index.js",
@@ -167,11 +195,26 @@
167
195
  "import": "./dist/react.js",
168
196
  "require": "./dist/react.js"
169
197
  },
198
+ "./websockets": {
199
+ "types": "./dist/websockets/index.d.ts",
200
+ "import": "./dist/websockets/index.js",
201
+ "require": "./dist/websockets/index.js"
202
+ },
203
+ "./state": {
204
+ "types": "./dist/state/index.d.ts",
205
+ "import": "./dist/state/index.js",
206
+ "require": "./dist/state/index.js"
207
+ },
170
208
  "./schedule": {
171
209
  "types": "./dist/schedule.d.ts",
172
210
  "import": "./dist/schedule.js",
173
211
  "require": "./dist/schedule.js"
174
212
  },
213
+ "./queue": {
214
+ "types": "./dist/queue/index.d.ts",
215
+ "import": "./dist/queue/index.js",
216
+ "require": "./dist/queue/index.js"
217
+ },
175
218
  "./schedules": {
176
219
  "types": "./dist/schedules/index.d.ts",
177
220
  "import": "./dist/schedules/index.js",
@@ -187,16 +230,6 @@
187
230
  "import": "./dist/workflows.js",
188
231
  "require": "./dist/workflows.js"
189
232
  },
190
- "./experimental/memory/session": {
191
- "types": "./dist/experimental/memory/session/index.d.ts",
192
- "import": "./dist/experimental/memory/session/index.js",
193
- "require": "./dist/experimental/memory/session/index.js"
194
- },
195
- "./experimental/memory/utils": {
196
- "types": "./dist/experimental/memory/utils/index.d.ts",
197
- "import": "./dist/experimental/memory/utils/index.js",
198
- "require": "./dist/experimental/memory/utils/index.js"
199
- },
200
233
  "./experimental/webmcp": {
201
234
  "types": "./dist/experimental/webmcp.d.ts",
202
235
  "import": "./dist/experimental/webmcp.js",
@@ -267,6 +300,81 @@
267
300
  "import": "./dist/browser/tanstack-ai.js",
268
301
  "require": "./dist/browser/tanstack-ai.js"
269
302
  },
303
+ "./voice": {
304
+ "types": "./dist/voice/index.d.ts",
305
+ "import": "./dist/voice/index.js",
306
+ "require": "./dist/voice/index.js"
307
+ },
308
+ "./voice/types": {
309
+ "types": "./dist/voice/types.d.ts",
310
+ "import": "./dist/voice/types.js",
311
+ "require": "./dist/voice/types.js"
312
+ },
313
+ "./voice/client": {
314
+ "types": "./dist/voice/client.d.ts",
315
+ "import": "./dist/voice/client.js",
316
+ "require": "./dist/voice/client.js"
317
+ },
318
+ "./voice/react": {
319
+ "types": "./dist/voice/react.d.ts",
320
+ "import": "./dist/voice/react.js",
321
+ "require": "./dist/voice/react.js"
322
+ },
323
+ "./voice/errors": {
324
+ "types": "./dist/voice/errors.d.ts",
325
+ "import": "./dist/voice/errors.js",
326
+ "require": "./dist/voice/errors.js"
327
+ },
328
+ "./voice/workers-ai": {
329
+ "types": "./dist/voice/workers-ai.d.ts",
330
+ "import": "./dist/voice/workers-ai.js",
331
+ "require": "./dist/voice/workers-ai.js"
332
+ },
333
+ "./voice/sfu": {
334
+ "types": "./dist/voice/sfu.d.ts",
335
+ "import": "./dist/voice/sfu.js",
336
+ "require": "./dist/voice/sfu.js"
337
+ },
338
+ "./voice/text": {
339
+ "types": "./dist/voice/text.d.ts",
340
+ "import": "./dist/voice/text.js",
341
+ "require": "./dist/voice/text.js"
342
+ },
343
+ "./channels": {
344
+ "types": "./dist/channels/index.d.ts",
345
+ "import": "./dist/channels/index.js",
346
+ "require": "./dist/channels/index.js"
347
+ },
348
+ "./channels/email": {
349
+ "types": "./dist/channels/email.d.ts",
350
+ "import": "./dist/channels/email.js",
351
+ "require": "./dist/channels/email.js"
352
+ },
353
+ "./channels/slack": {
354
+ "types": "./dist/channels/slack.d.ts",
355
+ "import": "./dist/channels/slack.js",
356
+ "require": "./dist/channels/slack.js"
357
+ },
358
+ "./channels/telegram": {
359
+ "types": "./dist/channels/telegram.d.ts",
360
+ "import": "./dist/channels/telegram.js",
361
+ "require": "./dist/channels/telegram.js"
362
+ },
363
+ "./channels/voice": {
364
+ "types": "./dist/channels/voice.d.ts",
365
+ "import": "./dist/channels/voice.js",
366
+ "require": "./dist/channels/voice.js"
367
+ },
368
+ "./channels/ai-sdk": {
369
+ "types": "./dist/channels/ai-sdk.d.ts",
370
+ "import": "./dist/channels/ai-sdk.js",
371
+ "require": "./dist/channels/ai-sdk.js"
372
+ },
373
+ "./channels/tanstack-ai": {
374
+ "types": "./dist/channels/tanstack-ai.d.ts",
375
+ "import": "./dist/channels/tanstack-ai.js",
376
+ "require": "./dist/channels/tanstack-ai.js"
377
+ },
270
378
  "./tsconfig": "./agents.tsconfig.json",
271
379
  "./vite": {
272
380
  "types": "./dist/vite.d.ts",
@@ -319,6 +427,10 @@
319
427
  "test": "vitest --run",
320
428
  "test:node": "vitest --project node",
321
429
  "test:react": "vitest --project react",
430
+ "test:voice:workers": "vitest --project voice-workers",
431
+ "test:voice:react": "vitest --project voice-react",
432
+ "test:channels": "vitest --project channels",
433
+ "test:channels:live": "vitest --run -c src/channels/vitest.live.config.ts",
322
434
  "test:browser": "vitest run --config src/browser-tests/vitest.config.ts",
323
435
  "test:workers": "vitest --project workers",
324
436
  "test:chat": "vitest --project chat",
@@ -1 +0,0 @@
1
- {"version":3,"file":"capability-BjSKYpzg.js","names":[],"sources":["../src/lifecycle/capability.ts"],"sourcesContent":["import type {\n CapabilityStartContext,\n DurableObjectCapability\n} from \"./capability-runner\";\n\n/** Opaque address understood by a Lifecycle routing transport. */\nexport type LifecycleRouteAddress = {\n /** Stable equality and storage key. */\n readonly key: string;\n /** Transport-owned serialized address. */\n readonly data: string;\n};\n\n/** Context supplied with a routed capability message. */\nexport type LifecycleRouteContext = {\n /** Address of the sending Lifecycle, or undefined for an unrouted root. */\n readonly source: LifecycleRouteAddress | undefined;\n /** Capability-owned message payload. */\n readonly payload: unknown;\n};\n\n/** Alarm coordination available to every Lifecycle capability. */\nexport type LifecycleAlarms = {\n /** Recompute the physical alarm from installed capability state. */\n readonly rearm: () => Promise<void>;\n /**\n * True once explicit host teardown permanently disabled alarm arming.\n * Capabilities stop dispatching durable work when this reports true.\n */\n readonly disabled: () => boolean;\n};\n\n/** Best-effort telemetry available to every Lifecycle capability. */\nexport type LifecycleEvents = {\n /** Publish an event under this capability's stable identity. */\n readonly emit: (type: string, payload: unknown) => void;\n};\n\n/** Routing available to every Lifecycle capability. */\nexport type LifecycleRoutes = {\n /** This Lifecycle's transport address, or undefined at the route root. */\n readonly source: LifecycleRouteAddress | undefined;\n /** Route a capability-owned message to the root Lifecycle. */\n readonly toRoot: (payload: unknown) => Promise<unknown>;\n /** Route a capability-owned message to another Lifecycle. */\n readonly to: (\n target: LifecycleRouteAddress,\n payload: unknown\n ) => Promise<unknown>;\n};\n\n/**\n * Standard services granted to every installed Lifecycle capability.\n *\n * @experimental The API surface may change before stabilizing.\n */\nexport type LifecycleServices = {\n readonly storage: DurableObjectStorage;\n readonly ready: () => Promise<void>;\n /** True while capability and host startup hooks are still running. */\n readonly starting: () => boolean;\n readonly alarms: LifecycleAlarms;\n /**\n * Run a capability-held user callback inside the host invocation context.\n * Capability hooks run outside host context; this is the one boundary for\n * entering it, and a host composition root may substitute its own wrapper\n * (Agent adds tracing span scope).\n */\n readonly runInHostContext: (fn: () => unknown) => Promise<unknown>;\n readonly events: LifecycleEvents;\n readonly routes: LifecycleRoutes;\n};\n\nconst installedServices = new WeakMap<object, LifecycleServices>();\n\n/**\n * Base class for capabilities that consume standard Lifecycle services.\n *\n * @experimental The API surface may change before stabilizing.\n */\nexport abstract class LifecycleCapability<Props extends object = object> {\n readonly capabilityId: string;\n\n protected constructor(capabilityId: string) {\n if (capabilityId.trim() === \"\") {\n throw new Error(\"Lifecycle capability IDs must be non-empty\");\n }\n this.capabilityId = capabilityId;\n }\n\n /** Default startup hook; capabilities override when they own startup work. */\n onStart(_context: CapabilityStartContext<Props>): void {}\n\n /** Standard services when installed, or undefined in isolated unit tests. */\n protected get lifecycleServices(): LifecycleServices | undefined {\n return installedServices.get(this);\n }\n\n /** Standard services supplied when Lifecycle installs this capability. */\n protected get lifecycle(): LifecycleServices {\n const services = this.lifecycleServices;\n if (!services) {\n throw new Error(\n `${this.constructor.name} must be installed with Lifecycle.use() before use`\n );\n }\n return services;\n }\n}\n\n/**\n * @internal Bind the standard service surface to one capability instance.\n * `Lifecycle.use()` calls this during installation. Test a capability by\n * installing it on a minimal Durable Object with a real Lifecycle rather\n * than binding fake services.\n */\nexport function bindLifecycleCapability(\n capability: LifecycleCapability,\n services: LifecycleServices\n): void {\n installedServices.set(capability, services);\n}\n\n/** @internal Read a capability ID without exposing installation internals. */\nexport function lifecycleCapabilityId(\n capability: DurableObjectCapability\n): string | undefined {\n return capability instanceof LifecycleCapability\n ? capability.capabilityId\n : undefined;\n}\n"],"mappings":";AAyEA,MAAM,oCAAoB,IAAI,QAAmC;;;;;;AAOjE,IAAsB,sBAAtB,MAAyE;CAGvE,YAAsB,cAAsB;EAC1C,IAAI,aAAa,KAAK,MAAM,IAC1B,MAAM,IAAI,MAAM,4CAA4C;EAE9D,KAAK,eAAe;CACtB;;CAGA,QAAQ,UAA+C,CAAC;;CAGxD,IAAc,oBAAmD;EAC/D,OAAO,kBAAkB,IAAI,IAAI;CACnC;;CAGA,IAAc,YAA+B;EAC3C,MAAM,WAAW,KAAK;EACtB,IAAI,CAAC,UACH,MAAM,IAAI,MACR,GAAG,KAAK,YAAY,KAAK,mDAC3B;EAEF,OAAO;CACT;AACF;;;;;;;AAQA,SAAgB,wBACd,YACA,UACM;CACN,kBAAkB,IAAI,YAAY,QAAQ;AAC5C;;AAGA,SAAgB,sBACd,YACoB;CACpB,OAAO,sBAAsB,sBACzB,WAAW,eACX,KAAA;AACN"}
@@ -1,150 +0,0 @@
1
- //#region src/lifecycle/capability.d.ts
2
- /** Opaque address understood by a Lifecycle routing transport. */
3
- type LifecycleRouteAddress = {
4
- /** Stable equality and storage key. */ readonly key: string /** Transport-owned serialized address. */;
5
- readonly data: string;
6
- };
7
- /** Context supplied with a routed capability message. */
8
- type LifecycleRouteContext = {
9
- /** Address of the sending Lifecycle, or undefined for an unrouted root. */ readonly source:
10
- | LifecycleRouteAddress
11
- | undefined /** Capability-owned message payload. */;
12
- readonly payload: unknown;
13
- };
14
- /** Alarm coordination available to every Lifecycle capability. */
15
- type LifecycleAlarms = {
16
- /** Recompute the physical alarm from installed capability state. */ readonly rearm: () => Promise<void>;
17
- /**
18
- * True once explicit host teardown permanently disabled alarm arming.
19
- * Capabilities stop dispatching durable work when this reports true.
20
- */
21
- readonly disabled: () => boolean;
22
- };
23
- /** Best-effort telemetry available to every Lifecycle capability. */
24
- type LifecycleEvents = {
25
- /** Publish an event under this capability's stable identity. */ readonly emit: (
26
- type: string,
27
- payload: unknown
28
- ) => void;
29
- };
30
- /** Routing available to every Lifecycle capability. */
31
- type LifecycleRoutes = {
32
- /** This Lifecycle's transport address, or undefined at the route root. */ readonly source:
33
- | LifecycleRouteAddress
34
- | undefined /** Route a capability-owned message to the root Lifecycle. */;
35
- readonly toRoot: (
36
- payload: unknown
37
- ) => Promise<unknown> /** Route a capability-owned message to another Lifecycle. */;
38
- readonly to: (
39
- target: LifecycleRouteAddress,
40
- payload: unknown
41
- ) => Promise<unknown>;
42
- };
43
- /**
44
- * Standard services granted to every installed Lifecycle capability.
45
- *
46
- * @experimental The API surface may change before stabilizing.
47
- */
48
- type LifecycleServices = {
49
- readonly storage: DurableObjectStorage;
50
- readonly ready: () => Promise<void> /** True while capability and host startup hooks are still running. */;
51
- readonly starting: () => boolean;
52
- readonly alarms: LifecycleAlarms;
53
- /**
54
- * Run a capability-held user callback inside the host invocation context.
55
- * Capability hooks run outside host context; this is the one boundary for
56
- * entering it, and a host composition root may substitute its own wrapper
57
- * (Agent adds tracing span scope).
58
- */
59
- readonly runInHostContext: (fn: () => unknown) => Promise<unknown>;
60
- readonly events: LifecycleEvents;
61
- readonly routes: LifecycleRoutes;
62
- };
63
- /**
64
- * Base class for capabilities that consume standard Lifecycle services.
65
- *
66
- * @experimental The API surface may change before stabilizing.
67
- */
68
- declare abstract class LifecycleCapability<Props extends object = object> {
69
- readonly capabilityId: string;
70
- protected constructor(capabilityId: string);
71
- /** Default startup hook; capabilities override when they own startup work. */
72
- onStart(_context: CapabilityStartContext<Props>): void;
73
- /** Standard services when installed, or undefined in isolated unit tests. */
74
- protected get lifecycleServices(): LifecycleServices | undefined;
75
- /** Standard services supplied when Lifecycle installs this capability. */
76
- protected get lifecycle(): LifecycleServices;
77
- }
78
- //#endregion
79
- //#region src/lifecycle/capability-runner.d.ts
80
- type MaybePromise<T> = T | Promise<T>;
81
- /** One capability's requested physical alarm. */
82
- type AlarmContribution =
83
- | number
84
- | {
85
- /** Epoch time in milliseconds. */ readonly time: number /** Ignore ordinary wake-time candidates while this request exists. */;
86
- readonly exclusive: true;
87
- }
88
- | null;
89
- /** One best-effort event published by a Lifecycle capability. */
90
- type LifecycleEvent = {
91
- /** Stable capability or subsystem name. */ readonly source: string /** Stable event name within that source. */;
92
- readonly type: string /** Event-specific data. */;
93
- readonly payload: unknown;
94
- };
95
- /** Context supplied when durable capabilities start. */
96
- type CapabilityStartContext<Props extends object = object> = {
97
- /** Properties supplied while resolving the Durable Object. */ readonly props:
98
- | Props
99
- | undefined;
100
- };
101
- /** Context supplied when durable capabilities inspect an HTTP request. */
102
- type CapabilityRequestContext = {
103
- /** The request entering the Durable Object. */ readonly request: Request;
104
- };
105
- /**
106
- * A capability installed into a Durable Object lifecycle.
107
- *
108
- * Capabilities extending `LifecycleCapability` receive the standard storage,
109
- * readiness, alarm, event, and routing surface. Host-specific bindings and
110
- * protocol adapters remain explicit constructor dependencies. Hook parameters
111
- * carry only phase data; hooks do not run in ambient host context.
112
- *
113
- * @experimental The API surface may change before stabilizing.
114
- */
115
- interface DurableObjectCapability<Props extends object = object> {
116
- /** Initialize or recover the capability before the host handles work. */
117
- onStart?(context: CapabilityStartContext<Props>): MaybePromise<void>;
118
- /**
119
- * Inspect an HTTP request before the host's request handler.
120
- *
121
- * Return a response to handle the request, or `undefined` to continue.
122
- */
123
- onRequest?(
124
- context: CapabilityRequestContext
125
- ): MaybePromise<Response | undefined | void>;
126
- /** Run work assigned to the capability when the host's alarm fires. */
127
- onAlarm?(): MaybePromise<void>;
128
- /** Handle one message routed to this capability identity. */
129
- onRoute?(context: LifecycleRouteContext): MaybePromise<unknown>;
130
- /** Return this capability's next requested physical alarm. */
131
- getNextAlarm?(): MaybePromise<AlarmContribution>;
132
- /** Release live or in-memory resources during explicit host destruction. */
133
- dispose?(): MaybePromise<void>;
134
- }
135
- //#endregion
136
- export {
137
- LifecycleEvent as a,
138
- LifecycleEvents as c,
139
- LifecycleRoutes as d,
140
- LifecycleServices as f,
141
- DurableObjectCapability as i,
142
- LifecycleRouteAddress as l,
143
- CapabilityRequestContext as n,
144
- LifecycleAlarms as o,
145
- CapabilityStartContext as r,
146
- LifecycleCapability as s,
147
- AlarmContribution as t,
148
- LifecycleRouteContext as u
149
- };
150
- //# sourceMappingURL=capability-runner-CvHGZqUu.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"client.js","names":[],"sources":["../src/client.ts"],"sourcesContent":["import {\n type PartyFetchOptions,\n PartySocket,\n type PartySocketOptions\n} from \"partysocket\";\nimport type { Agent, RPCRequest, RPCResponse } from \"./\";\nimport type {\n ClientParameters,\n Method,\n RPCMethod,\n SerializableReturnValue,\n SerializableValue\n} from \"./serializable\";\nimport { MessageType } from \"./types\";\nimport { camelCaseToKebabCase, isInternalJsStubProp } from \"./utils\";\n\nexport class AgentConnectionError extends Error {\n code: number;\n reason: string;\n wasClean: boolean;\n\n constructor(event: CloseEvent) {\n const reason = event.reason || `WebSocket closed with code ${event.code}`;\n super(`Agent connection closed: ${reason}`);\n this.name = \"AgentConnectionError\";\n this.code = event.code;\n this.reason = event.reason;\n this.wasClean = event.wasClean;\n }\n}\n\nexport function isTerminalCloseEvent(event: CloseEvent): boolean {\n return event.code === 1008 || (event.code >= 4000 && event.code <= 4999);\n}\n\ntype TerminalReconnectOptions = {\n shouldReconnectOnClose?: (event: CloseEvent) => boolean;\n};\n\n/**\n * Options for creating an AgentClient\n */\nexport type AgentClientOptions<State = unknown> = Omit<\n PartySocketOptions,\n \"party\" | \"room\"\n> &\n TerminalReconnectOptions & {\n /** Name of the agent to connect to (ignored if basePath is set) */\n agent: string;\n /** Name of the specific Agent instance (ignored if basePath is set) */\n name?: string;\n /**\n * Full URL path - bypasses agent/name URL construction.\n * When set, the client connects to this path directly.\n * Server must handle routing manually (e.g., with getAgentByName + fetch).\n * @example\n * // Client connects to /user, server routes based on session\n * useAgent({ agent: \"UserAgent\", basePath: \"user\" })\n */\n basePath?: string;\n /** Called when the Agent's state is updated */\n onStateUpdate?: (state: State, source: \"server\" | \"client\") => void;\n /** Called when a state update fails (e.g., connection is readonly) */\n onStateUpdateError?: (error: string) => void;\n /**\n * Called when the server sends the agent's identity on connect.\n * Useful when using basePath, as the actual instance name is determined server-side.\n * @param name The actual agent instance name\n * @param agent The agent class name (kebab-case)\n */\n onIdentity?: (name: string, agent: string) => void;\n /**\n * Called when identity changes on reconnect (different instance than before).\n * If not provided and identity changes, a warning will be logged.\n * @param oldName Previous instance name\n * @param newName New instance name\n * @param oldAgent Previous agent class name\n * @param newAgent New agent class name\n */\n onIdentityChange?: (\n oldName: string,\n newName: string,\n oldAgent: string,\n newAgent: string\n ) => void;\n /**\n * Additional path to append to the URL.\n * Works with both standard routing and basePath.\n * @example\n * // With basePath: /user/settings\n * { basePath: \"user\", path: \"settings\" }\n * // Standard: /agents/my-agent/room/settings\n * { agent: \"MyAgent\", name: \"room\", path: \"settings\" }\n */\n path?: string;\n /**\n * Default timeout (in milliseconds) applied to non-streaming `call()`s\n * that don't pass an explicit `timeout`. Defaults to 30 000 ms.\n * Set to `0` to disable. Streaming calls never get a default timeout.\n */\n defaultCallTimeout?: number;\n /** Called when the connection closes with a terminal code and will not reconnect. */\n onConnectionError?: (error: AgentConnectionError) => void;\n };\n\n/**\n * Default timeout (in milliseconds) applied to non-streaming RPC calls\n * that don't pass an explicit `timeout`. Acts as a backstop so calls\n * whose response is lost (e.g. the connection drops mid-flight) reject\n * instead of hanging forever. Override per client via\n * `defaultCallTimeout`, or per call via `timeout` (0 disables).\n */\nexport const DEFAULT_CALL_TIMEOUT_MS = 30_000;\n\n/**\n * Options for streaming RPC calls\n */\nexport type StreamOptions = {\n /** Called when a chunk of data is received */\n onChunk?: (chunk: unknown) => void;\n /** Called when the stream ends */\n onDone?: (finalChunk: unknown) => void;\n /** Called when an error occurs */\n onError?: (error: string) => void;\n};\n\n/**\n * Options for RPC calls\n */\nexport type CallOptions = {\n /** Timeout in milliseconds. If the call doesn't complete within this time, it will be rejected. */\n timeout?: number;\n /** Streaming options for handling streaming responses */\n stream?: StreamOptions;\n};\n\n/**\n * Options for the agentFetch function\n */\nexport type AgentClientFetchOptions = Omit<\n PartyFetchOptions,\n \"party\" | \"room\"\n> & {\n /** Name of the agent to connect to (ignored if basePath is set) */\n agent: string;\n /** Name of the specific Agent instance (ignored if basePath is set) */\n name?: string;\n /**\n * Full URL path - bypasses agent/name URL construction.\n * When set, the request is made to this path directly.\n */\n basePath?: string;\n};\n\n// ---- Shared RPC Type Utilities ----\n\ntype AllOptional<T> = T extends [infer A, ...infer R]\n ? undefined extends A\n ? AllOptional<R>\n : false\n : true;\n\nexport type RPCMethods<T> = {\n [K in keyof T as T[K] extends RPCMethod<T[K]> ? K : never]: RPCMethod<T[K]>;\n};\n\ntype OptionalParametersMethod<T extends RPCMethod> =\n AllOptional<ClientParameters<T>> extends true ? T : never;\n\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any -- generic agent type constraint\nexport type AgentMethods<T> = Omit<RPCMethods<T>, keyof Agent<any, any>>;\n\nexport type OptionalAgentMethods<T> = {\n [K in keyof AgentMethods<T> as AgentMethods<T>[K] extends OptionalParametersMethod<\n AgentMethods<T>[K]\n >\n ? K\n : never]: OptionalParametersMethod<AgentMethods<T>[K]>;\n};\n\nexport type RequiredAgentMethods<T> = Omit<\n AgentMethods<T>,\n keyof OptionalAgentMethods<T>\n>;\n\nexport type AgentPromiseReturnType<T, K extends keyof AgentMethods<T>> =\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any -- generic promise return type\n ReturnType<AgentMethods<T>[K]> extends Promise<any>\n ? ReturnType<AgentMethods<T>[K]>\n : Promise<ReturnType<AgentMethods<T>[K]>>;\n\nexport type AgentStub<T> = {\n [K in keyof AgentMethods<T>]: (\n ...args: ClientParameters<AgentMethods<T>[K]>\n ) => AgentPromiseReturnType<AgentMethods<T>, K>;\n};\n\nexport type UntypedAgentStub = Record<string, Method>;\n\ntype AgentClientStub<AgentT> = keyof AgentMethods<AgentT> extends never\n ? UntypedAgentStub\n : AgentStub<AgentT>;\n\ntype OptionalArgsAgentClientCall<AgentT> = <\n K extends keyof OptionalAgentMethods<AgentT>\n>(\n method: K,\n args?: ClientParameters<OptionalAgentMethods<AgentT>[K]>,\n options?: CallOptions | StreamOptions\n) => AgentPromiseReturnType<AgentT, K>;\n\ntype RequiredArgsAgentClientCall<AgentT> = <\n K extends keyof RequiredAgentMethods<AgentT>\n>(\n method: K,\n args: ClientParameters<RequiredAgentMethods<AgentT>[K]>,\n options?: CallOptions | StreamOptions\n) => AgentPromiseReturnType<AgentT, K>;\n\ntype TypedAgentClientCall<AgentT> = OptionalArgsAgentClientCall<AgentT> &\n RequiredArgsAgentClientCall<AgentT>;\n\ntype UntypedAgentClientCall = {\n <T extends SerializableReturnValue>(\n method: string,\n args?: SerializableValue[],\n options?: CallOptions | StreamOptions\n ): Promise<T>;\n <T = unknown>(\n method: string,\n args?: unknown[],\n options?: CallOptions | StreamOptions\n ): Promise<T>;\n};\n\ntype AgentClientCall<AgentT> = keyof AgentMethods<AgentT> extends never\n ? UntypedAgentClientCall\n : TypedAgentClientCall<AgentT>;\n\n/**\n * Creates a proxy that wraps RPC method calls.\n * Internal JS methods (toJSON, then, etc.) return undefined to avoid\n * triggering RPC calls during serialization (e.g., console.log)\n */\nexport function createStubProxy<T = Record<string, Method>>(\n call: (method: string, args: unknown[]) => unknown\n): T {\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any -- proxy needs any for dynamic method access\n return new Proxy<any>(\n {},\n {\n get: (_target, method) => {\n if (isInternalJsStubProp(method)) {\n return undefined;\n }\n return (...args: unknown[]) => call(method as string, args);\n }\n }\n );\n}\n\n/**\n * WebSocket client for connecting to an Agent\n */\nexport class AgentClient<\n AgentT = unknown,\n State = AgentT extends { get state(): infer S } ? S : AgentT\n> extends PartySocket {\n /**\n * @deprecated Use agentFetch instead\n */\n static fetch(_opts: PartyFetchOptions): Promise<Response> {\n throw new Error(\n \"AgentClient.fetch is not implemented, use agentFetch instead\"\n );\n }\n agent: string;\n name: string;\n call: AgentClientCall<AgentT>;\n stub: AgentClientStub<AgentT>;\n\n /**\n * The current agent state, updated on server broadcasts and client setState calls.\n * Starts as undefined until the first state message is received from the server.\n */\n state: State | undefined = undefined;\n\n /**\n * Whether the client has received identity from the server.\n * Becomes true after the first identity message is received.\n * Resets to false on connection close.\n */\n identified = false;\n\n /**\n * Terminal connection error, if the server closed the socket with a code\n * that should not be retried automatically.\n */\n connectionError: AgentConnectionError | null = null;\n\n /**\n * Promise that resolves when identity has been received from the server.\n * Useful for waiting before making calls that depend on knowing the instance.\n * Resets on connection close so it can be awaited again after reconnect.\n */\n get ready(): Promise<void> {\n return this._readyPromise;\n }\n\n private options: AgentClientOptions<State>;\n private _pendingCalls = new Map<\n string,\n {\n resolve: (value: unknown) => void;\n reject: (error: Error) => void;\n stream?: StreamOptions;\n /**\n * Whether the request was actually transmitted to the server.\n * Requests issued while disconnected sit in PartySocket's internal\n * buffer (transmitted: false) and are flushed on the next open —\n * they survive a transient close instead of being rejected, since\n * the server never saw them and re-delivery can't double-execute.\n */\n transmitted: boolean;\n }\n >();\n private _readyPromise!: Promise<void>;\n private _resolveReady!: () => void;\n private _previousName: string | null = null;\n private _previousAgent: string | null = null;\n\n private _resetReady() {\n this._readyPromise = new Promise((resolve) => {\n this._resolveReady = resolve;\n });\n }\n\n constructor(options: AgentClientOptions<State>) {\n const agentNamespace = camelCaseToKebabCase(options.agent);\n const shouldReconnectOnClose = options.shouldReconnectOnClose;\n const classifyReconnect = (event: CloseEvent) =>\n (shouldReconnectOnClose?.(event) ?? true) && !isTerminalCloseEvent(event);\n\n // If basePath is provided, use it directly; otherwise construct from agent/name\n const socketOptions = options.basePath\n ? {\n basePath: options.basePath,\n path: options.path,\n ...options,\n shouldReconnectOnClose: classifyReconnect\n }\n : {\n party: agentNamespace,\n prefix: \"agents\",\n room: options.name || \"default\",\n path: options.path,\n ...options,\n shouldReconnectOnClose: classifyReconnect\n };\n\n super(socketOptions);\n this.agent = agentNamespace;\n this.name = options.name || \"default\";\n this.options = options;\n\n // Initialize ready promise\n this._resetReady();\n\n this.addEventListener(\"message\", (event) => {\n if (typeof event.data === \"string\") {\n let parsedMessage: Record<string, unknown>;\n try {\n parsedMessage = JSON.parse(event.data);\n } catch (_error) {\n // silently ignore invalid messages for now\n // TODO: log errors with log levels\n return;\n }\n if (parsedMessage.type === MessageType.CF_AGENT_IDENTITY) {\n const oldName = this._previousName;\n const oldAgent = this._previousAgent;\n const newName = parsedMessage.name as string;\n const newAgent = parsedMessage.agent as string;\n\n // Resolve ready/identified\n this.identified = true;\n this._resolveReady();\n\n // Detect identity change on reconnect\n if (\n oldName !== null &&\n oldAgent !== null &&\n (oldName !== newName || oldAgent !== newAgent)\n ) {\n if (this.options.onIdentityChange) {\n this.options.onIdentityChange(\n oldName,\n newName,\n oldAgent,\n newAgent\n );\n } else {\n const agentChanged = oldAgent !== newAgent;\n const nameChanged = oldName !== newName;\n let changeDescription = \"\";\n if (agentChanged && nameChanged) {\n changeDescription = `agent \"${oldAgent}\" → \"${newAgent}\", instance \"${oldName}\" → \"${newName}\"`;\n } else if (agentChanged) {\n changeDescription = `agent \"${oldAgent}\" → \"${newAgent}\"`;\n } else {\n changeDescription = `instance \"${oldName}\" → \"${newName}\"`;\n }\n console.warn(\n `[agents] Identity changed on reconnect: ${changeDescription}. ` +\n \"This can happen with server-side routing (e.g., basePath with getAgentByName) \" +\n \"where the instance is determined by auth/session. \" +\n \"Provide onIdentityChange callback to handle this explicitly, \" +\n \"or ignore if this is expected for your routing pattern.\"\n );\n }\n }\n\n // Always update from server identity (server is authoritative)\n this._previousName = newName;\n this._previousAgent = newAgent;\n this.name = newName;\n this.agent = newAgent;\n\n // Call onIdentity callback\n this.options.onIdentity?.(newName, newAgent);\n return;\n }\n if (parsedMessage.type === MessageType.CF_AGENT_STATE) {\n this.state = parsedMessage.state as State;\n this.options.onStateUpdate?.(parsedMessage.state as State, \"server\");\n return;\n }\n if (parsedMessage.type === MessageType.CF_AGENT_STATE_ERROR) {\n this.options.onStateUpdateError?.(parsedMessage.error as string);\n return;\n }\n if (parsedMessage.type === MessageType.RPC) {\n const response = parsedMessage as RPCResponse;\n const pending = this._pendingCalls.get(response.id);\n if (!pending) {\n console.warn(\n `[AgentClient] Discarded an RPC response with no matching pending call (id \"${response.id}\"). ` +\n \"The call likely timed out or was rejected when its connection closed before the response arrived.\"\n );\n return;\n }\n\n if (!response.success) {\n pending.reject(new Error(response.error));\n this._pendingCalls.delete(response.id);\n pending.stream?.onError?.(response.error);\n return;\n }\n\n // Handle streaming responses\n if (\"done\" in response) {\n if (response.done) {\n pending.resolve(response.result);\n this._pendingCalls.delete(response.id);\n pending.stream?.onDone?.(response.result);\n } else {\n pending.stream?.onChunk?.(response.result);\n }\n } else {\n // Non-streaming response\n pending.resolve(response.result);\n this._pendingCalls.delete(response.id);\n }\n }\n }\n });\n\n // PartySocket flushes its internal message buffer right before\n // dispatching \"open\" — anything queued has now been transmitted.\n this.addEventListener(\"open\", () => {\n this.connectionError = null;\n for (const pending of this._pendingCalls.values()) {\n pending.transmitted = true;\n }\n });\n\n // Clean up pending calls and reset ready state when connection closes\n this.addEventListener(\"close\", (event) => {\n const terminalClose = isTerminalCloseEvent(event);\n // Reset ready state for next connection\n this.identified = false;\n this._resetReady();\n\n if (this.shouldReconnect) {\n // Transient disconnect: reject calls whose request was already\n // transmitted — their response can never arrive. Buffered calls\n // stay pending; PartySocket re-sends them on reconnect.\n this._rejectPendingCalls(\"Connection closed\", {\n onlyTransmitted: true\n });\n } else {\n // Permanent close (close() called or retries exhausted): nothing\n // will ever flush the buffer, so reject everything.\n this._rejectPendingCalls(\"Connection closed\");\n if (terminalClose) {\n const error = new AgentConnectionError(event);\n this.connectionError = error;\n this.options.onConnectionError?.(error);\n }\n }\n });\n\n this.call = this._callImpl.bind(this) as AgentClientCall<AgentT>;\n this.stub = createStubProxy((method, args) =>\n this._callImpl(method, args)\n ) as AgentClientStub<AgentT>;\n }\n\n /**\n * Reject pending RPC calls with the given reason.\n * With `onlyTransmitted`, calls still sitting in the send buffer are\n * kept pending (they'll be flushed on reconnect).\n */\n private _rejectPendingCalls(\n reason: string,\n { onlyTransmitted = false }: { onlyTransmitted?: boolean } = {}\n ) {\n const error = new Error(reason);\n for (const [id, pending] of this._pendingCalls) {\n if (onlyTransmitted && !pending.transmitted) continue;\n this._pendingCalls.delete(id);\n pending.reject(error);\n pending.stream?.onError?.(reason);\n }\n }\n\n setState(state: State) {\n this.send(JSON.stringify({ state, type: MessageType.CF_AGENT_STATE }));\n this.state = state;\n this.options.onStateUpdate?.(state, \"client\");\n }\n\n /**\n * Close the connection and immediately reject all pending RPC calls.\n * This provides immediate feedback on intentional close rather than\n * waiting for the WebSocket close handshake to complete.\n *\n * Note: Any calls made after `close()` will be rejected when the\n * underlying WebSocket close event fires.\n */\n close(code?: number, reason?: string) {\n // Immediately reject all pending calls on intentional close\n this._rejectPendingCalls(\"Connection closed\");\n\n // Then close the underlying socket\n super.close(code, reason);\n }\n\n /**\n * Call a method on the Agent.\n * When AgentT is provided, method names are inferred from the agent's methods.\n * Falls back to untyped string-based calls when AgentT is not provided.\n */\n private async _callImpl(\n method: string,\n args: unknown[] = [],\n options?: CallOptions | StreamOptions\n ): Promise<unknown> {\n if (this.connectionError && this.readyState === this.CLOSED) {\n throw new Error(\"Connection closed\");\n }\n\n return new Promise((resolve, reject) => {\n const id = crypto.randomUUID();\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n\n // Detect legacy format: { onChunk?, onDone?, onError? } vs new format: { timeout?, stream? }\n const isLegacyFormat =\n options &&\n (\"onChunk\" in options || \"onDone\" in options || \"onError\" in options);\n const streamOptions = isLegacyFormat\n ? (options as StreamOptions)\n : (options as CallOptions | undefined)?.stream;\n const timeout = isLegacyFormat\n ? undefined\n : (options as CallOptions | undefined)?.timeout;\n\n // Apply the default timeout as a backstop for non-streaming calls\n // so a lost response rejects instead of hanging forever. An\n // explicit `timeout` (including 0 = disabled) always wins.\n const effectiveTimeout =\n timeout !== undefined\n ? timeout\n : streamOptions\n ? undefined\n : (this.options.defaultCallTimeout ?? DEFAULT_CALL_TIMEOUT_MS);\n\n if (effectiveTimeout) {\n timeoutId = setTimeout(() => {\n const pending = this._pendingCalls.get(id);\n this._pendingCalls.delete(id);\n const errorMessage = `RPC call to ${method} timed out after ${effectiveTimeout}ms`;\n pending?.stream?.onError?.(errorMessage);\n reject(new Error(errorMessage));\n }, effectiveTimeout);\n }\n\n this._pendingCalls.set(id, {\n reject: (e: Error) => {\n if (timeoutId) clearTimeout(timeoutId);\n reject(e);\n },\n resolve: (value: unknown) => {\n if (timeoutId) clearTimeout(timeoutId);\n resolve(value);\n },\n stream: streamOptions,\n // If the socket is open, send() below transmits synchronously;\n // otherwise the request is buffered until the next open event\n // (the \"open\" listener then marks it transmitted).\n transmitted: this.readyState === this.OPEN\n });\n\n const request: RPCRequest = {\n args,\n id,\n method,\n type: MessageType.RPC\n };\n\n this.send(JSON.stringify(request));\n });\n }\n}\n\n/**\n * Make an HTTP request to an Agent\n * @param opts Connection options\n * @param init Request initialization options\n * @returns Promise resolving to a Response\n */\nexport function agentFetch(opts: AgentClientFetchOptions, init?: RequestInit) {\n const agentNamespace = camelCaseToKebabCase(opts.agent);\n\n // If basePath is provided, use it directly; otherwise construct from agent/name\n // When basePath is set, room/party aren't used by PartySocket (basePath replaces the URL)\n if (opts.basePath) {\n return PartySocket.fetch(\n { basePath: opts.basePath, ...opts } as unknown as PartyFetchOptions,\n init\n );\n }\n\n return PartySocket.fetch(\n {\n party: agentNamespace,\n prefix: \"agents\",\n room: opts.name || \"default\",\n ...opts\n },\n init\n );\n}\n"],"mappings":"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"}