agents 0.22.0 → 0.23.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 (186) hide show
  1. package/README.md +20 -1
  2. package/dist/{agent-routing-CnkaHb-v.d.ts → agent-routing-DE5zmCQ8.d.ts} +1038 -394
  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-DtXMTDGM.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.map +1 -1
  15. package/dist/capability-runner-Be_-PLR1.d.ts +459 -0
  16. package/dist/channel-Bnm4S7T2.d.ts +491 -0
  17. package/dist/channels/ai-sdk.d.ts +46 -0
  18. package/dist/channels/ai-sdk.js +120 -0
  19. package/dist/channels/ai-sdk.js.map +1 -0
  20. package/dist/channels/email.d.ts +95 -0
  21. package/dist/channels/email.js +323 -0
  22. package/dist/channels/email.js.map +1 -0
  23. package/dist/channels/index.d.ts +233 -0
  24. package/dist/channels/index.js +608 -0
  25. package/dist/channels/index.js.map +1 -0
  26. package/dist/channels/slack.d.ts +140 -0
  27. package/dist/channels/slack.js +614 -0
  28. package/dist/channels/slack.js.map +1 -0
  29. package/dist/channels/tanstack-ai.d.ts +39 -0
  30. package/dist/channels/tanstack-ai.js +17 -0
  31. package/dist/channels/tanstack-ai.js.map +1 -0
  32. package/dist/channels/telegram.d.ts +106 -0
  33. package/dist/channels/telegram.js +427 -0
  34. package/dist/channels/telegram.js.map +1 -0
  35. package/dist/channels/voice.d.ts +45 -0
  36. package/dist/channels/voice.js +122 -0
  37. package/dist/channels/voice.js.map +1 -0
  38. package/dist/chat/index.d.ts +2325 -2019
  39. package/dist/chat/index.js +888 -518
  40. package/dist/chat/index.js.map +1 -1
  41. package/dist/chat-sdk/index.d.ts +7 -7
  42. package/dist/chat-sdk/index.js +1 -1
  43. package/dist/client.d.ts +1 -1
  44. package/dist/context/index.d.ts +216 -0
  45. package/dist/context/index.js +454 -0
  46. package/dist/context/index.js.map +1 -0
  47. package/dist/{current-agent-CuMErtly.d.ts → current-agent-Da_C9a3b.d.ts} +90 -107
  48. package/dist/current-agent-DhoDkSnH.js.map +1 -1
  49. package/dist/{diagnostics-CaBjfz4J.js → diagnostics-BzvaX2UT.js} +5 -1
  50. package/dist/diagnostics-BzvaX2UT.js.map +1 -0
  51. package/dist/diagnostics-C4jcz3VK.js +360 -0
  52. package/dist/diagnostics-C4jcz3VK.js.map +1 -0
  53. package/dist/index-BB0kqhIz.d.ts +101 -0
  54. package/dist/index-BVVgDSdq.d.ts +1 -0
  55. package/dist/index-XDkuQ7zm.d.ts +89 -0
  56. package/dist/{index-DcSAZKsB.d.ts → index-YSKgfgg9.d.ts} +3 -1
  57. package/dist/index.d.ts +91 -82
  58. package/dist/index.js +3 -2
  59. package/dist/ingress-BfetZbMO.js +83 -0
  60. package/dist/ingress-BfetZbMO.js.map +1 -0
  61. package/dist/internal-CYlgHl1l.js +59 -0
  62. package/dist/internal-CYlgHl1l.js.map +1 -0
  63. package/dist/internal_context.d.ts +1 -1
  64. package/dist/lifecycle/index.d.ts +35 -17
  65. package/dist/lifecycle/index.js +1 -1
  66. package/dist/lifecycle-CMRGjZdw.js +1299 -0
  67. package/dist/lifecycle-CMRGjZdw.js.map +1 -0
  68. package/dist/mcp/client/index.d.ts +20 -20
  69. package/dist/mcp/index.d.ts +35 -35
  70. package/dist/mcp/index.js +1 -1
  71. package/dist/observability/index.d.ts +1 -1
  72. package/dist/observability/index.js +1 -1
  73. package/dist/react.d.ts +4 -4
  74. package/dist/{retries-CAvxtG9d.d.ts → retries-D9Ds-1lz.d.ts} +17 -6
  75. package/dist/retries.d.ts +8 -6
  76. package/dist/retries.js +13 -1
  77. package/dist/retries.js.map +1 -1
  78. package/dist/routing/index.d.ts +137 -0
  79. package/dist/routing/index.js +244 -0
  80. package/dist/routing/index.js.map +1 -0
  81. package/dist/sanitize-D9TujEK8.js +79 -0
  82. package/dist/sanitize-D9TujEK8.js.map +1 -0
  83. package/dist/scheduler-DD9NdYbF.js +665 -0
  84. package/dist/scheduler-DD9NdYbF.js.map +1 -0
  85. package/dist/{scheduler-DQoTGoAW.d.ts → scheduler-Dwh85ZGl.d.ts} +21 -22
  86. package/dist/schedules/index.d.ts +1 -1
  87. package/dist/schedules/index.js +1 -1
  88. package/dist/sentence-chunker-BAidJ4DA.d.ts +68 -0
  89. package/dist/serializable.d.ts +1 -1
  90. package/dist/sessions/index.d.ts +441 -0
  91. package/dist/sessions/index.js +2063 -0
  92. package/dist/sessions/index.js.map +1 -0
  93. package/dist/skills/index.d.ts +99 -0
  94. package/dist/skills/index.js +254 -5
  95. package/dist/skills/index.js.map +1 -1
  96. package/dist/{src-5W6JNKVb.js → src-DlSHshb2.js} +1460 -1110
  97. package/dist/src-DlSHshb2.js.map +1 -0
  98. package/dist/streams/index.d.ts +120 -0
  99. package/dist/streams/index.js +107 -0
  100. package/dist/streams/index.js.map +1 -0
  101. package/dist/streams-D6tJ0NN9.d.ts +370 -0
  102. package/dist/streams-DZKgAj9b.js +709 -0
  103. package/dist/streams-DZKgAj9b.js.map +1 -0
  104. package/dist/sub-routing.d.ts +12 -12
  105. package/dist/surface-bZZJqBka.js +17 -0
  106. package/dist/surface-bZZJqBka.js.map +1 -0
  107. package/dist/tasks/index.d.ts +64 -0
  108. package/dist/tasks/index.js +2 -0
  109. package/dist/tasks-BRJ5zgya.d.ts +517 -0
  110. package/dist/tasks-ylZgBjhj.js +1656 -0
  111. package/dist/tasks-ylZgBjhj.js.map +1 -0
  112. package/dist/text-segment-joiner-BtAFQSA_.js +57 -0
  113. package/dist/text-segment-joiner-BtAFQSA_.js.map +1 -0
  114. package/dist/text-stream-CpdiKrJB.js +272 -0
  115. package/dist/text-stream-CpdiKrJB.js.map +1 -0
  116. package/dist/tokens-nHAKcN6M.js +52 -0
  117. package/dist/tokens-nHAKcN6M.js.map +1 -0
  118. package/dist/tool-schema-CBjGPrsQ.js +31 -0
  119. package/dist/tool-schema-CBjGPrsQ.js.map +1 -0
  120. package/dist/types-B7LojTe4.d.ts +202 -0
  121. package/dist/types-_Faxb570.d.ts +439 -0
  122. package/dist/voice/client.d.ts +226 -0
  123. package/dist/voice/client.js +932 -0
  124. package/dist/voice/client.js.map +1 -0
  125. package/dist/voice/errors.d.ts +43 -0
  126. package/dist/voice/errors.js +41 -0
  127. package/dist/voice/errors.js.map +1 -0
  128. package/dist/voice/index.d.ts +271 -0
  129. package/dist/voice/index.js +1812 -0
  130. package/dist/voice/index.js.map +1 -0
  131. package/dist/voice/react.d.ts +167 -0
  132. package/dist/voice/react.js +234 -0
  133. package/dist/voice/react.js.map +1 -0
  134. package/dist/voice/sfu.d.ts +71 -0
  135. package/dist/voice/sfu.js +157 -0
  136. package/dist/voice/sfu.js.map +1 -0
  137. package/dist/voice/text.d.ts +6 -0
  138. package/dist/voice/text.js +2 -0
  139. package/dist/voice/types.d.ts +58 -0
  140. package/dist/voice/types.js +18 -0
  141. package/dist/voice/types.js.map +1 -0
  142. package/dist/voice/workers-ai.d.ts +136 -0
  143. package/dist/voice/workers-ai.js +568 -0
  144. package/dist/voice/workers-ai.js.map +1 -0
  145. package/dist/websockets/index.d.ts +192 -0
  146. package/dist/websockets/index.js +2 -0
  147. package/dist/websockets-DUfRHPRq.js +502 -0
  148. package/dist/websockets-DUfRHPRq.js.map +1 -0
  149. package/dist/workflow-types.d.ts +25 -25
  150. package/dist/workflows.d.ts +21 -21
  151. package/dist/workflows.js +1 -1
  152. package/docs/agent-class.md +2 -2
  153. package/docs/agent-tools.md +2 -1
  154. package/docs/channels.md +323 -0
  155. package/docs/chat-agents.md +6 -13
  156. package/docs/context.md +131 -0
  157. package/docs/index.md +15 -12
  158. package/docs/lifecycle.md +102 -55
  159. package/docs/long-running-agents.md +2 -2
  160. package/docs/mcp-servers.md +5 -1
  161. package/docs/resumable-streaming.md +1 -1
  162. package/docs/routing.md +105 -0
  163. package/docs/sessions.md +237 -871
  164. package/docs/streams.md +213 -0
  165. package/docs/sub-agents.md +184 -124
  166. package/docs/tasks.md +246 -0
  167. package/docs/voice.md +745 -0
  168. package/package.json +115 -13
  169. package/dist/capability-runner-CvHGZqUu.d.ts +0 -150
  170. package/dist/compaction-helpers-iiKMr2TQ.js +0 -340
  171. package/dist/compaction-helpers-iiKMr2TQ.js.map +0 -1
  172. package/dist/compaction-helpers-wUz6M3us.d.ts +0 -621
  173. package/dist/diagnostics-CaBjfz4J.js.map +0 -1
  174. package/dist/durable-object-lifecycle-D6nNQJJd.js +0 -862
  175. package/dist/durable-object-lifecycle-D6nNQJJd.js.map +0 -1
  176. package/dist/experimental/memory/session/index.d.ts +0 -671
  177. package/dist/experimental/memory/session/index.js +0 -2379
  178. package/dist/experimental/memory/session/index.js.map +0 -1
  179. package/dist/experimental/memory/utils/index.d.ts +0 -96
  180. package/dist/experimental/memory/utils/index.js +0 -79
  181. package/dist/experimental/memory/utils/index.js.map +0 -1
  182. package/dist/scheduler-CR9RHGos.js +0 -857
  183. package/dist/scheduler-CR9RHGos.js.map +0 -1
  184. package/dist/src-5W6JNKVb.js.map +0 -1
  185. package/dist/tool-output-truncation-CNnnGZQ3.js +0 -98
  186. 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.23.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",
