experimental-a2 0.20.0 → 0.21.1

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 (286) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +1 -1
  3. package/dist/{actor-C7b-1arn.d.ts → actor-HnGmrOZZ.d.ts} +5 -5
  4. package/dist/{actor-C7b-1arn.d.ts.map → actor-HnGmrOZZ.d.ts.map} +1 -1
  5. package/dist/actor-client.d.ts +1 -1
  6. package/dist/actor-client.js +2 -2
  7. package/dist/actor-react.d.ts +3 -3
  8. package/dist/actor-react.js +5 -5
  9. package/dist/{actor-shared-t7w8xIKP.js → actor-shared-DFET5q16.js} +3 -3
  10. package/dist/{actor-shared-t7w8xIKP.js.map → actor-shared-DFET5q16.js.map} +1 -1
  11. package/dist/actor.d.ts +1 -1
  12. package/dist/actor.js +54 -43
  13. package/dist/actor.js.map +1 -1
  14. package/dist/{ai-Cz3hqVhk.d.ts → ai-CvEnqVfo.d.ts} +8 -8
  15. package/dist/{ai-Cz3hqVhk.d.ts.map → ai-CvEnqVfo.d.ts.map} +1 -1
  16. package/dist/{ai-mMiWul1T.js → ai-CzE672Q3.js} +9 -9
  17. package/dist/ai-CzE672Q3.js.map +1 -0
  18. package/dist/ai-client.d.ts +2 -2
  19. package/dist/ai-client.js +2 -2
  20. package/dist/ai-fx.d.ts +1 -1
  21. package/dist/ai-fx.js +3 -6
  22. package/dist/ai-fx.js.map +1 -1
  23. package/dist/{ai-harness-CV6rXbB3.d.ts → ai-harness-Bfk-Lycn.d.ts} +2 -2
  24. package/dist/{ai-harness-CV6rXbB3.d.ts.map → ai-harness-Bfk-Lycn.d.ts.map} +1 -1
  25. package/dist/{ai-harness-Clbg5ei7.js → ai-harness-dQeJaR1t.js} +7 -3
  26. package/dist/ai-harness-dQeJaR1t.js.map +1 -0
  27. package/dist/ai-pi.d.ts +1 -1
  28. package/dist/ai-pi.js +3 -3
  29. package/dist/ai-pi.js.map +1 -1
  30. package/dist/ai-react.d.ts +5 -5
  31. package/dist/ai-react.js +2 -2
  32. package/dist/ai-server.d.ts +14 -17
  33. package/dist/ai-server.d.ts.map +1 -1
  34. package/dist/ai-server.js +80 -73
  35. package/dist/ai-server.js.map +1 -1
  36. package/dist/ai.d.ts +2 -2
  37. package/dist/ai.js +2 -2
  38. package/dist/{client-BhHLoNKF.js → client-9IeTsiAs.js} +5 -5
  39. package/dist/{client-BhHLoNKF.js.map → client-9IeTsiAs.js.map} +1 -1
  40. package/dist/{client-h_DKFAjj.d.ts → client-CUMbS_38.d.ts} +3 -3
  41. package/dist/{client-h_DKFAjj.d.ts.map → client-CUMbS_38.d.ts.map} +1 -1
  42. package/dist/client.d.ts +3 -3
  43. package/dist/client.js +1 -1
  44. package/dist/{contract-BYKASlCV.js → contract-CWukt01d.js} +2 -2
  45. package/dist/contract-CWukt01d.js.map +1 -0
  46. package/dist/index.d.ts +5 -5
  47. package/dist/index.js +3 -3
  48. package/dist/{initial-snapshot-Bx-c0pDP.d.ts → initial-snapshot-D3Lve43o.d.ts} +4 -4
  49. package/dist/initial-snapshot-D3Lve43o.d.ts.map +1 -0
  50. package/dist/{internal-CscSY7K_.js → internal-Bc4PvfHk.js} +10 -3
  51. package/dist/internal-Bc4PvfHk.js.map +1 -0
  52. package/dist/otel.d.ts +1 -1
  53. package/dist/otel.js +1 -1
  54. package/dist/otel.js.map +1 -1
  55. package/dist/{react-BBXgHWFc.d.ts → react-BoHvC3v9.d.ts} +4 -4
  56. package/dist/{react-BBXgHWFc.d.ts.map → react-BoHvC3v9.d.ts.map} +1 -1
  57. package/dist/react.d.ts +1 -1
  58. package/dist/react.js +1 -1
  59. package/dist/{reducer-CqA59Q6U.d.ts → reducer-CYPHsSmd.d.ts} +2 -2
  60. package/dist/{reducer-CqA59Q6U.d.ts.map → reducer-CYPHsSmd.d.ts.map} +1 -1
  61. package/dist/{reducer-BAXc8JyF.js → reducer-CjmvZSAb.js} +2 -2
  62. package/dist/{reducer-BAXc8JyF.js.map → reducer-CjmvZSAb.js.map} +1 -1
  63. package/dist/runtime-consumer-BWmht60z.js +12 -0
  64. package/dist/runtime-consumer-BWmht60z.js.map +1 -0
  65. package/dist/scheduler-qstash.d.ts +2 -2
  66. package/dist/scheduler-qstash.js +3 -3
  67. package/dist/scheduler-task-X1SToDjP.js.map +1 -1
  68. package/dist/scheduler-vercel.d.ts +2 -2
  69. package/dist/scheduler-vercel.js +3 -3
  70. package/dist/scheduler-vercel.js.map +1 -1
  71. package/dist/{server-DYAATFuT.d.ts → server-BshFZ0eL.d.ts} +108 -41
  72. package/dist/server-BshFZ0eL.d.ts.map +1 -0
  73. package/dist/{server-qyb5aJJG.js → server-DvIB8kj5.js} +387 -113
  74. package/dist/server-DvIB8kj5.js.map +1 -0
  75. package/dist/server.browser.js +1 -1
  76. package/dist/server.browser.js.map +1 -1
  77. package/dist/server.d.ts +4 -4
  78. package/dist/server.js +2 -2
  79. package/dist/{session-clear-C-QwTXV1.d.ts → session-clear-Bk_29eEw.d.ts} +2 -2
  80. package/dist/session-clear-Bk_29eEw.d.ts.map +1 -0
  81. package/dist/{session-clear-DGI4jTQ5.js → session-clear-wHd5GCpZ.js} +5 -4
  82. package/dist/session-clear-wHd5GCpZ.js.map +1 -0
  83. package/dist/store-N8PXxDAS.js.map +1 -1
  84. package/dist/store-Z2qjw50n.d.ts +523 -0
  85. package/dist/store-Z2qjw50n.d.ts.map +1 -0
  86. package/dist/store-codec-DwrWlgQx.js +65 -0
  87. package/dist/store-codec-DwrWlgQx.js.map +1 -0
  88. package/dist/store-memory.d.ts +1 -1
  89. package/dist/store-memory.d.ts.map +1 -1
  90. package/dist/store-memory.js +393 -210
  91. package/dist/store-memory.js.map +1 -1
  92. package/dist/{store-polling-7WJV0YWP.js → store-polling-DYNyxCev.js} +2 -2
  93. package/dist/{store-polling-7WJV0YWP.js.map → store-polling-DYNyxCev.js.map} +1 -1
  94. package/dist/store-postgres.d.ts +1 -1
  95. package/dist/store-postgres.d.ts.map +1 -1
  96. package/dist/store-postgres.js +1586 -566
  97. package/dist/store-postgres.js.map +1 -1
  98. package/dist/{store-presence-polling-B1ixeqIS.js → store-presence-polling-CzQ0wdtM.js} +3 -3
  99. package/dist/{store-presence-polling-B1ixeqIS.js.map → store-presence-polling-CzQ0wdtM.js.map} +1 -1
  100. package/dist/store-redis-http.d.ts +1 -1
  101. package/dist/store-redis-http.js +4 -4
  102. package/dist/store-redis-notify-IiVdlYHc.js +2919 -0
  103. package/dist/store-redis-notify-IiVdlYHc.js.map +1 -0
  104. package/dist/store-redis.d.ts +1 -1
  105. package/dist/store-redis.js +2 -2
  106. package/dist/store-sqlite.d.ts +1 -1
  107. package/dist/store-sqlite.d.ts.map +1 -1
  108. package/dist/store-sqlite.js +517 -287
  109. package/dist/store-sqlite.js.map +1 -1
  110. package/dist/{telemetry-Cyfqo6Qt.d.ts → telemetry-CWwsh-Gx.d.ts} +3 -3
  111. package/dist/telemetry-CWwsh-Gx.d.ts.map +1 -0
  112. package/dist/{wire-BKxH1vbP.js → wire-CZGqNZRx.js} +5 -4
  113. package/dist/wire-CZGqNZRx.js.map +1 -0
  114. package/docs/01-quickstart.mdx +21 -15
  115. package/docs/02-examples.mdx +1 -1
  116. package/docs/actors/01-introduction.mdx +8 -0
  117. package/docs/actors/02-concurrency.mdx +1 -1
  118. package/docs/agents/01-introduction.mdx +1 -1
  119. package/docs/agents/02-tools.mdx +12 -11
  120. package/docs/agents/03-conversations.mdx +30 -20
  121. package/docs/agents/04-harnesses.mdx +7 -3
  122. package/docs/client/03-presence.mdx +18 -14
  123. package/docs/contract/01-events.mdx +2 -2
  124. package/docs/contract/02-state.mdx +18 -14
  125. package/docs/contract/03-sessions.mdx +32 -25
  126. package/docs/index.mdx +29 -24
  127. package/docs/reference/01-core.mdx +4 -4
  128. package/docs/reference/02-server.mdx +245 -190
  129. package/docs/reference/04-ai.mdx +20 -19
  130. package/docs/reference/05-telemetry.mdx +27 -13
  131. package/docs/reference/06-errors.mdx +24 -18
  132. package/docs/reference/meta.ts +1 -1
  133. package/docs/schedulers/01-overview.mdx +8 -8
  134. package/docs/schedulers/02-vercel-queues.mdx +2 -2
  135. package/docs/schedulers/03-qstash.mdx +4 -4
  136. package/docs/server/01-consumers.mdx +415 -0
  137. package/docs/server/02-timers.mdx +31 -21
  138. package/docs/server/03-cancellation.mdx +52 -44
  139. package/docs/server/04-routes.mdx +4 -1
  140. package/docs/server/05-sql-projections.mdx +391 -0
  141. package/docs/server/06-guarantees.mdx +55 -48
  142. package/docs/stores/01-overview.mdx +3 -3
  143. package/docs/stores/02-redis.mdx +11 -3
  144. package/docs/stores/03-redis-http.mdx +2 -2
  145. package/docs/stores/04-postgres.mdx +65 -14
  146. package/docs/stores/05-sqlite.mdx +5 -3
  147. package/docs/upgrades/01-overview.mdx +30 -0
  148. package/docs/upgrades/79-0-21.mdx +165 -0
  149. package/docs/upgrades/80-0-20.mdx +43 -0
  150. package/docs/upgrades/81-0-19.mdx +33 -0
  151. package/docs/upgrades/82-0-18.mdx +33 -0
  152. package/docs/upgrades/83-0-17.mdx +69 -0
  153. package/docs/upgrades/meta.ts +3 -0
  154. package/examples/playground/DEPLOY.md +39 -7
  155. package/examples/playground/app/a0/chat.test.tsx +2 -2
  156. package/examples/playground/app/a0/sandbox-log.ts +17 -15
  157. package/examples/playground/app/a0/server.ts +4 -4
  158. package/examples/playground/app/a2slack/a2slack.css +1067 -0
  159. package/examples/playground/app/a2slack/c/[channel]/page.tsx +20 -0
  160. package/examples/playground/app/a2slack/consumers/agent.ts +63 -0
  161. package/examples/playground/app/a2slack/consumers/feed.ts +164 -0
  162. package/examples/playground/app/a2slack/consumers/notify.ts +116 -0
  163. package/examples/playground/app/a2slack/consumers/search.ts +37 -0
  164. package/examples/playground/app/a2slack/consumers/triage.ts +31 -0
  165. package/examples/playground/app/a2slack/consumers/welcome.ts +25 -0
  166. package/examples/playground/app/a2slack/db/a2.ts +206 -0
  167. package/examples/playground/app/a2slack/db/index.ts +73 -0
  168. package/examples/playground/app/a2slack/db/migrations/0000_extensions.sql +4 -0
  169. package/examples/playground/app/a2slack/db/migrations/0001_workspace.sql +74 -0
  170. package/examples/playground/app/a2slack/db/migrations/0002_a2.sql +215 -0
  171. package/examples/playground/app/a2slack/db/migrations/0003_a2_batch.sql +67 -0
  172. package/examples/playground/app/a2slack/db/migrations/meta/0000_snapshot.json +18 -0
  173. package/examples/playground/app/a2slack/db/migrations/meta/0001_snapshot.json +500 -0
  174. package/examples/playground/app/a2slack/db/migrations/meta/0002_snapshot.json +1159 -0
  175. package/examples/playground/app/a2slack/db/migrations/meta/0003_snapshot.json +1159 -0
  176. package/examples/playground/app/a2slack/db/migrations/meta/_journal.json +34 -0
  177. package/examples/playground/app/a2slack/db/queries.ts +263 -0
  178. package/examples/playground/app/a2slack/db/schema.ts +145 -0
  179. package/examples/playground/app/a2slack/drills/a2slack.drill.ts +708 -0
  180. package/examples/playground/app/a2slack/drills/harness.ts +244 -0
  181. package/examples/playground/app/a2slack/events/route.ts +36 -0
  182. package/examples/playground/app/a2slack/identity.ts +44 -0
  183. package/examples/playground/app/a2slack/inbox/route.ts +8 -0
  184. package/examples/playground/app/a2slack/lag/data/route.ts +8 -0
  185. package/examples/playground/app/a2slack/lag/page.tsx +101 -0
  186. package/examples/playground/app/a2slack/lag.ts +73 -0
  187. package/examples/playground/app/a2slack/layout.tsx +43 -0
  188. package/examples/playground/app/a2slack/messages/route.ts +17 -0
  189. package/examples/playground/app/a2slack/model.test.ts +208 -0
  190. package/examples/playground/app/a2slack/model.ts +369 -0
  191. package/examples/playground/app/a2slack/models.test.ts +72 -0
  192. package/examples/playground/app/a2slack/page.tsx +10 -0
  193. package/examples/playground/app/a2slack/scheduler/route.ts +5 -0
  194. package/examples/playground/app/a2slack/search/route.ts +40 -0
  195. package/examples/playground/app/a2slack/search-index.ts +108 -0
  196. package/examples/playground/app/a2slack/server.test.ts +315 -0
  197. package/examples/playground/app/a2slack/server.ts +55 -0
  198. package/examples/playground/app/a2slack/sessions.ts +50 -0
  199. package/examples/playground/app/a2slack/thread/route.ts +8 -0
  200. package/examples/playground/app/a2slack/ui/ChannelView.tsx +87 -0
  201. package/examples/playground/app/a2slack/ui/Composer.tsx +117 -0
  202. package/examples/playground/app/a2slack/ui/DotsShadow.tsx +42 -0
  203. package/examples/playground/app/a2slack/ui/Feed.tsx +157 -0
  204. package/examples/playground/app/a2slack/ui/InboxContext.tsx +63 -0
  205. package/examples/playground/app/a2slack/ui/InboxView.tsx +82 -0
  206. package/examples/playground/app/a2slack/ui/Menu.tsx +128 -0
  207. package/examples/playground/app/a2slack/ui/MessageRow.tsx +314 -0
  208. package/examples/playground/app/a2slack/ui/NameGate.tsx +35 -0
  209. package/examples/playground/app/a2slack/ui/SearchContext.tsx +146 -0
  210. package/examples/playground/app/a2slack/ui/SearchResults.tsx +97 -0
  211. package/examples/playground/app/a2slack/ui/Shell.tsx +34 -0
  212. package/examples/playground/app/a2slack/ui/Sidebar.tsx +199 -0
  213. package/examples/playground/app/a2slack/ui/ThreadPanel.tsx +134 -0
  214. package/examples/playground/app/a2slack/ui/useInbox.ts +71 -0
  215. package/examples/playground/app/agent/server.ts +3 -3
  216. package/examples/playground/app/chat/[chatId]/chat-client.tsx +1 -1
  217. package/examples/playground/app/chat/server.ts +45 -35
  218. package/examples/playground/app/components/demo-icons.tsx +7 -0
  219. package/examples/playground/app/components/demos.tsx +7 -0
  220. package/examples/playground/app/orders/[orderId]/order-client.tsx +2 -2
  221. package/examples/playground/app/orders/page.tsx +1 -1
  222. package/examples/playground/app/orders/server.ts +49 -30
  223. package/examples/playground/app/recovery/[recoveryId]/recovery-client.tsx +14 -15
  224. package/examples/playground/app/recovery/page.tsx +4 -4
  225. package/examples/playground/app/recovery/server.ts +23 -32
  226. package/examples/playground/drizzle.config.ts +14 -0
  227. package/examples/playground/next.config.ts +6 -1
  228. package/examples/playground/package.json +12 -1
  229. package/examples/playground/scripts/migrate.mjs +31 -0
  230. package/examples/playground/vercel.json +9 -0
  231. package/examples/playground/vitest.drills.config.ts +32 -0
  232. package/package.json +5 -2
  233. package/sql/postgres/drizzle-schema.ts +206 -0
  234. package/sql/postgres/schema.sql +206 -67
  235. package/src/actor.ts +101 -71
  236. package/src/ai-agent.ts +149 -111
  237. package/src/ai-control-server.ts +8 -8
  238. package/src/ai-fx.ts +4 -6
  239. package/src/ai-harness.ts +10 -2
  240. package/src/ai-pi.ts +2 -2
  241. package/src/ai-server.ts +2 -2
  242. package/src/ai.ts +7 -7
  243. package/src/contract.ts +1 -1
  244. package/src/deterministic-id.ts +26 -3
  245. package/src/errors.ts +8 -5
  246. package/src/idempotent-replay.ts +0 -1
  247. package/src/index.ts +1 -1
  248. package/src/internal.ts +15 -5
  249. package/src/otel.ts +1 -1
  250. package/src/postgres-schema.ts +98 -57
  251. package/src/push-envelope.ts +20 -0
  252. package/src/runtime-consumer.ts +10 -0
  253. package/src/scheduler-task.ts +2 -2
  254. package/src/scheduler-vercel.ts +1 -1
  255. package/src/server.browser.ts +1 -1
  256. package/src/server.ts +774 -207
  257. package/src/session-socket.ts +1 -1
  258. package/src/store-codec.ts +66 -0
  259. package/src/store-memory.ts +581 -255
  260. package/src/store-postgres.ts +1984 -825
  261. package/src/store-redis-core.ts +1624 -1152
  262. package/src/store-redis-notify.ts +2 -0
  263. package/src/store-sqlite.ts +891 -486
  264. package/src/store.ts +227 -97
  265. package/src/telemetry.ts +2 -1
  266. package/src/wire.ts +1 -0
  267. package/dist/ai-harness-Clbg5ei7.js.map +0 -1
  268. package/dist/ai-mMiWul1T.js.map +0 -1
  269. package/dist/contract-BYKASlCV.js.map +0 -1
  270. package/dist/idempotent-replay-JdgMQRRm.js +0 -21
  271. package/dist/idempotent-replay-JdgMQRRm.js.map +0 -1
  272. package/dist/initial-snapshot-Bx-c0pDP.d.ts.map +0 -1
  273. package/dist/internal-CscSY7K_.js.map +0 -1
  274. package/dist/server-DYAATFuT.d.ts.map +0 -1
  275. package/dist/server-qyb5aJJG.js.map +0 -1
  276. package/dist/session-clear-C-QwTXV1.d.ts.map +0 -1
  277. package/dist/session-clear-DGI4jTQ5.js.map +0 -1
  278. package/dist/store-CyLUy86v.d.ts +0 -404
  279. package/dist/store-CyLUy86v.d.ts.map +0 -1
  280. package/dist/store-codec-DTG0Ftek.js +0 -10
  281. package/dist/store-codec-DTG0Ftek.js.map +0 -1
  282. package/dist/store-redis-notify-CM0AfLY0.js +0 -2544
  283. package/dist/store-redis-notify-CM0AfLY0.js.map +0 -1
  284. package/dist/telemetry-Cyfqo6Qt.d.ts.map +0 -1
  285. package/dist/wire-BKxH1vbP.js.map +0 -1
  286. package/docs/server/01-handlers.mdx +0 -227
