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
@@ -0,0 +1,213 @@
1
+ # Streams
2
+
3
+ > **Experimental.** Everything exported from `agents/streams` may change
4
+ > between releases while the durable output surface stabilizes.
5
+
6
+ `agents/streams` adds durable incremental output to a [Lifecycle
7
+ Object](./lifecycle.md): an ordered, durable chunk log per stream with a
8
+ monotonic cursor, replay-then-tail reads, and terminal status. A consumer
9
+ that reconnects replays from its cursor; a producer that dies mid-stream
10
+ leaves exactly the chunks it durably appended, ready for a replayed
11
+ producer to resume from. The capability needs no alarm, so it also works
12
+ on facets.
13
+
14
+ ## Install and use
15
+
16
+ ```ts
17
+ import { DurableObject } from "cloudflare:workers";
18
+ import { Lifecycle } from "agents/lifecycle";
19
+ import { Streams } from "agents/streams";
20
+
21
+ export class ReportObject extends DurableObject<Env> {
22
+ readonly streams = new Streams();
23
+ readonly lifecycle = Lifecycle.install(this).use(this.streams);
24
+ }
25
+ ```
26
+
27
+ On an `Agent`, install it onto the composition root in the constructor —
28
+ the pattern for adding any extra capability to an Agent:
29
+
30
+ ```ts
31
+ export class ReportAgent extends Agent<Env> {
32
+ readonly streams = new Streams();
33
+
34
+ constructor(ctx: AgentContext, env: Env) {
35
+ super(ctx, env);
36
+ this.lifecycle.use(this.streams);
37
+ }
38
+ }
39
+ ```
40
+
41
+ ## Producing
42
+
43
+ ```ts
44
+ const stream = await this.streams.open("reply:123", { metadata });
45
+ stream.append(chunk); // synchronous durable write; wakes live readers
46
+ stream.close(); // or stream.error(reason)
47
+ ```
48
+
49
+ Chunks are JSON values (1 MiB default ceiling, configurable via
50
+ `maxChunkBytes`); each append assigns the next monotonic sequence number —
51
+ the stream's **cursor**. `open()` is idempotent on the id: reopening a live
52
+ stream returns a writer at its cursor, reopening a settled stream throws
53
+ `StreamClosedError`, and settling twice is a no-op so recovery callers stay
54
+ idempotent.
55
+
56
+ ## Consuming
57
+
58
+ ```ts
59
+ for await (const chunk of this.streams.read("reply:123", { from, signal })) {
60
+ // replays persisted chunks from `from`, then tails live appends,
61
+ // ends when the stream settles
62
+ }
63
+
64
+ const status = await this.streams.status("reply:123");
65
+ // { state: "streaming" | "completed" | "errored", cursor, ... } | null
66
+ ```
67
+
68
+ Reads are independent of producer liveness. `list()` filters by state and
69
+ by `tag`, and `delete()` removes a settled stream and its chunk log (a live
70
+ stream must be settled first).
71
+
72
+ **Tags** are the lookup side of the id: `open(id, { tag })` stamps a stream
73
+ with an indexed application key — a request id, a session — that is
74
+ deliberately _not_ unique. An operation that produces successive streams (a
75
+ retried turn, a regenerated reply) tags each one, and
76
+ `list({ tag, limit: 1 })` finds the latest (results are newest-first). The
77
+ tag is fixed at creation; reopening a live stream with a different tag
78
+ throws. Use the id alone until one operation can own more than one stream —
79
+ that's the moment tags exist for.
80
+
81
+ `readBatches` also accepts `onUpToDate`, invoked once when the reader first
82
+ reaches the durable tail. Caught-up is distinct from ended: a live stream is
83
+ up to date while tailing — use it to flush replayed UI or flip on a "live"
84
+ indicator.
85
+
86
+ When the consumer pays per write — an SSE flush, an RPC hop, a history
87
+ append — read in batches instead of chunk by chunk:
88
+
89
+ ```ts
90
+ for await (const batch of this.streams.readBatches("reply:123", {
91
+ from,
92
+ batchSize: 50 // per-array ceiling during replay; default 100
93
+ })) {
94
+ flush(batch); // StreamChunk[] — one write per backlog, not per chunk
95
+ }
96
+ ```
97
+
98
+ `readBatches()` has the same lifecycle as `read()` (replay, then tail, end
99
+ on settlement); the difference is granularity: replay yields up to
100
+ `batchSize` chunks per array, and a live tail yields everything that
101
+ accumulated since the last wakeup as one array.
102
+
103
+ ## Composing with Tasks
104
+
105
+ The contract [Tasks](./tasks.md) replay was designed around: a task step
106
+ appends to a stream it does not own, and because the producer starts its
107
+ loop at the stream's own durable cursor, a replay after interruption is a
108
+ resume — the stream is the recovery evidence.
109
+
110
+ ```ts
111
+ readonly tasks = new Tasks({
112
+ definitions: {
113
+ "generate@v1": async (input: GenerateInput, step: TaskStep) => {
114
+ return step.do("stream", async () => {
115
+ const stream = await this.streams.open(input.streamId);
116
+ // Resuming producers start from the stream's own cursor, so a
117
+ // replay after interruption never duplicates a chunk.
118
+ for (let i = stream.cursor; i < input.total; i++) {
119
+ stream.append(await this.produce(i));
120
+ }
121
+ stream.close();
122
+ });
123
+ }
124
+ }
125
+ });
126
+ ```
127
+
128
+ Neither capability imports the other. The composition survives a real
129
+ process kill: the chunks appended before death are exactly what `status()`
130
+ reports afterward (proven by the SIGKILL e2e suite).
131
+
132
+ ## Serving
133
+
134
+ For SSE, one call serves the whole lifecycle:
135
+
136
+ ```ts
137
+ import { sseResponse } from "agents/streams";
138
+
139
+ async onRequest(request: Request) {
140
+ return sseResponse(this.streams, "reply:123", { request });
141
+ }
142
+ ```
143
+
144
+ Each chunk's sequence number rides the SSE `id:` field, so resume is native
145
+ to the protocol: a reconnecting `EventSource` sends `Last-Event-ID`
146
+ automatically and the helper continues from the next chunk — cursor
147
+ persistence with zero client code (`?from=` works too). The response
148
+ replays, emits an `up-to-date` control event at the tail, tails live
149
+ appends (with periodic heartbeat comments to survive idle proxies), and
150
+ finishes with `done` or `error` (carrying the recorded reason). The
151
+ request's signal aborts the tail when the client disconnects.
152
+ `examples/next/streams` is the end-to-end demo. For other transports,
153
+ `read()`/`readBatches()` remain the raw async iterables to pipe yourself.
154
+
155
+ ## Storage: blocks, and the cutover to a message
156
+
157
+ Chunks are stored as **rollover blocks**: one row per stream holds chunks
158
+ until it reaches 256 KB, then the next append opens a new row. An append
159
+ is one billed row either way (an UPDATE that grows the block, or the INSERT
160
+ of the next one), the same as a row-per-chunk log, but a stream of
161
+ thousands of chunks is a handful of rows, so deleting it is a handful of
162
+ writes instead of thousands. Replay parses one block at a time.
163
+
164
+ A stream is temporary: once its content has become something else (a
165
+ session message, a report), its rows are dead weight. The **cutover** ends
166
+ the stream, runs your own synchronous writes, and deletes its rows in one
167
+ SQLite transaction:
168
+
169
+ ```ts
170
+ stream.close({
171
+ commit: () => sessionSync.upsert(message), // synchronous writes only
172
+ discard: true // delete the stream's rows in the same transaction
173
+ });
174
+ ```
175
+
176
+ Either the message exists and the stream is gone, or `commit` threw, the
177
+ settle rolled back and the stream is still live. Nothing is left for a
178
+ retention sweep. `error(reason, { commit, discard })` is the same for a
179
+ failed producer. `commit` must not await; a Session handle's
180
+ `__DO_NOT_USE_WILL_BREAK__sync().upsert()` is the matching synchronous
181
+ message write, and returns a `notify()` to dispatch the change feed after
182
+ the transaction commits.
183
+
184
+ Measured on a real Durable Object (400-chunk chat turn, 10 chunks per
185
+ write): the old log paid 42 rows to write and another 42 to sweep; blocks
186
+ pay 42 to write and 3 to cut over.
187
+
188
+ ## Chat runs on this
189
+
190
+ `AIChatAgent` and `Think` store their in-flight turn output here:
191
+ `ResumableStream` (from `agents/chat`) is a thin adapter over Streams that
192
+ packs ~10 wire chunks into one stored segment for write economy, and ends
193
+ every turn with the cutover: the assistant message, the stream's
194
+ settlement and the deletion of its rows commit in one transaction. Nothing
195
+ is swept on an alarm any more. A stream a crash left behind is either
196
+ still `streaming` (recovery rebuilds the message from it) or reclaimed by
197
+ the next stream start, together with in-flight rows abandoned for over an
198
+ hour. Existing `cf_ai_chat_stream_*` tables migrate onto the capability
199
+ automatically. The packing pattern is worth copying for any
200
+ high-frequency producer: buffer what you already hold synchronously, append
201
+ one packed chunk, and unpack on read — durability is unchanged (nothing is
202
+ held across an await at settlement) and rows written drop by ~an order of
203
+ magnitude versus per-token appends.
204
+
205
+ ## Current limits
206
+
207
+ Live fanout is in-isolate (sufficient: a Durable Object executes in one
208
+ isolate at a time; reconnecting readers replay from their cursor). Retention
209
+ is explicit: `delete()`, or the cutover's `discard`; age-based sweeping in
210
+ the capability itself, producer-generation fencing on `open()`,
211
+ and transport helpers extracted from chat's resume protocol are future work.
212
+ The design record is
213
+ [`design/rfc-streams.md`](https://github.com/cloudflare/agents/blob/main/design/rfc-streams.md).