54
+ "teleproto": "^1.228.5",
52
55
  "valibot": "1.4.1",
53
- "zod": "^4.4.3"
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,6 +195,11 @@
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
+ },
170
203
  "./schedule": {
171
204
  "types": "./dist/schedule.d.ts",
172
205
  "import": "./dist/schedule.js",
@@ -187,16 +220,6 @@
187
220
  "import": "./dist/workflows.js",
188
221
  "require": "./dist/workflows.js"
189
222
  },
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
223
  "./experimental/webmcp": {
201
224
  "types": "./dist/experimental/webmcp.d.ts",
202
225
  "import": "./dist/experimental/webmcp.js",
@@ -267,6 +290,81 @@
267
290
  "import": "./dist/browser/tanstack-ai.js",
268
291
  "require": "./dist/browser/tanstack-ai.js"
269
292
  },
293
+ "./voice": {
294
+ "types": "./dist/voice/index.d.ts",
295
+ "import": "./dist/voice/index.js",
296
+ "require": "./dist/voice/index.js"
297
+ },
298
+ "./voice/types": {
299
+ "types": "./dist/voice/types.d.ts",
300
+ "import": "./dist/voice/types.js",
301
+ "require": "./dist/voice/types.js"
302
+ },
303
+ "./voice/client": {
304
+ "types": "./dist/voice/client.d.ts",
305
+ "import": "./dist/voice/client.js",
306
+ "require": "./dist/voice/client.js"
307
+ },
308
+ "./voice/react": {
309
+ "types": "./dist/voice/react.d.ts",
310
+ "import": "./dist/voice/react.js",
311
+ "require": "./dist/voice/react.js"
312
+ },
313
+ "./voice/errors": {
314
+ "types": "./dist/voice/errors.d.ts",
315
+ "import": "./dist/voice/errors.js",
316
+ "require": "./dist/voice/errors.js"
317
+ },
318
+ "./voice/workers-ai": {
319
+ "types": "./dist/voice/workers-ai.d.ts",
320
+ "import": "./dist/voice/workers-ai.js",
321
+ "require": "./dist/voice/workers-ai.js"
322
+ },
323
+ "./voice/sfu": {
324
+ "types": "./dist/voice/sfu.d.ts",
325
+ "import": "./dist/voice/sfu.js",
326
+ "require": "./dist/voice/sfu.js"
327
+ },
328
+ "./voice/text": {
329
+ "types": "./dist/voice/text.d.ts",
330
+ "import": "./dist/voice/text.js",
331
+ "require": "./dist/voice/text.js"
332
+ },
333
+ "./channels": {
334
+ "types": "./dist/channels/index.d.ts",
335
+ "import": "./dist/channels/index.js",
336
+ "require": "./dist/channels/index.js"
337
+ },
338
+ "./channels/email": {
339
+ "types": "./dist/channels/email.d.ts",
340
+ "import": "./dist/channels/email.js",
341
+ "require": "./dist/channels/email.js"
342
+ },
343
+ "./channels/slack": {
344
+ "types": "./dist/channels/slack.d.ts",
345
+ "import": "./dist/channels/slack.js",
346
+ "require": "./dist/channels/slack.js"
347
+ },
348
+ "./channels/telegram": {
349
+ "types": "./dist/channels/telegram.d.ts",
350
+ "import": "./dist/channels/telegram.js",
351
+ "require": "./dist/channels/telegram.js"
352
+ },
353
+ "./channels/voice": {
354
+ "types": "./dist/channels/voice.d.ts",
355
+ "import": "./dist/channels/voice.js",
356
+ "require": "./dist/channels/voice.js"
357
+ },
358
+ "./channels/ai-sdk": {
359
+ "types": "./dist/channels/ai-sdk.d.ts",
360
+ "import": "./dist/channels/ai-sdk.js",
361
+ "require": "./dist/channels/ai-sdk.js"
362
+ },
363
+ "./channels/tanstack-ai": {
364
+ "types": "./dist/channels/tanstack-ai.d.ts",
365
+ "import": "./dist/channels/tanstack-ai.js",
366
+ "require": "./dist/channels/tanstack-ai.js"
367
+ },
270
368
  "./tsconfig": "./agents.tsconfig.json",