package/dist/ai-server.js CHANGED
@@ -1,11 +1,12 @@
1
- import { i as A2Error } from "./session-clear-DGI4jTQ5.js";
2
- import { a as reducer, s as validateSync } from "./reducer-BAXc8JyF.js";
3
- import { h as installAmbientToolScopeStorage, m as failedPreviousAttempt, p as consumeSchedulerSendFailure } from "./internal-CscSY7K_.js";
1
+ import { i as A2Error } from "./session-clear-wHd5GCpZ.js";
2
+ import { a as reducer, s as validateSync } from "./reducer-CjmvZSAb.js";
3
+ import { h as installAmbientToolScopeStorage, m as failedPreviousAttempt, p as consumeSchedulerSendFailure } from "./internal-Bc4PvfHk.js";
4
4
  import { t as boundedCache } from "./bounded-cache-CPHWF-8h.js";
5
- import { a as CONSOLE_TELEMETRY, o as setServerFetchHooks, t as createServer } from "./server-qyb5aJJG.js";
5
+ import { a as CONSOLE_TELEMETRY, n as createServer, o as setServerFetchHooks } from "./server-DvIB8kj5.js";
6
6
  import { a as unexplainedAdmission, i as steersOn, n as initialControlState, r as steeringEnd, t as STEERED_REASON } from "./ai-control-CvLbW10B.js";
7
- import { A as interruptUIMessage, C as reduceToolActivity, D as flattenProgressBatches, E as upsertResponse, M as assertMessageBase, N as restoreMessageBase, O as progressBatches, S as projectedMessage, T as upsertMessage, _ as applyControlChanges, a as events, b as findMessage, d as appSlice, f as isAgentContract, g as isUIMessage, h as aiEventId, j as pauseUIMessage, k as progressOwnedBy, m as AI_EVENT_ID_PREFIX, n as agentContract, p as withAIStorage, u as appReducerOf, v as controlCommit, w as retainMessageBase, y as advanceProjection } from "./ai-mMiWul1T.js";
8
- import { a as gatewaySessionAffinity, c as harnessLog, f as registerHarnessStates, l as harnessStates, o as harnessDriver } from "./ai-harness-Clbg5ei7.js";
7
+ import { A as interruptUIMessage, C as reduceToolActivity, D as flattenProgressBatches, E as upsertResponse, M as assertMessageBase, N as restoreMessageBase, O as progressBatches, S as projectedMessage, T as upsertMessage, _ as applyControlChanges, b as findMessage, d as appSlice, f as isAgentContract, g as isUIMessage, h as aiEventId, j as pauseUIMessage, k as progressOwnedBy, m as AI_EVENT_ID_PREFIX, n as agentContract, o as events, p as withAIStorage, u as appReducerOf, v as controlCommit, w as retainMessageBase, y as advanceProjection } from "./ai-CzE672Q3.js";
8
+ import { a as gatewaySessionAffinity, c as harnessLog, f as registerHarnessStates, l as harnessStates, o as harnessDriver } from "./ai-harness-dQeJaR1t.js";
9
+ import { t as runtimeConsumer } from "./runtime-consumer-BWmht60z.js";
9
10
  import { AsyncLocalStorage } from "node:async_hooks";