271
369
  "./vite": {
272
370
  "types": "./dist/vite.d.ts",
@@ -319,6 +417,10 @@
319
417
  "test": "vitest --run",
320
418
  "test:node": "vitest --project node",
321
419
  "test:react": "vitest --project react",
420
+ "test:voice:workers": "vitest --project voice-workers",
421
+ "test:voice:react": "vitest --project voice-react",
422
+ "test:channels": "vitest --project channels",
423
+ "test:channels:live": "vitest --run -c src/channels/vitest.live.config.ts",
322
424
  "test:browser": "vitest run --config src/browser-tests/vitest.config.ts",
323
425
  "test:workers": "vitest --project workers",
324
426
  "test:chat": "vitest --project chat",
@@ -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,340 +0,0 @@
1
- //#region src/experimental/memory/utils/tokens.ts
2
- /** Approximate characters per token for English text */
3
- const CHARS_PER_TOKEN = 4;
4
- /** Approximate token multiplier per whitespace-separated word */
5
- const WORDS_TOKEN_MULTIPLIER = 1.3;
6
- /** Approximate overhead tokens per message (role, framing) */
7
- const TOKENS_PER_MESSAGE = 4;
8
- /**
9
- * Estimate token count for a string using a hybrid heuristic.
10
- *
11
- * Takes the max of two estimates:
12
- * - Character-based: `length / 4` — better for dense content (JSON, code, URLs)
13
- * - Word-based: `words * 1.3` — better for natural language prose
14
- *
15
- * This is a heuristic. Do not use where exact counts are required.
16
- */
17
- function estimateStringTokens(text) {
18
- if (!text) return 0;
19
- const charEstimate = text.length / 4;
20
- const wordEstimate = text.split(/\s+/).filter(Boolean).length * WORDS_TOKEN_MULTIPLIER;
21
- return Math.ceil(Math.max(charEstimate, wordEstimate));
22
- }
23
- function estimateUnknownTokens(value) {
24
- if (value === null || value === void 0) return 0;
25
- if (typeof value === "string") return estimateStringTokens(value);
26
- try {
27
- return estimateStringTokens(JSON.stringify(value));
28
- } catch {
29
- return estimateStringTokens(String(value));
30
- }
31
- }
32
- /**
33
- * Estimate total token count for an array of UIMessages.
34
- *
35
- * Walks each message's parts (text, reasoning, tool invocations, tool results)
36
- * and applies per-message overhead.
37
- *
38
- * This is a heuristic. Do not use where exact counts are required.
39
- */
40
- function estimateMessageTokens(messages) {
41
- let tokens = 0;
42
- for (const msg of messages) {
43
- tokens += 4;
44
- for (const part of msg.parts) if (part.type === "text" || part.type === "reasoning") tokens += estimateUnknownTokens(part.text ?? part.reasoning);
45
- else if (part.type.startsWith("tool-") || part.type === "dynamic-tool") {
46
- tokens += estimateUnknownTokens(part.input);
47
- tokens += estimateUnknownTokens(part.output ?? part.result);
48
- } else if (part.text !== void 0) tokens += estimateUnknownTokens(part.text);
49
- else if (part.result !== void 0) tokens += estimateUnknownTokens(part.result);
50
- }
51
- return tokens;
52
- }
53
- //#endregion
54
- //#region src/experimental/memory/utils/compaction-helpers.ts
55
- /** Prefix for all compaction messages (overlays and summaries) */
56
- const COMPACTION_PREFIX = "compaction_";
57
- /** Check if a message is a compaction message */
58
- function isCompactionMessage(msg) {
59
- return msg.id.startsWith(COMPACTION_PREFIX);
60
- }
61
- /**
62
- * Check if a message contains tool invocations.
63
- */
64
- function hasToolCalls(msg) {
65
- return msg.parts.some((p) => p.type.startsWith("tool-") || p.type === "dynamic-tool");
66
- }
67
- /**
68
- * Get tool call IDs from a message's parts.
69
- */
70
- function getToolCallIds(msg) {
71
- const ids = /* @__PURE__ */ new Set();
72
- for (const part of msg.parts) if ((part.type.startsWith("tool-") || part.type === "dynamic-tool") && "toolCallId" in part) ids.add(part.toolCallId);
73
- return ids;
74
- }
75
- /**
76
- * Check if a message is a tool result referencing a specific call ID.
77
- */
78
- function isToolResultFor(msg, callIds) {
79
- return msg.parts.some((p) => (p.type.startsWith("tool-") || p.type === "dynamic-tool") && "toolCallId" in p && callIds.has(p.toolCallId));
80
- }
81
- /**
82
- * Align a boundary index forward to avoid splitting tool call/result groups.
83
- * If the boundary falls between an assistant message with tool calls and its
84
- * tool results, move it forward past the results.
85
- */
86
- function alignBoundaryForward(messages, idx) {
87
- if (idx <= 0 || idx >= messages.length) return idx;
88
- const prev = messages[idx - 1];
89
- if (prev.role === "assistant" && hasToolCalls(prev)) {
90
- const callIds = getToolCallIds(prev);
91
- while (idx < messages.length && isToolResultFor(messages[idx], callIds)) idx++;
92
- }
93
- return idx;
94
- }
95
- /**
96
- * Align a boundary index backward to avoid splitting tool call/result groups.
97
- * If the boundary falls in the middle of tool results, move it backward to
98
- * include the assistant message that made the calls.
99
- */
100
- function alignBoundaryBackward(messages, idx) {
101
- if (idx <= 0 || idx >= messages.length) return idx;
102
- while (idx > 0) {
103
- const msg = messages[idx];
104
- if (msg.role === "assistant" && hasToolCalls(msg)) break;
105
- const prev = messages[idx - 1];
106
- if (prev.role === "assistant" && hasToolCalls(prev)) {
107
- if (isToolResultFor(msg, getToolCallIds(prev))) {
108
- idx--;
109
- continue;
110
- }
111
- }
112
- break;
113
- }
114
- return idx;
115
- }
116
- /**
117
- * Find the compression end boundary using a token budget for the tail.
118
- * Walks backward from the end, accumulating tokens until budget is reached.
119
- * Returns the index where compression should stop (everything from this
120
- * index onward is protected).
121
- *
122
- * @param messages All messages
123
- * @param headEnd Index where the protected head ends (compression starts here)
124
- * @param tailTokenBudget Maximum tokens to keep in the tail
125
- * @param minTailMessages Minimum messages to protect in the tail (fallback)
126
- */
127
- function findTailCutByTokens(messages, headEnd, tailTokenBudget = 2e4, minTailMessages = 2) {
128
- const n = messages.length;
129
- let accumulated = 0;
130
- let tokenCut = n;
131
- for (let i = n - 1; i >= headEnd; i--) {
132
- const msgTokens = estimateMessageTokens([messages[i]]);
133
- if (accumulated + msgTokens > tailTokenBudget && tokenCut < n) break;
134
- accumulated += msgTokens;
135
- tokenCut = i;
136
- }
137
- const minCut = n - minTailMessages;
138
- return alignBoundaryBackward(messages, minCut >= headEnd ? Math.min(tokenCut, minCut) : tokenCut);
139
- }
140
- async function findTailCutByTokensWithCounter(messages, headEnd, tokenCounter, tailTokenBudget = 2e4, minTailMessages = 2) {
141
- const n = messages.length;
142
- let accumulated = 0;
143
- let tokenCut = n;
144
- for (let i = n - 1; i >= headEnd; i--) {
145
- const msgTokens = await tokenCounter([messages[i]]);
146
- if (accumulated + msgTokens > tailTokenBudget && tokenCut < n) break;
147
- accumulated += msgTokens;
148
- tokenCut = i;
149
- }
150
- const minCut = n - minTailMessages;
151
- return alignBoundaryBackward(messages, minCut >= headEnd ? Math.min(tokenCut, minCut) : tokenCut);
152
- }
153
- /**
154
- * Fix orphaned tool call/result pairs after compaction.
155
- *
156
- * Two failure modes:
157
- * 1. Tool result references a call_id whose assistant tool_call was removed
158
- * → Remove the orphaned result
159
- * 2. Assistant has tool_calls whose results were dropped
160
- * → Add stub results so the API doesn't error
161
- *
162
- * @param messages Messages after compaction
163
- * @returns Sanitized messages with no orphaned pairs
164
- */
165
- function sanitizeToolPairs(messages) {
166
- const survivingCallIds = /* @__PURE__ */ new Set();
167
- for (const msg of messages) if (msg.role === "assistant") for (const id of getToolCallIds(msg)) survivingCallIds.add(id);
168
- const resultCallIds = /* @__PURE__ */ new Set();
169
- for (const msg of messages) for (const part of msg.parts) if ((part.type.startsWith("tool-") || part.type === "dynamic-tool") && "toolCallId" in part && "output" in part) resultCallIds.add(part.toolCallId);
170
- const orphanedResults = /* @__PURE__ */ new Set();
171
- for (const id of resultCallIds) if (!survivingCallIds.has(id)) orphanedResults.add(id);
172
- let result = messages;
173
- if (orphanedResults.size > 0) result = result.map((msg) => {
174
- const filteredParts = msg.parts.filter((part) => {
175
- if ((part.type.startsWith("tool-") || part.type === "dynamic-tool") && "toolCallId" in part && "output" in part) return !orphanedResults.has(part.toolCallId);
176
- return true;
177
- });
178
- if (filteredParts.length !== msg.parts.length) return {
179
- ...msg,
180
- parts: filteredParts
181
- };
182
- return msg;
183
- });
184
- const missingResults = /* @__PURE__ */ new Set();
185
- for (const id of survivingCallIds) if (!resultCallIds.has(id) && !orphanedResults.has(id)) missingResults.add(id);
186
- if (missingResults.size > 0) {
187
- const patched = [];
188
- for (const msg of result) {
189
- patched.push(msg);
190
- if (msg.role === "assistant") {
191
- for (const id of getToolCallIds(msg)) if (missingResults.has(id)) {
192
- const callPart = msg.parts.find((p) => "toolCallId" in p && p.toolCallId === id);
193
- patched.push({
194
- id: `stub-${id}`,
195
- role: "assistant",
196
- parts: [{
197
- type: "tool-result",
198
- toolCallId: id,
199
- toolName: callPart?.toolName ?? "unknown",
200
- result: "[Result from earlier conversation — see context summary above]"
201
- }],
202
- createdAt: /* @__PURE__ */ new Date()
203
- });
204
- }
205
- }
206
- }
207
- result = patched;
208
- }
209
- return result.filter((msg) => msg.parts.length > 0);
210
- }
211
- /**
212
- * Compute a summary token budget based on the content being compressed.
213
- * 20% of the compressed content, clamped to 2K-8K tokens.
214
- */
215
- function computeSummaryBudget(messages) {
216
- const contentTokens = estimateMessageTokens(messages);
217
- const budget = Math.floor(contentTokens * .2);
218
- return Math.max(100, budget);
219
- }
220
- /**
221
- * Build a prompt for LLM summarization of compressed messages.
222
- *
223
- * @param messages Messages to summarize
224
- * @param previousSummary Previous summary for iterative updates (or null for first compaction)
225
- * @param budget Target token count for the summary
226
- */
227
- function buildSummaryPrompt(messages, previousSummary, budget) {
228
- const content = messages.map((msg) => {
229
- const textParts = msg.parts.filter((p) => p.type === "text").map((p) => p.text).join("\n");
230
- const toolParts = msg.parts.filter((p) => p.type.startsWith("tool-") || p.type === "dynamic-tool").map((p) => {
231
- const tp = p;
232
- const parts = [`[Tool: ${tp.toolName ?? "unknown"}]`];
233
- if (tp.input) parts.push(`Input: ${JSON.stringify(tp.input).slice(0, 500)}`);
234
- if (tp.output) parts.push(`Output: ${String(tp.output).slice(0, 500)}`);
235
- return parts.join("\n");
236
- }).join("\n");
237
- return `[${msg.role}]\n${textParts}${toolParts ? "\n" + toolParts : ""}`;
238
- }).join("\n\n---\n\n");
239
- if (previousSummary) return `You are updating a conversation summary. A previous summary exists below. New conversation turns have occurred since then and need to be incorporated.
240
-
241
- PREVIOUS SUMMARY:
242
- ${previousSummary}
243
-
244
- NEW TURNS TO INCORPORATE:
245
- ${content}
246
-
247
- Update the summary. PRESERVE existing information that is still relevant. ADD new information. Remove information only if it is clearly obsolete.
248
-
249
- ## Topic
250
- [What the conversation is about]
251
-
252
- ## Key Points
253
- [Important information, decisions, and conclusions from the conversation]
254
-
255
- ## Current State
256
- [Where things stand now — what has been done, what is in progress]
257
-
258
- ## Open Items
259
- [Unresolved questions, pending tasks, or next steps discussed]
260
-
261
- Target ~${budget} tokens. Be factual — only include information that was explicitly discussed in the conversation. Do NOT invent file paths, commands, or details that were not mentioned. Write only the summary body.`;
262
- return `Create a concise summary of this conversation that preserves the important information for future context.
263
-
264
- CONVERSATION TO SUMMARIZE:
265
- ${content}
266
-
267
- Use this structure:
268
-
269
- ## Topic
270
- [What the conversation is about]
271
-
272
- ## Key Points
273
- [Important information, decisions, and conclusions from the conversation]
274
-
275
- ## Current State
276
- [Where things stand now — what has been done, what is in progress]
277
-
278
- ## Open Items
279
- [Unresolved questions, pending tasks, or next steps discussed]
280
-
281
- Target ~${budget} tokens. Be factual — only include information that was explicitly discussed in the conversation. Do NOT invent file paths, commands, or details that were not mentioned. Write only the summary body.`;
282
- }
283
- /**
284
- * Reference compaction implementation.
285
- *
286
- * Implements the full hermes-style compaction algorithm:
287
- * 1. Protect head messages (first N)
288
- * 2. Protect tail by token budget (walk backward)
289
- * 3. Align boundaries to tool call groups
290
- * 4. Summarize middle section with LLM (structured format)
291
- * 5. Sanitize orphaned tool pairs
292
- * 6. Iterative summary updates on subsequent compactions
293
- *
294
- * @example
295
- * ```typescript
296
- * import { createCompactFunction } from "agents/experimental/memory/utils";
297
- *
298
- * const session = new Session(provider, {
299
- * compaction: {
300
- * tokenThreshold: 100000,
301
- * fn: createCompactFunction({
302
- * summarize: (prompt) => generateText({ model, prompt }).then(r => r.text)
303
- * })
304
- * }
305
- * });
306
- * ```
307
- */
308
- function createCompactFunction(opts) {
309
- const protectHead = opts.protectHead ?? 3;
310
- const tailTokenBudget = opts.tailTokenBudget ?? 2e4;
311
- const minTailMessages = opts.minTailMessages ?? 2;
312
- return async (messages, context) => {
313
- if (messages.length <= protectHead + minTailMessages) return null;
314
- const sessionCounter = context?.tokenCounter;
315
- const tailCounter = opts.tokenCounter ?? (sessionCounter ? (msgs) => sessionCounter({
316
- messages: msgs,
317
- systemPrompt: "",
318
- contextBlocks: []
319
- }) : void 0);
320
- let compressStart = protectHead;
321
- compressStart = alignBoundaryForward(messages, compressStart);
322
- let compressEnd = tailCounter ? await findTailCutByTokensWithCounter(messages, compressStart, tailCounter, tailTokenBudget, minTailMessages) : findTailCutByTokens(messages, compressStart, tailTokenBudget, minTailMessages);
323
- if (compressEnd <= compressStart) return null;
324
- const middleMessages = messages.slice(compressStart, compressEnd).filter((m) => !isCompactionMessage(m));
325
- if (middleMessages.length === 0) return null;
326
- const existingCompaction = messages.find(isCompactionMessage);
327
- const prompt = buildSummaryPrompt(middleMessages, existingCompaction ? existingCompaction.parts.filter((p) => p.type === "text").map((p) => p.text).join("\n") : null, computeSummaryBudget(middleMessages));
328
- const summary = await opts.summarize(prompt);
329
- if (!summary.trim()) return null;
330
- return {
331
- fromMessageId: middleMessages[0].id,
332
- toMessageId: middleMessages[middleMessages.length - 1].id,
333
- summary
334
- };
335
- };
336
- }
337
- //#endregion
338
- export { computeSummaryBudget as a, isCompactionMessage as c, TOKENS_PER_MESSAGE as d, WORDS_TOKEN_MULTIPLIER as f, buildSummaryPrompt as i, sanitizeToolPairs as l, estimateStringTokens as m, alignBoundaryBackward as n, createCompactFunction as o, estimateMessageTokens as p, alignBoundaryForward as r, findTailCutByTokens as s, COMPACTION_PREFIX as t, CHARS_PER_TOKEN as u };
339
-
340
- //# sourceMappingURL=compaction-helpers-iiKMr2TQ.js.map