10
11
  import { asSchema, convertToModelMessages, isToolUIPart, stepCountIs, streamText, toUIMessageStream } from "ai";
11
12
  import { Buffer } from "node:buffer";
@@ -1606,8 +1607,8 @@ const measuredInputTokens = (options) => {
1606
1607
  //#endregion
1607
1608
  //#region src/ai-agent.ts
1608
1609
  /**
1609
- * The server-only implementation of the experimental-a2/ai protocol: the
1610
- * handler table and `agent()`, its assembly as an ordinary A2 server.
1610
+ * The server-only implementation of the experimental-a2/ai protocol: its
1611
+ * consumers and `agent()`, its assembly as an ordinary A2 server.
1611
1612
  */
1612
1613
  const isAgentIngressEvent = (event) => {
1613
1614
  if (event.type !== "ai.control.requested") return false;
@@ -1658,8 +1659,8 @@ const withModelSettings = (options) => {
1658
1659
  const instructionTexts = (instructions) => instructions === void 0 ? [] : typeof instructions === "string" ? [instructions] : (Array.isArray(instructions) ? instructions : [instructions]).map((message) => message.content);
1659
1660
  const errorMessage = (error) => error instanceof Error ? error.message : String(error);
1660
1661
  const toolScopeStorage = installAmbientToolScopeStorage(() => new AsyncLocalStorage());
1661
- /** Run `fn` with `ctx` as the ambient tool handler context, for direct tool tests. */
1662
- function runWithHandlerContext(ctx, fn) {
1662
+ /** Run `fn` with `ctx` as the ambient tool consumer context, for direct tool tests. */
1663
+ function runWithConsumerContext(ctx, fn) {
1663
1664
  return toolScopeStorage.run({ context: ctx }, fn);
1664
1665
  }
1665
1666
  /** Sessions whose latest step prompt one process keeps for that step's tools. */
@@ -2118,7 +2119,7 @@ const assertNoLoopOptions = (options) => {
2118
2119
  throw new TypeError(harness === "ai-sdk" ? `${key} belongs to the harness: agent({ harness: { type: 'ai-sdk', ${key} } })` : `${key} is an option of the AI SDK harness; ${harness}() runs its own loop`);
2119
2120
  }
2120
2121
  };
2121
- function createHandlers(options) {
2122
+ function createConsumers(options) {
2122
2123
  if (options.model === void 0) throw new TypeError("agent requires model");
2123
2124
  if (options.progress?.maxChunks !== void 0 && (!Number.isInteger(options.progress.maxChunks) || options.progress.maxChunks < 1)) throw new TypeError("progress.maxChunks must be a positive integer");
2124
2125
  if (options.progress?.maxDelayMs !== void 0 && (!Number.isFinite(options.progress.maxDelayMs) || options.progress.maxDelayMs < 0)) throw new TypeError("progress.maxDelayMs must be a non-negative number");
@@ -2742,8 +2743,14 @@ function createHandlers(options) {
2742
2743
  };
2743
2744
  }
2744
2745
  };
2745
- return {
2746
- "ai.model.metadata.requested": { handler: async (ctx) => {
2746
+ const contract = options.contract;
2747
+ const { toolLane } = options;
2748
+ return [
2749
+ runtimeConsumer({
2750
+ contract,
2751
+ name: "a2.ai.metadata",
2752
+ types: ["ai.model.metadata.requested"]
2753
+ }).run(async (ctx) => {
2747
2754
  const limits = await readModelLimits({
2748
2755
  modelId: ctx.event.payload.modelId,
2749
2756
  signal: ctx.signal
@@ -2757,27 +2764,29 @@ function createHandlers(options) {
2757
2764
  limits
2758
2765
  }
2759
2766
  };
2760
- } },
2761
- "ai.control.requested": {
2767
+ }),
2768
+ runtimeConsumer({
2769
+ contract,
2770
+ name: "a2.ai.control",
2771
+ types: [
2772
+ "ai.control.requested",
2773
+ "ai.work.reported",
2774
+ "ai.session.closed"
2775
+ ],
2762
2776
  lane: ({ event }) => {
2777
+ if (event.type !== "ai.control.requested") return "a2.ai.control";
2763
2778
  const command = event.payload;
2764
2779
  if (event.id === "") throw new A2Error("INVALID_PAYLOAD", "AI command IDs must be nonempty");
2765
2780
  if (event.id?.startsWith("a2.ai:")) throw new A2Error("INVALID_PAYLOAD", `AI command IDs cannot use the reserved '${AI_EVENT_ID_PREFIX}' prefix`);
2766
2781
  if ((command.action === "send" || command.action === "steer") && event.id !== command.message.id) throw new A2Error("INVALID_PAYLOAD", "AI input event ID must equal message.id");
2767
2782
  return "a2.ai.control";
2768
- },
2769
- handler: controlHandler
2770
- },
2771
- "ai.work.reported": {
2772
- lane: "a2.ai.control",
2773
- handler: controlHandler
2774
- },
2775
- "ai.session.closed": {
2776
- lane: "a2.ai.control",
2777
- handler: controlHandler
2778
- },
2779
- "ai.generation.requested": {
2780
- lane: "a2.ai.model",
2783
+ }
2784
+ }).run(controlHandler),
2785
+ runtimeConsumer({
2786
+ contract,
2787
+ name: "a2.ai.model",
2788
+ types: ["ai.generation.requested"],
2789
+ lane: () => "a2.ai.model",
2781
2790
  abortOn: {
2782
2791
  "ai.control.requested": (event, trigger) => event.payload.action === "stop" && event.payload.turnId === trigger.payload.control?.turnId,
2783
2792
  "ai.control.committed": (event, trigger) => {
@@ -2785,32 +2794,34 @@ function createHandlers(options) {
2785
2794
  return active?.turnId !== trigger.payload.control?.turnId || active?.version !== trigger.payload.control?.version;
2786
2795
  },
2787
2796
  "ai.session.closed": true
2788
- },
2789
- handler: (ctx) => telemetry.span("a2.ai.generate", {
2790
- "a2.contract": options.contract.name,
2791
- "a2.session_id": ctx.event.sessionId,
2792
- "a2.ai.generate.request_id": ctx.event.id,
2793
- "a2.ai.generate.attempt": ctx.attempt
2794
- }, async () => {
2795
- try {
2796
- return control.settled({
2797
- ctx,
2798
- events: await generationHandler(ctx)
2799
- });
2800
- } catch (error) {
2801
- if (control.cancelled({
2802
- error,
2803
- signal: ctx.signal
2804
- })) return control.settled({
2805
- ctx,
2806
- events: void 0
2807
- });
2808
- throw error;
2809
- }
2810
- })
2811
- },
2812
- "ai.tool.execution.requested": {
2813
- ...options.toolLane === void 0 ? {} : { lane: options.toolLane },
2797
+ }
2798
+ }).run((ctx) => telemetry.span("a2.ai.generate", {
2799
+ "a2.contract": options.contract.name,
2800
+ "a2.session_id": ctx.event.sessionId,
2801
+ "a2.ai.generate.request_id": ctx.event.id,
2802
+ "a2.ai.generate.attempt": ctx.attempt
2803
+ }, async () => {
2804
+ try {
2805
+ return control.settled({
2806
+ ctx,
2807
+ events: await generationHandler(ctx)
2808
+ });
2809
+ } catch (error) {
2810
+ if (control.cancelled({
2811
+ error,
2812
+ signal: ctx.signal
2813
+ })) return control.settled({
2814
+ ctx,
2815
+ events: void 0
2816
+ });
2817
+ throw error;
2818
+ }
2819
+ })),
2820
+ runtimeConsumer({
2821
+ contract,
2822
+ name: "a2.ai.tools",
2823
+ types: ["ai.tool.execution.requested"],
2824
+ ...toolLane === void 0 ? {} : { lane: () => toolLane },
2814
2825
  abortOn: {
2815
2826
  "ai.control.requested": (event, trigger) => event.payload.action === "stop" && event.payload.turnId === trigger.payload.turnId,
2816
2827
  "ai.generation.failed": (event, trigger) => event.payload.generationId === trigger.payload.call.generationId,
@@ -2819,21 +2830,21 @@ function createHandlers(options) {
2819
2830
  return active?.turnId !== trigger.payload.turnId || active?.version !== trigger.payload.version;
2820
2831
  },
2821
2832
  "ai.session.closed": true
2822
- },
2823
- handler: (ctx) => telemetry.span("a2.ai.tool", {
2824
- "a2.contract": options.contract.name,
2825
- "a2.session_id": ctx.event.sessionId,
2826
- "a2.ai.tool.request_id": ctx.event.payload.call.requestId,
2827
- "a2.ai.tool.call_id": ctx.event.payload.call.toolCallId,
2828
- "a2.ai.tool.name": ctx.event.payload.call.toolName,
2829
- "a2.ai.tool.attempt": ctx.attempt
2830
- }, () => handleToolExecution(ctx))
2831
- }
2832
- };
2833
+ }
2834
+ }).run((ctx) => telemetry.span("a2.ai.tool", {
2835
+ "a2.contract": options.contract.name,
2836
+ "a2.session_id": ctx.event.sessionId,
2837
+ "a2.ai.tool.request_id": ctx.event.payload.call.requestId,
2838
+ "a2.ai.tool.call_id": ctx.event.payload.call.toolCallId,
2839
+ "a2.ai.tool.name": ctx.event.payload.call.toolName,
2840
+ "a2.ai.tool.attempt": ctx.attempt
2841
+ }, () => handleToolExecution(ctx)))
2842
+ ];
2833
2843
  }
2834
2844
  function agent(options) {
2835
2845
  assertNoLoopOptions(options);
2836
- const { model, tools, instructions, maxSteps, harness, toolRecovery, progress, toolLane, handlers, ...rest } = options;
2846
+ if (options.toolLane !== void 0 && (typeof options.toolLane !== "string" || options.toolLane.length === 0)) throw new TypeError("toolLane must be a non-empty string");
2847
+ const { model, tools, instructions, maxSteps, harness, toolRecovery, progress, toolLane, ...rest } = options;
2837
2848
  let contract;
2838
2849
  let serverOptions;
2839
2850
  if ("contract" in rest) {
@@ -2852,7 +2863,7 @@ function agent(options) {
2852
2863
  serverOptions = remaining;
2853
2864
  }
2854
2865
  const states = harnessStates();
2855
- const builtIns = createHandlers({
2866
+ const builtIns = createConsumers({
2856
2867
  contract,
2857
2868
  model,
2858
2869
  harnessStates: states,
@@ -2865,14 +2876,10 @@ function agent(options) {
2865
2876
  ...progress === void 0 ? {} : { progress },
2866
2877
  ...toolLane === void 0 ? {} : { toolLane }
2867
2878
  });
2868
- for (const type of Object.keys(handlers ?? {})) if (Object.hasOwn(builtIns, type)) throw new TypeError(`agent handles '${type}' itself`);
2869
2879
  const server = createServer({
2870
2880
  ...serverOptions,
2871
2881
  contract,
2872
- handlers: {
2873
- ...builtIns,
2874
- ...handlers
2875
- }
2882
+ consumers: [...builtIns, ...serverOptions.consumers ?? []]
2876
2883
  });
2877
2884
  registerHarnessStates(server, states);
2878
2885
  const applicationEvents = "contract" in rest;
@@ -2883,6 +2890,6 @@ function agent(options) {
2883
2890
  return server;
2884
2891
  }
2885
2892
  //#endregion
2886
- export { agent, runWithHandlerContext };
2893
+ export { agent, runWithConsumerContext };
2887
2894
 
2888
2895
  //# sourceMappingURL=ai-server.js.map