@demlik/tea 0.13.0 → 0.14.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 (372) hide show
  1. package/README.md +11 -9
  2. package/dist/agent/index.d.ts +637 -45
  3. package/dist/agent/index.js +9 -19
  4. package/dist/{chunk-25LBDCBC.js → chunk-6IQPODUF.js} +2 -2
  5. package/dist/{chunk-25LBDCBC.js.map → chunk-6IQPODUF.js.map} +1 -1
  6. package/dist/chunk-AQ6ZIMEA.js +421 -0
  7. package/dist/chunk-AQ6ZIMEA.js.map +1 -0
  8. package/dist/{chunk-MUUROGIH.js → chunk-BLJ2JQSH.js} +62 -12
  9. package/dist/chunk-BLJ2JQSH.js.map +1 -0
  10. package/dist/{chunk-RH5EFRVJ.js → chunk-F2US5BW6.js} +25 -5
  11. package/dist/chunk-F2US5BW6.js.map +1 -0
  12. package/dist/{batch-window/index.js → chunk-F7FMAWLA.js} +4 -8
  13. package/dist/chunk-F7FMAWLA.js.map +1 -0
  14. package/dist/{chunk-O4MVQTEJ.js → chunk-HUKZQX6U.js} +20 -16
  15. package/dist/chunk-HUKZQX6U.js.map +1 -0
  16. package/dist/{chunk-EWJP3YYP.js → chunk-HWVW4AXC.js} +3 -3
  17. package/dist/chunk-HWVW4AXC.js.map +1 -0
  18. package/dist/{chunk-DMYGQB4O.js → chunk-HYDWG35Q.js} +23 -6
  19. package/dist/chunk-HYDWG35Q.js.map +1 -0
  20. package/dist/{chunk-YUXP55T2.js → chunk-I5MQMJDW.js} +57 -7
  21. package/dist/chunk-I5MQMJDW.js.map +1 -0
  22. package/dist/{chunk-J6527VRQ.js → chunk-LFZUK6J2.js} +3 -3
  23. package/dist/chunk-LFZUK6J2.js.map +1 -0
  24. package/dist/{chunk-ZVJZ72HY.js → chunk-LYLTKJWM.js} +25 -11
  25. package/dist/chunk-LYLTKJWM.js.map +1 -0
  26. package/dist/{chunk-D736QUGF.js → chunk-MYXFNWAJ.js} +4 -5
  27. package/dist/chunk-MYXFNWAJ.js.map +1 -0
  28. package/dist/{chunk-K575PT4S.js → chunk-PR6TB3BL.js} +15 -4
  29. package/dist/chunk-PR6TB3BL.js.map +1 -0
  30. package/dist/chunk-RQULHGYH.js +1804 -0
  31. package/dist/chunk-RQULHGYH.js.map +1 -0
  32. package/dist/{chunk-FV3Z5MBE.js → chunk-TXN2KFHF.js} +14 -4
  33. package/dist/chunk-TXN2KFHF.js.map +1 -0
  34. package/dist/{chunk-Q2UM7BXU.js → chunk-VBDU4JL6.js} +2 -2
  35. package/dist/chunk-VBDU4JL6.js.map +1 -0
  36. package/dist/chunk-Z2L3LSNV.js +1470 -0
  37. package/dist/chunk-Z2L3LSNV.js.map +1 -0
  38. package/dist/{core-Co0LWkIA.d.ts → core-CTzMJ82M.d.ts} +72 -23
  39. package/dist/devtools/index.d.ts +2 -2
  40. package/dist/devtools/index.js +207 -2
  41. package/dist/devtools/index.js.map +1 -1
  42. package/dist/do/index.d.ts +42 -29
  43. package/dist/do/index.js +36 -25
  44. package/dist/do/index.js.map +1 -1
  45. package/dist/{durable-effects-C6uwzjb5.d.ts → durable-effects-B0-qGQDy.d.ts} +2 -2
  46. package/dist/extension/index.d.ts +300 -3
  47. package/dist/extension/index.js +596 -5
  48. package/dist/extension/index.js.map +1 -1
  49. package/dist/flow/index.d.ts +1295 -0
  50. package/dist/flow/index.js +732 -0
  51. package/dist/flow/index.js.map +1 -0
  52. package/dist/idempotency/index.d.ts +90 -116
  53. package/dist/idempotency/index.js +4 -1
  54. package/dist/{batch-window/index.d.ts → index-4vZzljCD.d.ts} +7 -12
  55. package/dist/{fan-out/index.d.ts → index-6A7dB8f6.d.ts} +7 -9
  56. package/dist/index-B5BZ-_cT.d.ts +616 -0
  57. package/dist/index-Bc40JWVl.d.ts +131 -0
  58. package/dist/{debounce/index.d.ts → index-DHSUmQTR.d.ts} +7 -7
  59. package/dist/index-DJWIER_3.d.ts +69 -0
  60. package/dist/{snapshot/index.d.ts → index-DMCeMPMJ.d.ts} +15 -78
  61. package/dist/{monitored-run/index.d.ts → index-NjrT3fL2.d.ts} +37 -13
  62. package/dist/{recorder/index.d.ts → index-TvRb1KVf.d.ts} +4 -7
  63. package/dist/{deadline/index.d.ts → index-q0hXFeZ0.d.ts} +155 -9
  64. package/dist/index.d.ts +711 -6
  65. package/dist/index.js +1 -2
  66. package/dist/jev/index.d.ts +634 -0
  67. package/dist/jev/index.js +433 -0
  68. package/dist/jev/index.js.map +1 -0
  69. package/dist/machine-CdIcN2Xm.d.ts +1773 -0
  70. package/dist/machine-viz/index.d.ts +1 -1
  71. package/dist/machine-viz/index.js +12 -5
  72. package/dist/machine-viz/index.js.map +1 -1
  73. package/dist/mem/index.d.ts +18 -3
  74. package/dist/mem/index.js +22 -2
  75. package/dist/mem/index.js.map +1 -1
  76. package/dist/node/index.d.ts +104 -6
  77. package/dist/node/index.js +132 -9
  78. package/dist/node/index.js.map +1 -1
  79. package/dist/{paginator → paginate}/index.d.ts +151 -6
  80. package/dist/paginate/index.js +7 -0
  81. package/dist/parity/index.d.ts +4 -10
  82. package/dist/parity/index.js +4 -7
  83. package/dist/parity/index.js.map +1 -1
  84. package/dist/pbt/index.d.ts +247 -5
  85. package/dist/pbt/index.js +124 -5
  86. package/dist/pbt/index.js.map +1 -1
  87. package/dist/{trace-replay → persistence}/index.d.ts +7 -5
  88. package/dist/persistence/index.js +6 -0
  89. package/dist/react/index.d.ts +2 -2
  90. package/dist/react/index.js +1 -2
  91. package/dist/react/index.js.map +1 -1
  92. package/dist/resilience/index.d.ts +743 -0
  93. package/dist/resilience/index.js +657 -0
  94. package/dist/resilience/index.js.map +1 -0
  95. package/dist/retry-backoff/index.d.ts +3 -2
  96. package/dist/retry-backoff/index.js +1 -1
  97. package/dist/runtime-types-LWDoi943.d.ts +998 -0
  98. package/dist/testing/index.d.ts +2 -2
  99. package/dist/testing/index.js +1 -2
  100. package/dist/testing/index.js.map +1 -1
  101. package/dist/{throttled-input → timing}/index.d.ts +143 -12
  102. package/dist/{throttled-input → timing}/index.js +57 -12
  103. package/dist/timing/index.js.map +1 -0
  104. package/dist/{types-XS_miRnB.d.ts → types-DP3f5NIl.d.ts} +1 -1
  105. package/dist/work-queue/index.d.ts +130 -54
  106. package/dist/work-queue/index.js +3 -2
  107. package/dist/work-queue/index.js.map +1 -1
  108. package/package.json +45 -218
  109. package/dist/authed-call/index.d.ts +0 -120
  110. package/dist/authed-call/index.js +0 -134
  111. package/dist/authed-call/index.js.map +0 -1
  112. package/dist/await-terminal/index.d.ts +0 -101
  113. package/dist/await-terminal/index.js +0 -76
  114. package/dist/await-terminal/index.js.map +0 -1
  115. package/dist/batch-window/index.js.map +0 -1
  116. package/dist/cache/index.d.ts +0 -152
  117. package/dist/cache/index.js +0 -8
  118. package/dist/chart/index.d.ts +0 -218
  119. package/dist/chart/index.js +0 -16
  120. package/dist/chart/index.js.map +0 -1
  121. package/dist/chart/inspect/index.d.ts +0 -86
  122. package/dist/chart/inspect/index.js +0 -5
  123. package/dist/chart/inspect/react.d.ts +0 -113
  124. package/dist/chart/inspect/react.js +0 -11
  125. package/dist/chart/inspect/react.js.map +0 -1
  126. package/dist/chart/inspect/styles.css +0 -286
  127. package/dist/chart/lane/index.d.ts +0 -362
  128. package/dist/chart/lane/index.js +0 -9
  129. package/dist/chart/lane/index.js.map +0 -1
  130. package/dist/chart/lane/react.d.ts +0 -84
  131. package/dist/chart/lane/react.js +0 -559
  132. package/dist/chart/lane/react.js.map +0 -1
  133. package/dist/chart/lane/server.d.ts +0 -148
  134. package/dist/chart/lane/server.js +0 -209
  135. package/dist/chart/lane/server.js.map +0 -1
  136. package/dist/chart/lane/styles.css +0 -498
  137. package/dist/chart/lane/viewer/assets/abnfDiagram-N423BO3Z-C729LI31.js +0 -1
  138. package/dist/chart/lane/viewer/assets/architectureDiagram-T3A2C74G-C729LI31.js +0 -1
  139. package/dist/chart/lane/viewer/assets/blockDiagram-VBNYF7ZC-C729LI31.js +0 -1
  140. package/dist/chart/lane/viewer/assets/c4Diagram-5PPSVZJV-C729LI31.js +0 -1
  141. package/dist/chart/lane/viewer/assets/chunk-2GRJ4B5K-HdDf8SI3.js +0 -1
  142. package/dist/chart/lane/viewer/assets/chunk-5RXB4S5H-CcNtpUd7.js +0 -231
  143. package/dist/chart/lane/viewer/assets/chunk-5VM5RSS4-BP4fRS_5.js +0 -15
  144. package/dist/chart/lane/viewer/assets/chunk-KBJHAD2P-DZOw7xU6.js +0 -1
  145. package/dist/chart/lane/viewer/assets/chunk-NSK5VX7P-CBCyTZMs.js +0 -128
  146. package/dist/chart/lane/viewer/assets/classDiagram-JCYQIIEL-C729LI31.js +0 -1
  147. package/dist/chart/lane/viewer/assets/classDiagram-v2-OCEON4UE-D4uAiFr8.js +0 -206
  148. package/dist/chart/lane/viewer/assets/cose-bilkent-JH36ORCC-DOwCrGXH.js +0 -1
  149. package/dist/chart/lane/viewer/assets/cynefinDiagram-MW4NZA55-C729LI31.js +0 -1
  150. package/dist/chart/lane/viewer/assets/dagre-K_PewWfS.js +0 -1
  151. package/dist/chart/lane/viewer/assets/dagre-VZM6K2ZE-831qZcA8.js +0 -4
  152. package/dist/chart/lane/viewer/assets/diagram-7IWD3JNH-C729LI31.js +0 -1
  153. package/dist/chart/lane/viewer/assets/diagram-B4RE2ZJO-C729LI31.js +0 -1
  154. package/dist/chart/lane/viewer/assets/diagram-LBJQPF4R-C729LI31.js +0 -1
  155. package/dist/chart/lane/viewer/assets/diagram-Q27KOJAE-C729LI31.js +0 -1
  156. package/dist/chart/lane/viewer/assets/diagram-UB23O5K3-C729LI31.js +0 -1
  157. package/dist/chart/lane/viewer/assets/ebnfDiagram-BXEA7PRR-C729LI31.js +0 -1
  158. package/dist/chart/lane/viewer/assets/erDiagram-JOGREHBK-C729LI31.js +0 -1
  159. package/dist/chart/lane/viewer/assets/flowDiagram-UKHOOZJN-C729LI31.js +0 -1
  160. package/dist/chart/lane/viewer/assets/ganttDiagram-PKOTCBZU-C729LI31.js +0 -1
  161. package/dist/chart/lane/viewer/assets/gitGraphDiagram-DS77QQ5N-C729LI31.js +0 -1
  162. package/dist/chart/lane/viewer/assets/index-9SkH5NA3.css +0 -1
  163. package/dist/chart/lane/viewer/assets/index-Bgt4sXpW.js +0 -195
  164. package/dist/chart/lane/viewer/assets/infoDiagram-6WML65LV-C729LI31.js +0 -1
  165. package/dist/chart/lane/viewer/assets/ishikawaDiagram-WSZJBQD7-C729LI31.js +0 -1
  166. package/dist/chart/lane/viewer/assets/journeyDiagram-NVQOT4AX-C729LI31.js +0 -1
  167. package/dist/chart/lane/viewer/assets/kanban-definition-27J2QSJJ-G7PaPzy-.js +0 -89
  168. package/dist/chart/lane/viewer/assets/katex-DOwCrGXH.js +0 -1
  169. package/dist/chart/lane/viewer/assets/mindmap-definition-FAOFIHXS-CGj9nrVk.js +0 -96
  170. package/dist/chart/lane/viewer/assets/path-fybaL0A-.js +0 -1
  171. package/dist/chart/lane/viewer/assets/pegDiagram-VL7TDLO6-C729LI31.js +0 -1
  172. package/dist/chart/lane/viewer/assets/pieDiagram-7S7Q4E2Y-C729LI31.js +0 -1
  173. package/dist/chart/lane/viewer/assets/quadrantDiagram-CIZ2JOQS-C729LI31.js +0 -1
  174. package/dist/chart/lane/viewer/assets/railroadDiagram-AXF67PYL-C729LI31.js +0 -1
  175. package/dist/chart/lane/viewer/assets/requirementDiagram-LRYGKXZP-C729LI31.js +0 -1
  176. package/dist/chart/lane/viewer/assets/sankeyDiagram-W5VNT64P-C729LI31.js +0 -1
  177. package/dist/chart/lane/viewer/assets/sequenceDiagram-SI44F4Z6-C729LI31.js +0 -1
  178. package/dist/chart/lane/viewer/assets/stateDiagram-OKZ733FA-B_88AzBS.js +0 -1
  179. package/dist/chart/lane/viewer/assets/stateDiagram-v2-UEYNNEHI-CR5gcgq6.js +0 -1
  180. package/dist/chart/lane/viewer/assets/swimlanes-SLNWSIFB-B4xK-rwg.js +0 -1
  181. package/dist/chart/lane/viewer/assets/swimlanesDiagram-ULZ7WXOC-C729LI31.js +0 -1
  182. package/dist/chart/lane/viewer/assets/timeline-definition-Z64GVDOM-CCv52MfY.js +0 -120
  183. package/dist/chart/lane/viewer/assets/vennDiagram-T6HMQDX7-C729LI31.js +0 -1
  184. package/dist/chart/lane/viewer/assets/wardleyDiagram-T6FBY63Y-C729LI31.js +0 -1
  185. package/dist/chart/lane/viewer/assets/xychartDiagram-ELKLHX3M-C729LI31.js +0 -1
  186. package/dist/chart/lane/viewer/index.html +0 -15
  187. package/dist/chart/report/index.d.ts +0 -117
  188. package/dist/chart/report/index.js +0 -32
  189. package/dist/chart/report/index.js.map +0 -1
  190. package/dist/chunk-2YFLOCWX.js +0 -15
  191. package/dist/chunk-2YFLOCWX.js.map +0 -1
  192. package/dist/chunk-3I52QZZ5.js +0 -519
  193. package/dist/chunk-3I52QZZ5.js.map +0 -1
  194. package/dist/chunk-3ZAFFRRB.js +0 -457
  195. package/dist/chunk-3ZAFFRRB.js.map +0 -1
  196. package/dist/chunk-4EQZ76JC.js +0 -33
  197. package/dist/chunk-4EQZ76JC.js.map +0 -1
  198. package/dist/chunk-4KLG43GY.js +0 -223
  199. package/dist/chunk-4KLG43GY.js.map +0 -1
  200. package/dist/chunk-7FRZ2CT2.js +0 -424
  201. package/dist/chunk-7FRZ2CT2.js.map +0 -1
  202. package/dist/chunk-AZZLE7XR.js +0 -62
  203. package/dist/chunk-AZZLE7XR.js.map +0 -1
  204. package/dist/chunk-BYQUGDD3.js +0 -16
  205. package/dist/chunk-BYQUGDD3.js.map +0 -1
  206. package/dist/chunk-CIQG5L42.js +0 -685
  207. package/dist/chunk-CIQG5L42.js.map +0 -1
  208. package/dist/chunk-CLM6ERNO.js +0 -61
  209. package/dist/chunk-CLM6ERNO.js.map +0 -1
  210. package/dist/chunk-COS5MSTO.js +0 -88
  211. package/dist/chunk-COS5MSTO.js.map +0 -1
  212. package/dist/chunk-CRPZJVD2.js +0 -71
  213. package/dist/chunk-CRPZJVD2.js.map +0 -1
  214. package/dist/chunk-D62FDQKE.js +0 -53
  215. package/dist/chunk-D62FDQKE.js.map +0 -1
  216. package/dist/chunk-D736QUGF.js.map +0 -1
  217. package/dist/chunk-DGE4PV4A.js +0 -26
  218. package/dist/chunk-DGE4PV4A.js.map +0 -1
  219. package/dist/chunk-DMYGQB4O.js.map +0 -1
  220. package/dist/chunk-EWJP3YYP.js.map +0 -1
  221. package/dist/chunk-FV3Z5MBE.js.map +0 -1
  222. package/dist/chunk-HCEVHFJ7.js +0 -54
  223. package/dist/chunk-HCEVHFJ7.js.map +0 -1
  224. package/dist/chunk-J6527VRQ.js.map +0 -1
  225. package/dist/chunk-JELSZN25.js +0 -47
  226. package/dist/chunk-JELSZN25.js.map +0 -1
  227. package/dist/chunk-K575PT4S.js.map +0 -1
  228. package/dist/chunk-L57ZOT5K.js +0 -184
  229. package/dist/chunk-L57ZOT5K.js.map +0 -1
  230. package/dist/chunk-MU6MCIAC.js +0 -15
  231. package/dist/chunk-MU6MCIAC.js.map +0 -1
  232. package/dist/chunk-MUUROGIH.js.map +0 -1
  233. package/dist/chunk-NR7BU22N.js +0 -758
  234. package/dist/chunk-NR7BU22N.js.map +0 -1
  235. package/dist/chunk-O4MVQTEJ.js.map +0 -1
  236. package/dist/chunk-OOYD44JI.js +0 -317
  237. package/dist/chunk-OOYD44JI.js.map +0 -1
  238. package/dist/chunk-Q2UM7BXU.js.map +0 -1
  239. package/dist/chunk-RH5EFRVJ.js.map +0 -1
  240. package/dist/chunk-S2EGRPCM.js +0 -47
  241. package/dist/chunk-S2EGRPCM.js.map +0 -1
  242. package/dist/chunk-SINXE47Y.js +0 -55
  243. package/dist/chunk-SINXE47Y.js.map +0 -1
  244. package/dist/chunk-UF4MZSLT.js +0 -53
  245. package/dist/chunk-UF4MZSLT.js.map +0 -1
  246. package/dist/chunk-UOC2PL46.js +0 -13
  247. package/dist/chunk-UOC2PL46.js.map +0 -1
  248. package/dist/chunk-VYFAZN3F.js +0 -372
  249. package/dist/chunk-VYFAZN3F.js.map +0 -1
  250. package/dist/chunk-WRAA7GVZ.js +0 -209
  251. package/dist/chunk-WRAA7GVZ.js.map +0 -1
  252. package/dist/chunk-XGELA764.js +0 -163
  253. package/dist/chunk-XGELA764.js.map +0 -1
  254. package/dist/chunk-YUXP55T2.js.map +0 -1
  255. package/dist/chunk-YWIKDKHY.js +0 -307
  256. package/dist/chunk-YWIKDKHY.js.map +0 -1
  257. package/dist/chunk-ZJ5AOYBH.js +0 -8
  258. package/dist/chunk-ZJ5AOYBH.js.map +0 -1
  259. package/dist/chunk-ZSUUOEPL.js +0 -731
  260. package/dist/chunk-ZSUUOEPL.js.map +0 -1
  261. package/dist/chunk-ZVJZ72HY.js.map +0 -1
  262. package/dist/circuit-breaker/index.d.ts +0 -197
  263. package/dist/circuit-breaker/index.js +0 -3
  264. package/dist/circuit-breaker/index.js.map +0 -1
  265. package/dist/deadline/index.js +0 -6
  266. package/dist/deadline/index.js.map +0 -1
  267. package/dist/debounce/index.js +0 -3
  268. package/dist/debounce/index.js.map +0 -1
  269. package/dist/extension/react.d.ts +0 -121
  270. package/dist/extension/react.js +0 -75
  271. package/dist/extension/react.js.map +0 -1
  272. package/dist/extension/subs/index.d.ts +0 -45
  273. package/dist/extension/subs/index.js +0 -80
  274. package/dist/extension/subs/index.js.map +0 -1
  275. package/dist/extension/test-utils.d.ts +0 -128
  276. package/dist/extension/test-utils.js +0 -277
  277. package/dist/extension/test-utils.js.map +0 -1
  278. package/dist/fan-out/index.js +0 -5
  279. package/dist/fan-out/index.js.map +0 -1
  280. package/dist/fold-BJPdjc9w.d.ts +0 -435
  281. package/dist/graph-B3L5e0N1.d.ts +0 -923
  282. package/dist/idempotency/adapter.d.ts +0 -62
  283. package/dist/idempotency/adapter.js +0 -4
  284. package/dist/idempotency/adapter.js.map +0 -1
  285. package/dist/idempotent-intake/index.d.ts +0 -188
  286. package/dist/idempotent-intake/index.js +0 -7
  287. package/dist/idempotent-intake/index.js.map +0 -1
  288. package/dist/journal/index.d.ts +0 -373
  289. package/dist/journal/index.js +0 -3
  290. package/dist/journal/index.js.map +0 -1
  291. package/dist/llm-call/index.d.ts +0 -311
  292. package/dist/llm-call/index.js +0 -16
  293. package/dist/llm-call/index.js.map +0 -1
  294. package/dist/machine-BtFWQmmq.d.ts +0 -804
  295. package/dist/monitored-run/index.js +0 -10
  296. package/dist/monitored-run/index.js.map +0 -1
  297. package/dist/paginated-walk/index.d.ts +0 -235
  298. package/dist/paginated-walk/index.js +0 -16
  299. package/dist/paginated-walk/index.js.map +0 -1
  300. package/dist/paginator/index.js +0 -3
  301. package/dist/paginator/index.js.map +0 -1
  302. package/dist/pbt/arbitraries/index.d.ts +0 -136
  303. package/dist/pbt/arbitraries/index.js +0 -3
  304. package/dist/pbt/arbitraries/index.js.map +0 -1
  305. package/dist/pbt/runners/index.d.ts +0 -118
  306. package/dist/pbt/runners/index.js +0 -5
  307. package/dist/pbt/runners/index.js.map +0 -1
  308. package/dist/poller/index.d.ts +0 -352
  309. package/dist/poller/index.js +0 -115
  310. package/dist/poller/index.js.map +0 -1
  311. package/dist/prediction/index.d.ts +0 -131
  312. package/dist/prediction/index.js +0 -4
  313. package/dist/prediction/index.js.map +0 -1
  314. package/dist/protocol-B5YmJr0d.d.ts +0 -45
  315. package/dist/pure/index.d.ts +0 -3
  316. package/dist/pure/index.js +0 -4
  317. package/dist/pure/index.js.map +0 -1
  318. package/dist/rate-limit/index.d.ts +0 -115
  319. package/dist/rate-limit/index.js +0 -3
  320. package/dist/rate-limit/index.js.map +0 -1
  321. package/dist/reconciler/index.d.ts +0 -193
  322. package/dist/reconciler/index.js +0 -164
  323. package/dist/reconciler/index.js.map +0 -1
  324. package/dist/recorder/index.js +0 -3
  325. package/dist/recorder/index.js.map +0 -1
  326. package/dist/reducer-4GNR6b8B.d.ts +0 -447
  327. package/dist/resilient-call/index.d.ts +0 -320
  328. package/dist/resilient-call/index.js +0 -14
  329. package/dist/resilient-call/index.js.map +0 -1
  330. package/dist/retry-to-success/index.d.ts +0 -109
  331. package/dist/retry-to-success/index.js +0 -37
  332. package/dist/retry-to-success/index.js.map +0 -1
  333. package/dist/run-pAcmBpah.d.ts +0 -713
  334. package/dist/runtime-types-CNLmhWif.d.ts +0 -517
  335. package/dist/saga/index.d.ts +0 -241
  336. package/dist/saga/index.js +0 -150
  337. package/dist/saga/index.js.map +0 -1
  338. package/dist/samples-B3My5oh2.d.ts +0 -59
  339. package/dist/snapshot/index.js +0 -5
  340. package/dist/snapshot/index.js.map +0 -1
  341. package/dist/subs/index.d.ts +0 -472
  342. package/dist/subs/index.js +0 -7
  343. package/dist/subs/index.js.map +0 -1
  344. package/dist/throttle/index.d.ts +0 -134
  345. package/dist/throttle/index.js +0 -3
  346. package/dist/throttle/index.js.map +0 -1
  347. package/dist/throttled-input/index.js.map +0 -1
  348. package/dist/token-refresh/index.d.ts +0 -216
  349. package/dist/token-refresh/index.js +0 -6
  350. package/dist/token-refresh/index.js.map +0 -1
  351. package/dist/trace-replay/index.js +0 -6
  352. package/dist/trace-replay/index.js.map +0 -1
  353. package/dist/with-deadline/index.d.ts +0 -197
  354. package/dist/with-deadline/index.js +0 -111
  355. package/dist/with-deadline/index.js.map +0 -1
  356. package/dist/with-resilience/index.d.ts +0 -225
  357. package/dist/with-resilience/index.js +0 -240
  358. package/dist/with-resilience/index.js.map +0 -1
  359. package/dist/with-telemetry/index.d.ts +0 -150
  360. package/dist/with-telemetry/index.js +0 -70
  361. package/dist/with-telemetry/index.js.map +0 -1
  362. package/dist/work-queue/adapter.d.ts +0 -84
  363. package/dist/work-queue/adapter.js +0 -4
  364. package/dist/work-queue/adapter.js.map +0 -1
  365. package/dist/work-queue/ops.d.ts +0 -71
  366. package/dist/work-queue/ops.js +0 -3
  367. package/dist/work-queue/ops.js.map +0 -1
  368. package/dist/workflow/index.d.ts +0 -485
  369. package/dist/workflow/index.js +0 -244
  370. package/dist/workflow/index.js.map +0 -1
  371. /package/dist/{cache → paginate}/index.js.map +0 -0
  372. /package/dist/{chart/inspect → persistence}/index.js.map +0 -0
@@ -0,0 +1,1773 @@
1
+ import { C as Cmd, j as Tagged, I as Interpret, A as AnyCmdDef, a as CmdOf, b as CmdDef, e as Settled, k as NoCtx, O as OkOf, E as ErrOf, l as MalformedResult, i as CmdValue, g as PortEmitter, m as Requirements, n as TaggedError, M as Machine } from './core-CTzMJ82M.js';
2
+ import { a as MonitoredRunState, R as RunFailure, M as MonitoredRunCmd } from './index-NjrT3fL2.js';
3
+ import { R as RunCmd, S as SucceedMsg, F as FailMsg, a as ResilientState, M as MsgType, b as MsgTypeValue } from './index-B5BZ-_cT.js';
4
+ import { D as DeadlineExceeded, a as DeadlineSub } from './index-q0hXFeZ0.js';
5
+ import { F as FanOutState } from './index-6A7dB8f6.js';
6
+ import { RetryPolicy, AnyRetryPolicy } from './retry-backoff/index.js';
7
+ import { Result } from 'better-result';
8
+ import { z } from 'zod';
9
+
10
+ /**
11
+ * @packageDocumentation
12
+ * internal/llm-call — `resilient-call` + structured-output parse + a typed
13
+ * failure variant, around a purpose-discriminated LLM invocation. Internal
14
+ * since #49 — not published on any subpath; `@demlik/tea/agent` re-exports
15
+ * the types a consumer meets.
16
+ *
17
+ * This is the ~60-line `call_llm` handler from the audit-agent seed
18
+ * (`interpret.ts` / `effects.ts`) collapsed into the uniform L2 knob: a config
19
+ * object, the resilient-call slice it inherits, and one interpret handler that
20
+ * assembles messages, binds the structured-output schema for the call's
21
+ * `purpose`, invokes the model (retry composed from `../resilient-call`, NOT
22
+ * reinvented), parses the output, and RETURNS the enriched resilient settle Msg
23
+ * (`resilient_ok` / `resilient_err`) so it re-enters the host reducer and drives
24
+ * the inherited succeed/fail → backoff → onTimer loop.
25
+ *
26
+ * ## What it adds over `../resilient-call`
27
+ *
28
+ * - **Two DI ports** (the seed's two seams):
29
+ * 1. `model` — either `async (messages) => answer`, the plain-function
30
+ * port (#58), or `(modelId) => LLM`, the model factory that binds the
31
+ * structured-output schema itself. Tests pass a fake so the handler
32
+ * runs end-to-end without touching a real provider; the production
33
+ * worker wires `createChatModel(env, …)`.
34
+ * 2. `loadMessages: Loader` — the SDK / message loader. The seed lazy-
35
+ * imports `@langchain/core/messages` (a top-level `import type` blows
36
+ * up the workers test runner); the loader keeps that import lazy and
37
+ * stubbable. It produces the `BaseMessage[]` for a given call.
38
+ * - **Structured-output parse** — each `purpose` maps to a `Schema` in
39
+ * `config.schemas`. The handler binds `model.withStructuredOutput(schema)`
40
+ * so the invoke resolves to a typed object; a `Schema.parse` that throws
41
+ * becomes a `resilient_err` carrying an `LlmErr` (a parse failure is a
42
+ * failure, not a stall — "errors are data"). `withStructuredOutput` is the
43
+ * seed's brain-only path; the fake model in tests returns the typed object
44
+ * directly.
45
+ * - **A typed failure variant** — every failure (model throw, timeout-via-
46
+ * retry-exhaustion, schema parse) is surfaced as the `LlmErr` carried on the
47
+ * enriched `resilient_err` settle Msg, tagged with the `purpose` so the
48
+ * consumer's reducer routes per-stage. The seed dispatched
49
+ * `llm_failed{purpose}`; the consumer rebuilds that shape in its reducer arm
50
+ * from `m.error: LlmErr`.
51
+ *
52
+ * ## Inheriting resilient-call by composition (not reinvention)
53
+ *
54
+ * The retry / backoff lives in `../resilient-call`: `createLlmCall` builds a
55
+ * `createResilientCall` knob over the model-invoke port and DELEGATES `init`,
56
+ * `attempt`, `succeed`, `fail`, `onTimer`, `subs` to it verbatim — the slice is
57
+ * literally resilient-call's slice (the spec's "retry lives here"). There is no
58
+ * second backoff implementation here. The handler runs the invoke through the
59
+ * resilient-call handler so a transient model failure backs off exactly as a
60
+ * resilient HTTP call would; the `purpose`-branch + structured parse wrap the
61
+ * port the resilient handler drives.
62
+ *
63
+ * ## The two non-negotiables (canon, inherited)
64
+ *
65
+ * - **Durable** — the slice is resilient-call's plain-data slice (a Model
66
+ * field). Input carried on the `resilient_run` Cmd is the plain
67
+ * `LlmCall` request (purpose + modelId + payload) — no closures.
68
+ * - **Replayable** — every transition is a resilient-call verb; the handler
69
+ * is the only impurity, and the one clock read is `Date.now()` at the
70
+ * effect boundary (inside the handler), exactly as the seed stamped its
71
+ * `llm_responded` / `llm_failed` Msgs.
72
+ *
73
+ * ## Typical wiring
74
+ *
75
+ * const llm = createLlmCall<MyPurpose, MyOutputs>({
76
+ * model: (id) => createChatModel(env, id),
77
+ * schemas: { plan: planSchema, report: reportSchema },
78
+ * retry: defaultRetryPolicy,
79
+ * loadMessages: defaultMessagesLoader,
80
+ * });
81
+ *
82
+ * // in the machine:
83
+ * init: () => [{ resilience: llm.init() }, []],
84
+ * update: {
85
+ * call_llm: (s, m) => lift(s, llm.attempt(s.resilience, m.input, m.at)),
86
+ * // `resilient_ok` / `resilient_err` RE-ENTER from `handlers` (the settle
87
+ * // Msg the interpret handler returns). Run the inherited verb FIRST so the
88
+ * // succeed/fail → backoff → onTimer loop advances, THEN fold the enriched
89
+ * // payload (`m.result: LlmOk` / `m.error: LlmErr`) into the host's own
90
+ * // state — the enrichment lives in the reducer arm, not the handler.
91
+ * resilient_ok: (s, m) => {
92
+ * const [slice, cmds] = llm.succeed(s.resilience, m.key, m);
93
+ * return [{ ...s, resilience: slice, output: m.result.output }, cmds];
94
+ * },
95
+ * resilient_err: (s, m) => {
96
+ * const [slice, cmds] = llm.fail(s.resilience, m.key, m);
97
+ * return [{ ...s, resilience: slice, failure: m.error }, cmds];
98
+ * },
99
+ * deadline_exceeded: (s, m) => lift(s, llm.onTimer(s.resilience, m)),
100
+ * },
101
+ * subscriptions: (s) => llm.subs(s.resilience),
102
+ * subscribe: { deadline: subscribeDeadline },
103
+ * interpret: llm.handlers(),
104
+ */
105
+
106
+ /**
107
+ * The minimal structured-output schema contract: `parse(unknown) => T`, the
108
+ * zod-style call the handler uses to validate the model's output before it
109
+ * settles `resilient_ok`. A throwing `parse` (the zod contract on invalid
110
+ * input) propagates out of `invokeOne` and is caught by the resilient handler,
111
+ * which settles `resilient_err` (enriched to `LlmErr`) — a parse failure is a
112
+ * failure, never a silent pass. Structural so a real `z.ZodType<T>` satisfies
113
+ * it without an import.
114
+ */
115
+ interface Schema<T> {
116
+ /** Validate + narrow `value` to `T`, or throw on mismatch (the zod contract). */
117
+ parse(value: unknown): T;
118
+ }
119
+ /**
120
+ * The minimal chat-model contract every model the handler talks to must
121
+ * satisfy — the seed's `InjectableChatModel`, trimmed to the one operation
122
+ * llm-call drives for brain-only stages:
123
+ *
124
+ * `withStructuredOutput(schema)` → a runnable whose `invoke(messages)`
125
+ * resolves to a typed object matching `schema`.
126
+ *
127
+ * `BaseChatModel` from `@langchain/core` is the runtime type; this surface
128
+ * names only what llm-call calls so a test fake can ignore the rest. Generic
129
+ * over the message shape `Msg` so a consumer's loader and model agree on it
130
+ * without llm-call inspecting messages.
131
+ */
132
+ interface Llm<Msg> {
133
+ withStructuredOutput<T>(schema: Schema<T>): {
134
+ invoke(messages: readonly Msg[]): Promise<T>;
135
+ };
136
+ }
137
+ /**
138
+ * Build the `Msg[]` the handler hands to the bound model for a given call. The
139
+ * SDK / message-assembly seam — the seed's `buildBaseMessages` + the lazy
140
+ * `loadMessages` loader rolled into one injected port. Async because the seed
141
+ * lazy-imports the SDK (a top-level `import type` of the langchain messages
142
+ * package explodes the workers test runner). Receives the full `LlmCall` so it
143
+ * can branch on `purpose` exactly as the seed's `buildBaseMessages` did.
144
+ */
145
+ type MessageLoader<P extends string, Msg> = (call: LlmCall<P>) => Promise<readonly Msg[]>;
146
+ /**
147
+ * The model factory — the first DI port. `(modelId) => Llm`. Tests pass a fake
148
+ * builder; production wires `createChatModel(env, getModelConfig(id))`. `null`
149
+ * means "the host's default model" (the seed's `string | null`).
150
+ */
151
+ type ModelFactory<Msg> = (modelId: string | null) => Llm<Msg>;
152
+ /**
153
+ * The plain-function model port — the common path. One async function
154
+ * from the assembled messages to the model's answer; the handler validates the
155
+ * answer through the purpose's `Schema` exactly as it re-validates the
156
+ * structured-output path, so a malformed answer is a `resilient_err`, never a
157
+ * corrupt success. `ModelFactory` → `withStructuredOutput(schema).invoke(...)`
158
+ * stays the advanced form for a model that binds the schema itself.
159
+ *
160
+ * `T` is the answer type the schema narrows to — for the agent, an `AgentTurn`.
161
+ */
162
+ type PlainModel<Msg, T = unknown> = (messages: readonly Msg[]) => Promise<T>;
163
+ /**
164
+ * Either model port. A bare `async` function is read as a `PlainModel` (see
165
+ * {@link asModelFactory}); a sync function is the factory.
166
+ */
167
+ type ModelPort<Msg, T = unknown> = ModelFactory<Msg> | PlainModel<Msg, T>;
168
+ /**
169
+ * Lift a plain-function model into the `ModelFactory` port. The factory ignores
170
+ * `modelId` (the function IS the model) and its `Llm` runs the bound schema over
171
+ * the function's answer, so both ports meet the handler as one shape.
172
+ *
173
+ * Reach for this explicitly when the function is not declared `async` — a sync
174
+ * function that returns a promise (`(m) => client.chat(m)`) carries no runtime
175
+ * mark that tells it apart from a factory. Passed bare, `asModelFactory`
176
+ * refuses it on the first call with an `LlmErr` whose reason is
177
+ * {@link PLAIN_MODEL_MISROUTE_REASON}.
178
+ */
179
+ declare function plainModel<Msg, T>(fn: PlainModel<Msg, T>): ModelFactory<Msg>;
180
+ /**
181
+ * The reason an `LlmErr` carries when a sync promise-returning function was
182
+ * passed as `model` bare — the one runtime shape neither port can own.
183
+ */
184
+ declare const PLAIN_MODEL_MISROUTE_REASON: string;
185
+ /**
186
+ * One LLM call request — the resilient-call `input` for this module, carried on
187
+ * the `resilient_run` Cmd as plain data — no closures, so it survives
188
+ * persistence and replay. Purpose-discriminated: a `purpose` selecting the
189
+ * schema + prompt assembly, the `model` id, and the opaque per-purpose
190
+ * `payload` the loader consumes.
191
+ *
192
+ * `key` defaults to `purpose` when the consumer calls `attempt(s, purpose, …)`,
193
+ * so one in-flight call per purpose is tracked under the resilient-call slice —
194
+ * the common single-call-per-stage shape. A consumer that fans out many calls
195
+ * of one purpose passes a distinct `key`.
196
+ */
197
+ interface LlmCall<P extends string> {
198
+ /** The stage / schema selector — drives both `schemas[purpose]` and message assembly. */
199
+ readonly purpose: P;
200
+ /** The model id to invoke; `null` = the host's default model. */
201
+ readonly model: string | null;
202
+ /** The per-purpose prompt payload the `MessageLoader` consumes. Opaque to the knob. */
203
+ readonly payload: unknown;
204
+ }
205
+ /** The parsed, typed success carried on the `resilient_ok` settle Msg, tagged with its purpose. */
206
+ interface LlmOk<P extends string, O extends Record<P, unknown>> {
207
+ readonly key: string;
208
+ readonly purpose: P;
209
+ readonly output: O[P];
210
+ }
211
+ /** The typed failure variant — every failure path surfaces this, tagged by purpose. */
212
+ interface LlmErr<P extends string> {
213
+ readonly key: string;
214
+ readonly purpose: P;
215
+ /** A human-readable cause (model throw, retry-exhaustion, or schema parse). */
216
+ readonly reason: string;
217
+ /** The original error, carried untouched for the consumer to inspect. */
218
+ readonly error: unknown;
219
+ }
220
+ /**
221
+ * The settle Msgs llm-call's handler RETURNS from `interpret` so the substrate
222
+ * enqueues them as follow-up Msgs (re-entry) into the host reducer — exactly as
223
+ * `../resilient-call` does. They are the resilient-call settle Msgs with the
224
+ * payloads ENRICHED to llm-call's typed variants: `result` is the parsed,
225
+ * purpose-tagged `LlmOk`; `error` is the typed `LlmErr` (purpose + reason +
226
+ * raw). The host wires `resilient_ok` → `succeed` and `resilient_err` → `fail`
227
+ * reducer arms (the doc-comment wiring), and folds the enriched payload into its
228
+ * own state there — llm-call never forces a Msg vocabulary on the host, and the
229
+ * settle Msg drives the inherited succeed/fail → backoff → onTimer loop instead
230
+ * of bypassing it.
231
+ */
232
+ type LlmSucceedMsg<P extends string, O extends Record<P, unknown>> = SucceedMsg<LlmOk<P, O>>;
233
+ /**
234
+ * The FAILURE settle Msg (`resilient_err`) — resilient-call's `FailMsg` with its
235
+ * `error: unknown` narrowed to the typed `LlmErr`, so the host reducer reads the
236
+ * purpose, the reason and the raw payload without a cast.
237
+ */
238
+ type LlmFailMsg<P extends string> = Omit<FailMsg, "error"> & {
239
+ readonly error: LlmErr<P>;
240
+ };
241
+ /** The retry / deadline timer Msg — `DeadlineExceeded`, inherited from resilient-call. */
242
+ type LlmTimerMsg = DeadlineExceeded;
243
+ /**
244
+ * The ports the LEGACY detached `handlers(ports)` form takes. Two outbound Msg
245
+ * builders the handler hands the typed Ok / Err; the consumer returns its own
246
+ * Msg (or `undefined`). KEPT only for `../agent`, which still inherits the
247
+ * detached shape; that path does NOT drive the retry loop (it dispatches the
248
+ * consumer's Msg directly and never re-enters the resilient settle Msg). New
249
+ * consumers use the no-arg `handlers()` form, which RETURNS the settle Msg for
250
+ * re-entry and drives the inherited succeed/fail → backoff → onTimer loop.
251
+ * `../agent` carries the same retry-loop gap and is fixed separately.
252
+ *
253
+ * The builders return `M | undefined` — `undefined` is the "dispatch nothing"
254
+ * sentinel the detached form checks (`!== undefined`), spelled as `undefined`
255
+ * rather than `void` so the union is unambiguous (a `void` member of a union is
256
+ * confusing and reads as "may return anything").
257
+ */
258
+ interface LlmCallPorts<P extends string, O extends Record<P, unknown>, M> {
259
+ /** Build the Msg dispatched on a parsed success. Return `undefined` to dispatch nothing. */
260
+ readonly onOk: (ok: LlmOk<P, O>) => M | undefined;
261
+ /** Build the Msg dispatched on any failure (throw / retry-exhausted / parse). */
262
+ readonly onErr: (err: LlmErr<P>) => M | undefined;
263
+ }
264
+ /**
265
+ * The effect Cmd this module emits: run the LLM call for `key` with `input`. The
266
+ * `input` is the plain `LlmCall` request — the handler reads `purpose` /
267
+ * `model` / `payload` off it (invariant 3: Cmds are data).
268
+ *
269
+ * It is `../resilient-call`'s `RunCmd` specialized to the `LlmCall` input — NOT a
270
+ * re-declared shape — so the resilient verbs' return tuples (`[State, RunCmd[]]`)
271
+ * are this exact type and thread through `attempt` / `succeed` / `fail` /
272
+ * `onTimer` with no cast.
273
+ */
274
+ type LlmRunCmd<P extends string> = RunCmd<LlmCall<P>>;
275
+
276
+ /**
277
+ * @demlik/tea/agent — the domain data model: the tool + turn shapes the consumer
278
+ * supplies, the agentic-stage conversation, the `createAgent` config object, and
279
+ * the durable agent slice + its lifecycle status.
280
+ *
281
+ * Everything here is plain data (durable + replayable): the composed wrappers'
282
+ * slices, the conversation, and the config are all JSON-serializable. The
283
+ * compaction vocabulary lives in `./compaction`; this module imports its
284
+ * types where the slice / config reference them. The reducer core (the verbs +
285
+ * the wired `toMachine`) lives in `./index`.
286
+ */
287
+
288
+ /**
289
+ * One tool the model asked to call this turn. Plain data so it round-trips through the
290
+ * durable fan-out ledger: a stable `callId` (the fan-out identity), the tool
291
+ * `name`, and the opaque `args` the consumer's own interpret reads.
292
+ */
293
+ interface ToolCall {
294
+ /** Stable id the model minted; the fan-out item identity (`idOf`). */
295
+ readonly callId: string;
296
+ /** The tool to invoke. The consumer's `toolOf` maps it to an effect Cmd. */
297
+ readonly name: string;
298
+ /** Args the model emitted, opaque to the agent. */
299
+ readonly args: Readonly<Record<string, unknown>>;
300
+ }
301
+ /**
302
+ * One model turn: the narration `content` the model produced and the
303
+ * `toolCalls` it asked us to run. An empty
304
+ * `toolCalls` means the model is done with this stage (advance the pipeline).
305
+ * This is the parsed output of a brain call; the consumer's schema produces it.
306
+ *
307
+ * `provider` is the opaque passthrough slot (#93): whatever the adapter hands
308
+ * back beside `content` / `toolCalls` that its provider expects echoed
309
+ * verbatim on the next turn — Anthropic's signed `thinking` blocks,
310
+ * `server_tool_use`, OpenAI reasoning items. tea stores it on the turn and
311
+ * returns it unchanged on the `assistant` `AgentMessage` that replays this
312
+ * turn; it never reads, validates or transforms it. The adapter owns its shape,
313
+ * which must be JSON-serializable like the rest of the Model. A compaction fold
314
+ * (ADR 0004) summarises turns into text, so it drops the slot with the turns it
315
+ * summarises. Optional and additive: a persisted turn without it still parses.
316
+ */
317
+ interface AgentTurn {
318
+ /** Free-text narration the model produced this turn (folded into the conversation). */
319
+ readonly content: string;
320
+ /** The tools the model asked us to run; empty = stage done. */
321
+ readonly toolCalls: readonly ToolCall[];
322
+ /** Provider-opaque blocks to echo back verbatim next turn. tea never reads it. */
323
+ readonly provider?: unknown;
324
+ }
325
+ /**
326
+ * One partial piece of a turn the model is still producing — a token delta, as
327
+ * the provider emitted it.
328
+ *
329
+ * A chunk is NOT state. It never reaches the Model, the journal or the Store:
330
+ * by the time a turn is durable it has settled, and a delta that has not settled
331
+ * is not an outcome ADR 0011 could fold. So `TurnChunk` carries only what a
332
+ * progress surface renders — the text so far — and carries no identity, because
333
+ * an identity would invite someone to store it.
334
+ */
335
+ interface TurnChunk {
336
+ /** The text delta this chunk adds to the turn's `content`. */
337
+ readonly text: string;
338
+ }
339
+ /**
340
+ * The side channel a {@link StreamingModel} writes its deltas to — the second
341
+ * argument of the streaming port. One sink, called synchronously by the adapter
342
+ * as the provider yields; a throw from it is contained by the caller that
343
+ * supplied it, so a progress surface's defect cannot fail a model call.
344
+ */
345
+ interface ModelStream {
346
+ /** Hand one delta to whoever is watching this run. */
347
+ readonly onChunk: (chunk: TurnChunk) => void;
348
+ }
349
+ /**
350
+ * The streaming model port — `(messages, { onChunk }) => Promise<AgentTurn>`.
351
+ *
352
+ * The second, OPTIONAL shape of the brain. It differs from
353
+ * `PlainModel<Msg, T>` in one thing: it is handed a {@link ModelStream} it may
354
+ * write deltas to while the turn is in flight. What it RESOLVES is the same
355
+ * settled turn the plain port resolves, and that turn is the only thing the
356
+ * reducer ever sees — the deltas are a side channel that ends at the caller's
357
+ * listener.
358
+ *
359
+ * A `PlainModel` is assignable here (a function may declare fewer parameters
360
+ * than its type), which is what lets one config field accept either shape.
361
+ * `isStreamingModel` tells them apart at runtime so a plain model is still
362
+ * invoked with exactly one argument, as it always was.
363
+ */
364
+ type StreamingModel<Msg, T = unknown> = (messages: readonly Msg[], stream: ModelStream) => Promise<T>;
365
+ /**
366
+ * Whether a model port wants the {@link ModelStream} — read off its declared
367
+ * arity, which is the mark JavaScript already carries. No config flag, and no
368
+ * marker property for a consumer to forget: a brain written
369
+ * `async (messages, { onChunk }) => …` streams, and one written
370
+ * `async (messages) => …` does not.
371
+ *
372
+ * The cost of the arity read is the cost of every arity read — a model that
373
+ * declares a parameter it ignores, or takes `...args`, reads as the other shape.
374
+ * Both misreads are benign: a `...args` model is handed no stream and emits no
375
+ * chunks; a model with an unused second parameter is handed a stream it never
376
+ * writes to. Neither can change the settled turn. PURE.
377
+ */
378
+ declare function isStreamingModel(model: (...args: never[]) => unknown): boolean;
379
+ /**
380
+ * Narrow an unknown to an `AgentTurn` — the runtime witness for tea's own
381
+ * structured-output type. A consumer's brain schema parses the model's output
382
+ * into an `AgentTurn` (the agentic purpose's output); rather than every consumer
383
+ * hand-rolling this guard + a `Schema<AgentTurn>` for a type the agent OWNS, the
384
+ * agent exports both. Checks the load-bearing fields: `content` is a string and
385
+ * `toolCalls` is an array of `ToolCall` (each element guarded — the narrow is a
386
+ * real parse of the boundary, not a shallow `Array.isArray`). `provider` is
387
+ * opaque, so its presence or absence is not a fact the guard reads. PURE —
388
+ * allocates no Error.
389
+ */
390
+ declare function isAgentTurn(value: unknown): value is AgentTurn;
391
+ /**
392
+ * The `Schema<AgentTurn>` for tea's own turn type — the parse target a brain
393
+ * call binds when the agentic purpose's output is a bare `AgentTurn` (the common
394
+ * case). Throws on a non-`AgentTurn` (the zod-style `parse` contract the
395
+ * llm-call handler relies on). Deletes the consumer's hand-rolled
396
+ * `auditSchema` / `isAgentTurn` pair.
397
+ *
398
+ * A consumer whose turn type EXTENDS `AgentTurn` with extra fields still writes
399
+ * its own schema (it must validate the extra fields); this is for the plain case.
400
+ */
401
+ declare const agentTurnSchema: Schema<AgentTurn>;
402
+ /**
403
+ * One settled tool outcome the consumer routes back into the loop.
404
+ * `ok` carries the result the consumer's interpret produced;
405
+ * `error` carries the failure as data — see {@link ToolFailure}.
406
+ */
407
+ type ToolOutcome<R> = {
408
+ readonly kind: "ok";
409
+ readonly result: R;
410
+ } | ToolFailure;
411
+ /**
412
+ * A settled tool failure as the conversation keeps it: the `{ _tag, …payload }`
413
+ * the tool failed with, spread beside the `reason` string the model reads.
414
+ *
415
+ * Both halves are load-bearing and neither replaces the other. `reason` is the
416
+ * model's channel — `toolErrorReason`'s rendering, which is what the next brain
417
+ * call carries; `_tag` and the payload are the program's, so host code can
418
+ * branch on the failure instead of parsing prose out of `reason` (#115). A
419
+ * payload field never shadows `kind` or `reason`: the router writes those last.
420
+ *
421
+ * `_tag` is OPTIONAL here for one reason only — a record persisted by 0.12.x or
422
+ * earlier was written before the tag was kept, so a Store handing one back has
423
+ * a failure with no tag, and a required field would be a lie about durable
424
+ * state. Every failure THIS version mints carries one. For the exhaustive
425
+ * per-tag union, take `onToolError`'s argument, which is typed from the tools
426
+ * themselves ({@link ToolFailureOf}).
427
+ */
428
+ interface ToolFailure {
429
+ readonly kind: "error";
430
+ /** The model-facing rendering — `toolErrorReason(error)`. */
431
+ readonly reason: string;
432
+ /** The failure's tag; absent only on a record persisted before 0.13. */
433
+ readonly _tag?: string;
434
+ }
435
+ /**
436
+ * The failure arm typed against a KNOWN tag union — `{ kind, reason }` beside
437
+ * each arm of `E`, distributed, so a `switch` on `_tag` narrows the payload and
438
+ * an unhandled tag is a compile error. `ToolFailure` is its erased form.
439
+ */
440
+ type TaggedFailure<E extends Tagged> = E extends unknown ? {
441
+ readonly kind: "error";
442
+ readonly reason: string;
443
+ } & E : never;
444
+ /**
445
+ * The per-tool resilience knob — a timeout, a retry ladder, or both, declared on
446
+ * the `tool()` spec and executed by the agent's reducer through
447
+ * `../internal/resilience/resilient-call`.
448
+ *
449
+ * Both fields are optional and a tool that names neither behaves exactly as it
450
+ * did before this knob existed: no slice entry is minted, no timer is armed, and
451
+ * its settle path is the plain fan-out one. The ladder lives in the Model, so a
452
+ * process killed between two attempts resumes at the attempt it was on rather
453
+ * than restarting the run — the property a `Promise.race` or a `for` loop inside
454
+ * the handler cannot have, because those live inside the effect boundary.
455
+ */
456
+ interface ToolResilience {
457
+ /**
458
+ * The budget one tool CALL gets, in ms, measured from the first attempt and
459
+ * NOT restarted by a retry — the overall cap `resilient-call`'s deadline brick
460
+ * enforces. When it elapses the call settles as a `ToolOutcome` error
461
+ * carrying `_tag: "timeout"` beside its `reason`, and the loop moves on, whatever the
462
+ * in-flight attempt does next — its late settle arrives for a call nothing is
463
+ * waiting on and folds nothing, so a slow tool costs the budget and not the
464
+ * turn.
465
+ *
466
+ * What it does NOT do is cancel the handler: a promise cannot be cancelled in
467
+ * JavaScript, so the attempt runs to its own end, and `run`'s teardown still
468
+ * drains it. A handler that resolves LATE is bounded by this knob; a handler
469
+ * that never resolves at all holds the runtime's shutdown regardless, and
470
+ * wants an `AbortSignal` in the handler rather than a budget out here.
471
+ *
472
+ * Omit → the call has no cap and ends only when its handler settles.
473
+ */
474
+ readonly timeoutMs?: number;
475
+ /**
476
+ * The backoff ladder a FAILED attempt climbs — the same
477
+ * `BackoffCurve & RetryBudget` shape `AgentConfigCore.retry` takes for the
478
+ * brain call. Each failure is recorded in the Model and the next attempt is
479
+ * armed as a timer Sub, so the wait is durable and the attempt count survives
480
+ * a reload. When the budget is spent the call settles as a `ToolOutcome` error
481
+ * carrying `_tag: "retry_exhausted"` beside its `reason`, plus `attempts` and
482
+ * `last` as fields — see {@link ToolRetryExhausted}.
483
+ *
484
+ * Omit → the first failure is the outcome, exactly as before.
485
+ */
486
+ readonly retry?: AnyRetryPolicy;
487
+ }
488
+ /** The reason-tag a timed-out tool call settles under. */
489
+ declare const TOOL_TIMEOUT_TAG = "timeout";
490
+ /** The reason-tag a tool call that spent its retry budget settles under. */
491
+ declare const TOOL_RETRY_EXHAUSTED_TAG = "retry_exhausted";
492
+ /** A call that spent its `timeoutMs` budget — {@link ToolResilience.timeoutMs}. */
493
+ interface ToolTimedOut {
494
+ readonly _tag: typeof TOOL_TIMEOUT_TAG;
495
+ }
496
+ /** A call that spent its retry budget — {@link ToolResilience.retry}. */
497
+ interface ToolRetryExhausted {
498
+ readonly _tag: typeof TOOL_RETRY_EXHAUSTED_TAG;
499
+ /** How many attempts the ladder burned, the failed last one included. */
500
+ readonly attempts: number;
501
+ /** The last attempt's own `reason`, so the real failure is not buried. */
502
+ readonly last: string;
503
+ }
504
+ /**
505
+ * The two failures the resilience ladder itself authors — `timeout` and
506
+ * `retry_exhausted`. They are in every tool's
507
+ * error union rather than only a policied tool's: the policy is a `tool()` spec
508
+ * field a maintainer can add later, and a union that narrowed with it would turn
509
+ * adding a `timeoutMs` into a silent behaviour change at every `onToolError`
510
+ * that had switched exhaustively without them.
511
+ */
512
+ type ToolResilienceError = ToolTimedOut | ToolRetryExhausted;
513
+ /**
514
+ * A folded tool record kept on the conversation once a tool settles — the
515
+ * call + its outcome, in settle order. The consumer's message loader reads
516
+ * these (plus `turns`) to assemble the next brain call's prompt.
517
+ *
518
+ * `turn` is the `turnCount` at the time the record was folded — the association
519
+ * compaction needs to drop the RIGHT records (#85 / design A1). When compaction
520
+ * folds `turns[0..N]` into a summary, it must also drop every tool record that
521
+ * belonged to those turns; without a turn stamp on the record there is no honest
522
+ * way to know which. It is the round-trip index, not a wall clock — small and
523
+ * JSON-stable, preserving the durability invariant.
524
+ */
525
+ interface ToolRecord<R> {
526
+ readonly call: ToolCall;
527
+ readonly outcome: ToolOutcome<R>;
528
+ /** The `turnCount` at fold time — which round-trip this record belongs to (#85, A1). */
529
+ readonly turn: number;
530
+ }
531
+ /**
532
+ * Whether the agentic stage is waiting on the model (`llm`), on tools
533
+ * (`tools`), or on a compaction round-trip (`compacting`). The in-flight
534
+ * fan-out batch exists ONLY in the `tools` variant — "awaiting llm with tools
535
+ * pending" is structurally impossible (TEA canon §2.6 / Rule 1
536
+ * impossible-states pin). Discriminated on `kind`.
537
+ *
538
+ * `compacting` is the honest state for the dedicated compaction round-trip
539
+ * (design B1): the transcript grew, the policy asked to fold `folding` of the
540
+ * OLDEST turns, and the summarize call is in flight INSTEAD of the next brain
541
+ * call. `folding` is the count `planCompaction` returned — the fold-back
542
+ * (`compact_ok`) drops exactly that many head turns + their tool records.
543
+ */
544
+ type Awaiting = {
545
+ readonly kind: "llm";
546
+ } | {
547
+ readonly kind: "tools";
548
+ readonly batchTurn: number;
549
+ } | {
550
+ readonly kind: "compacting";
551
+ readonly folding: number;
552
+ };
553
+ /**
554
+ * The agentic-stage conversation — durable inside the agent slice so an
555
+ * eviction mid-loop resumes the exact turn. The model turns + folded tool
556
+ * records are the consumer's prompt source (via the llm-call message loader);
557
+ * `turnCount` drives the livelock guard; `awaiting` carries the ONE outstanding
558
+ * effect for the agentic stage.
559
+ *
560
+ * Generic over the consumer's tool-result type `R` (what `toolOk` carries).
561
+ */
562
+ interface Conversation<R> {
563
+ /** Model turns this stage has produced, in order. */
564
+ readonly turns: readonly AgentTurn[];
565
+ /** Settled tool records, in settle order — the model sees these next turn. */
566
+ readonly toolRecords: readonly ToolRecord<R>[];
567
+ /** Monotonic round-trip count; the livelock guard compares it to `maxTurns`. */
568
+ readonly turnCount: number;
569
+ /** What the loop is waiting for next. */
570
+ readonly awaiting: Awaiting;
571
+ }
572
+ /**
573
+ * The snapshotting discriminant. Checkpointing is either OFF — in which
574
+ * case `snapshotEvery` is structurally absent and the monitored-run slice never
575
+ * emits a `snapshot_write` Cmd — or ON, in which case `snapshotEvery` is a
576
+ * `number`. A `{ snapshotEvery?: never }` member (rather than a bare optional)
577
+ * makes the OFF case load-bearing: it forbids passing `snapshotEvery` at all, so
578
+ * `toMachine` can config-derive whether the `snapshot_write` interpret handler
579
+ * is REQUIRED (ON) or FORBIDDEN (OFF) instead of defaulting it to a silent
580
+ * no-op.
581
+ *
582
+ * This is what kills the type lie: with checkpointing off, `snapshot_write` is
583
+ * absent from the consumer's interpret contract entirely — never a
584
+ * `snapshot_write: async () => undefined` ceremony that masks a real wiring bug.
585
+ */
586
+ type AgentSnapshotConfig = {
587
+ readonly snapshotEvery?: never;
588
+ } | {
589
+ readonly snapshotEvery: number;
590
+ };
591
+ /**
592
+ * The core (non-snapshot, non-compaction) agent configuration. The full `AgentConfig`
593
+ * intersects this with the `AgentSnapshotConfig` + `AgentCompactionConfig`
594
+ * discriminants — see those types for why the cadence / policy are discriminated
595
+ * unions rather than bare optionals.
596
+ *
597
+ * Type parameters:
598
+ * - `Stage` — the consumer's pipeline stage id (any JSON value).
599
+ * - `P` — the brain-call purpose union (`"plan" | "act" | ...`).
600
+ * - `O` — the purpose→output map. Every purpose drives the agentic loop,
601
+ * so each output is pinned to `AgentTurn` (or a subtype) by the
602
+ * `O extends Record<P, AgentTurn>` bound — that is what the loop
603
+ * folds. An `Outputs` whose purpose output is NOT an `AgentTurn`
604
+ * fails to compile here; the rule lives in the type, not a cast.
605
+ * - `R` — the consumer's tool-result type (what `toolOk` carries).
606
+ * - `TC` — the consumer's per-tool effect Cmd, the discriminated variant
607
+ * `toolOf` produces. Kept PRECISE (a closed Cmd variant, not the
608
+ * open `Cmd`) so `AgentCmd<P, TC>` stays a closed discriminated
609
+ * union and the wired machine's interpret merge type-checks per
610
+ * key — the brain handler maps to `resilient_run`, the tool one to
611
+ * `TC["type"]` — with no laundering cast. Defaults to `Cmd` for
612
+ * the consumer that does not care to name its tool Cmd.
613
+ * - `Msg` — the model's message shape (threaded through the llm-call loader).
614
+ */
615
+ interface AgentConfigCore<Stage, P extends string, O extends Record<P, AgentTurn>, R, TC extends Cmd = Cmd, Msg = unknown> {
616
+ /** The ordered stages. Omit / empty → a single-shot run (one agentic stage). */
617
+ readonly stages?: readonly Stage[];
618
+ /** No-progress watchdog budget, in ms. Omit → no watchdog. */
619
+ readonly deadlineMs?: number;
620
+ /**
621
+ * DI port — the brain. `async (messages) => turn` is the common path:
622
+ * the returned turn is validated through the purpose's schema
623
+ * (`agentTurnSchema` for the plain case), so a malformed turn is the run's
624
+ * `llm` failure, not a throw. `(modelId) => Llm` is the advanced form for a
625
+ * model that binds the structured-output schema itself.
626
+ */
627
+ readonly model: ModelPort<Msg, O[P]>;
628
+ /**
629
+ * The system prompt, stored ON THE MODEL at `init` (`AgentState.instructions`)
630
+ * rather than closed over — so a replay reproduces the exact prompt that ran,
631
+ * a rehydrated run keeps the prompt it started with, and a compaction fold
632
+ * (which touches only the conversation) can never lose it (ADR 0004). It
633
+ * reaches the brain call through `payloadOf`'s third argument. Omit → `null`.
634
+ */
635
+ readonly instructions?: string;
636
+ /** One structured-output schema per purpose; the parse target per brain call. */
637
+ readonly schemas: {
638
+ readonly [K in P]: Schema<O[K]>;
639
+ };
640
+ /** Backoff policy for brain calls, composed into `../llm-call`. Omit → no backoff. */
641
+ readonly retry?: RetryPolicy;
642
+ /** DI port — the SDK / message loader. Omit → brain calls invoke with `[]`. */
643
+ readonly loadMessages?: MessageLoader<P, Msg>;
644
+ /** Map one tool call to the effect Cmd the consumer's interpret performs. */
645
+ readonly toolOf: (call: ToolCall) => TC;
646
+ /**
647
+ * The per-tool timeout / retry knob for a call, read once per launch. `null`
648
+ * (or an omitted seam) → the tool runs bare and its settle path is the plain
649
+ * fan-out one, byte for byte what it was before the knob existed.
650
+ *
651
+ * This is the seam a `toolRouter` fills from the `tool()` specs
652
+ * (`router.resilienceOf`), which is how `defineAgent` grows the knob without
653
+ * growing a lid option: the policy is declared where the tool is. A hand-wired
654
+ * `createAgent` supplies it directly. It must be PURE and config-derived — the
655
+ * reducer calls it on the launch path.
656
+ */
657
+ readonly toolResilienceOf?: (call: ToolCall) => ToolResilience | null;
658
+ /**
659
+ * How many of ONE turn's tool calls a transition LAUNCHES at once. At the
660
+ * default `1` a turn's calls go out one at a time; raise it and up to that
661
+ * many move from `pending` to `running` in the fan-out ledger in a single
662
+ * transition, so the durable Model (and a `store`'s record of it) says what
663
+ * was launched.
664
+ *
665
+ * Above `1` those calls also OVERLAP on the clock, so a turn of two slow
666
+ * tools costs the slower rather than the sum — but only for the tool cells a
667
+ * `toolRouter` owns (the `toMachine({ tools })` path, which `defineAgent`
668
+ * takes). The overlap lives inside those cells, never in the kernel:
669
+ * `runInterpret` still interprets a transition's Cmds one after another and
670
+ * never interleaves two handlers (ADR 0018). A hand-wired `toolInterpret`
671
+ * cell is yours, so it overlaps only if you write it to.
672
+ *
673
+ * Overlapping does NOT reorder the fold. Settle Msgs are dispatched in
674
+ * Cmd-EMISSION order whichever call finishes first, so a replayed log
675
+ * reproduces the same Model — invariant 2's serializability, which the knob
676
+ * was never allowed to spend.
677
+ *
678
+ * Omit (or `1`) → serial dispatch, exactly as before.
679
+ */
680
+ readonly toolConcurrency?: number;
681
+ /**
682
+ * Which brain-call purpose a given stage runs. The agent fires
683
+ * `call_llm{ turnOf(stage) }` to drive the agentic stage's loop. The purpose's
684
+ * schema output is an `AgentTurn` — enforced by the `O extends Record<P,
685
+ * AgentTurn>` bound, not left to a doc-comment.
686
+ */
687
+ readonly turnOf: (stage: Stage | undefined) => P;
688
+ /**
689
+ * Build the per-purpose brain-call payload from the durable state: the
690
+ * stage, the conversation, and the Model's `instructions` slot. Omit → `null`.
691
+ */
692
+ readonly payloadOf?: (stage: Stage | undefined, conversation: Conversation<R>, instructions: string | null) => unknown;
693
+ /** The model id every brain call invokes. Omit → `null` (the host's default). */
694
+ readonly modelId?: string | null;
695
+ /**
696
+ * Livelock guard: bound on model round-trips within one run. On
697
+ * `turnCount >= maxTurns` the run fails `{ reason: "turn_limit" }`. Omit → no
698
+ * turn guard (the other stop conditions still bound the loop).
699
+ */
700
+ readonly maxTurns?: number;
701
+ /**
702
+ * Wall-clock guard: total milliseconds from `run.startedAt` the run may take.
703
+ * At the turn boundary, `at - run.startedAt >= maxElapsedMs` fails the run
704
+ * `{ reason: "elapsed_limit" }`. Unlike `deadlineMs` — a no-progress watchdog
705
+ * that RESTARTS on every advance — this budget never restarts, so a run that
706
+ * keeps progressing is bounded by it. Omit → no wall-clock cap.
707
+ *
708
+ * `startedAt` is durable, so a resumed run continues the ORIGINAL budget
709
+ * rather than starting a fresh one; the elapsed span a killed run spent dead
710
+ * counts against it.
711
+ */
712
+ readonly maxElapsedMs?: number;
713
+ /**
714
+ * The consumer's own stop condition, consulted at the turn boundary once the
715
+ * turn-count and wall-clock guards have passed. `true` settles the run
716
+ * `cancelled` at `at` — the same terminal an aborted `signal` reaches, so the
717
+ * transcript stands and no further model call goes out. Omit → no predicate.
718
+ *
719
+ * Where `maxTurns` and `maxElapsedMs` bound a quantity this agent counts,
720
+ * this bounds one only the caller can see (a token ledger, an external flag,
721
+ * a condition on the turns so far). It must be PURE and total over the state
722
+ * it is handed — the reducer calls it, so a replay of the same Msg log calls
723
+ * it with the same state and must get the same answer. It is config, not
724
+ * Model: a resumed run consults the predicate the config passed to THIS boot.
725
+ */
726
+ readonly stopWhen?: (state: AgentState<Stage, P, O, R>) => boolean;
727
+ /**
728
+ * The impurity-injection seam for the inherited brain-call retry jitter — the
729
+ * ONE place this otherwise-pure machine reads randomness. Pass a fixed
730
+ * `() => 0` to pin backoff (tests, replay, durability proofs). Omit →
731
+ * `Math.random`, read only at the resilient-call verb boundary.
732
+ */
733
+ readonly rng?: () => number;
734
+ }
735
+ /**
736
+ * The agent configuration — the core seams intersected with the snapshotting discriminant
737
+ * (`AgentSnapshotConfig`). Type parameters are documented on `AgentConfigCore`;
738
+ * the only addition here is that `snapshotEvery` is the discriminant that drives
739
+ * whether `toMachine` requires (or forbids) the `snapshot_write` interpret
740
+ * handler.
741
+ */
742
+ type AgentConfig<Stage, P extends string, O extends Record<P, AgentTurn>, R, TC extends Cmd = Cmd, Msg = unknown> = AgentConfigCore<Stage, P, O, R, TC, Msg> & AgentSnapshotConfig & AgentCompactionConfig<R, Msg>;
743
+ /**
744
+ * Why a run terminated as `failed`, beyond monitored-run's own reasons. The
745
+ * `turn_limit` reason is the agent's livelock guard and `elapsed_limit` its
746
+ * wall-clock one; deadline / stage failures surface through the monitored-run
747
+ * slice's own `failure`.
748
+ */
749
+ type AgentFailure = {
750
+ readonly reason: "turn_limit";
751
+ readonly at: number;
752
+ } | {
753
+ readonly reason: "elapsed_limit";
754
+ readonly at: number;
755
+ } | {
756
+ readonly reason: "llm";
757
+ readonly error: unknown;
758
+ readonly at: number;
759
+ };
760
+ /**
761
+ * The agent slice — every composed wrapper's slice plus the loop's conversation
762
+ * and the agent-specific failure annotation.
763
+ *
764
+ * - `run` — the `../monitored-run` slice (pipeline position +
765
+ * lifecycle + watchdog). The OUTER lifecycle truth.
766
+ * - `resilience` — the `../llm-call` (= resilient-call) slice (brain-call
767
+ * retry / backoff). Per-purpose retry lives here.
768
+ * - `tools` — the `../fan-out` ledger for the current turn's tools.
769
+ * - `conversation` — the agentic-stage loop state. `null` until the loop is
770
+ * entered (the consumer seeds it at the agentic stage).
771
+ * - `failure` — the agent-specific terminal annotation (turn-limit /
772
+ * llm), null otherwise. Distinct from `run.failure`.
773
+ * - `instructions` — the system prompt this run was configured with, set at
774
+ * `init` and never touched by a fold (ADR 0004).
775
+ */
776
+ interface AgentState<Stage, P extends string, O extends Record<P, unknown>, R> {
777
+ readonly run: MonitoredRunState<Stage>;
778
+ readonly resilience: ResilientState<LlmCall<P>, LlmOk<P, O>>;
779
+ readonly tools: FanOutState<ToolCall, ToolOutcome<R>>;
780
+ readonly conversation: Conversation<R> | null;
781
+ /**
782
+ * The compaction round-trip's resilient slice (#85, design B1) — a DEDICATED
783
+ * resilient-call slice for the reserved `$compact` purpose, separate from the
784
+ * brain `resilience` slice so a compaction retry/backoff never disturbs the
785
+ * brain call's breaker or retry counter. Always present (empty `calls` when no
786
+ * compaction is in flight, or when no policy is configured) so the slice stays
787
+ * a flat plain-data record — durable + replayable like every composed wrapper.
788
+ */
789
+ readonly compaction: ResilientState<LlmCall<CompactionPurpose>, LlmOk<CompactionPurpose, CompactionOutputs>>;
790
+ /**
791
+ * The per-tool timeout / retry ladders (#117) — one dedicated resilient-call
792
+ * slice PER TOOL NAME, because the policy is declared per tool and one slice
793
+ * carries one config. Keyed by tool name; each slice's own keys are
794
+ * {@link toolCallKey}s, so two concurrent calls to the same tool climb
795
+ * independent ladders while sharing the tool's declared policy.
796
+ *
797
+ * A tool declaring neither `timeoutMs` nor `retry` mints no entry, so this is
798
+ * `{}` for every agent that uses no per-tool knob — the addition costs an
799
+ * empty record on the durable Model and nothing else.
800
+ *
801
+ * The result arm is `null`: a tool's VALUE settles through the fan-out ledger
802
+ * and the conversation, exactly as before. This slice tracks only the ladder —
803
+ * which attempt is out, when the next one is due, and when the budget is spent
804
+ * — which is what has to survive a reload.
805
+ */
806
+ readonly toolResilience: Readonly<Record<string, ResilientState<ToolCall, null>>>;
807
+ /**
808
+ * The `callId`s whose PUBLIC outcome is already a failure (#145) — a tool the
809
+ * ladder settled on its deadline or on a spent retry budget, or one whose own
810
+ * error was folded. A promise cannot be cancelled, so the abandoned attempt
811
+ * may still resolve; when it does, its late `_ok` names a `callId` listed
812
+ * here and every public channel stays silent about it.
813
+ *
814
+ * The fan-out already drops the late value (its entry is gone, so the fold is
815
+ * a no-op), but "folds nothing" and "emits nothing" are two different facts:
816
+ * the event projector is Msg-shaped and would otherwise push a `ToolSettled`
817
+ * for a `callId` `onToolError` already reported as `{ _tag: "timeout" }`. The
818
+ * projector reads the post-transition state, by which point the ladder has
819
+ * forgotten the key, so the discriminator is carried HERE rather than derived
820
+ * from a presence check that erases both readings.
821
+ *
822
+ * Plain data, one string per failed call, cleared by `start` with the rest of
823
+ * the prior run's bookkeeping. It survives the batch drain and the stage
824
+ * retire on purpose — that is exactly when a late settle arrives.
825
+ */
826
+ readonly refusedCalls: readonly string[];
827
+ readonly failure: AgentFailure | null;
828
+ /**
829
+ * The run's terminal output — the FIRST-CLASS result (issue #46). `null`
830
+ * until the pipeline finishes; set to the last model turn (the empty-tool
831
+ * turn that retired the final stage) the instant `run.phase` becomes `"done"`.
832
+ *
833
+ * This survives the `conversation` clear on stage retire: clearing the
834
+ * conversation is correct durability hygiene (a finished stage's transcript
835
+ * is not live state), but the run's PRODUCT is, so it lives here on the
836
+ * durable slice rather than being scraped off the `observe` firehose by
837
+ * matching the private `resilient_ok` Msg and racing the clear (the old
838
+ * `captureLastTurn` dance this field deletes). A consumer reads
839
+ * `runtime.result()?.output` / `(await runtime.done()).output`.
840
+ *
841
+ * Typed `AgentTurn | null` (not `O[P]`): the run's output is always a model
842
+ * turn — the `O extends Record<P, AgentTurn>` type bound pins every purpose's
843
+ * output to an `AgentTurn`, and the terminating turn is the one with no tool
844
+ * calls. The wider `Record<P, unknown>` bound on `AgentState` itself does not
845
+ * constrain `O[P]`, so naming the concrete `AgentTurn` keeps this field's type
846
+ * total without a purpose-indexing narrow.
847
+ */
848
+ readonly output: AgentTurn | null;
849
+ /**
850
+ * The system prompt, durable beside the transcript it governs. `null` when
851
+ * the config named none. Read by `brainCall` on every model call — a
852
+ * rehydrated or replayed run prompts with what the Model says, never with
853
+ * what a closure happens to hold now.
854
+ */
855
+ readonly instructions: string | null;
856
+ }
857
+ /**
858
+ * The unified terminal failure the agent settles on. The agent terminates `failed`
859
+ * through TWO independent slice channels:
860
+ *
861
+ * - `state.failure` (`AgentFailure`) — the AGENT'S OWN annotation
862
+ * (`turn_limit` livelock guard / `elapsed_limit` wall-clock guard / `llm`
863
+ * exhausted-retry). Set WITHOUT moving
864
+ * `run.phase` (it stays `running`); `isSettled` treats a non-null `failure`
865
+ * as terminal regardless of `run.phase`.
866
+ * - `state.run.failure` (`RunFailure`) — the monitored-run channel
867
+ * (`deadline` watchdog / `stage` failure), present iff `run.phase` is
868
+ * `"failed"`.
869
+ *
870
+ * Callers used to union these by hand at every status question. `status`
871
+ * collapses them into ONE `failure`, so a consumer reads `status(s).failure`
872
+ * without knowing which channel produced it.
873
+ */
874
+ type AgentTerminalFailure<Stage> = AgentFailure | RunFailure<Stage>;
875
+ /**
876
+ * The agent's lifecycle status — THE single typed channel for "what is this run
877
+ * doing?". A discriminated union on `kind` so any change to the
878
+ * private slice shape (`Awaiting`, the failure channels, `run.phase`) forces a
879
+ * compile error at the call sites that switch on it, instead of silently
880
+ * breaking a hand-rolled re-derivation. Make-invalid-states-unrepresentable:
881
+ *
882
+ * - `idle` — never started: `run.phase === "idle"`, the slice straight
883
+ * out of `init` before any `agent_start`. Distinct from
884
+ * `running` so a "start or resume?" decision never boots a
885
+ * run that has not begun (#92); the next move is `agent_start`.
886
+ * - `running` — live, NOT awaiting tools (a brain call is in flight, or the
887
+ * run is between stages). Not resumable on cold wake by
888
+ * itself — the in-flight brain call re-fires from `boot`.
889
+ * A `stale` run reads here too: monitored-run documents it
890
+ * as a soft, still-resumable live mark that the next
891
+ * `progress` flips back to `running`.
892
+ * - `suspended` — the RESUMABLE case: running + a live conversation +
893
+ * `awaiting.kind === "tools"`. `pending` is the outstanding
894
+ * tool calls (`conversation.awaiting` … the in-flight batch),
895
+ * read off `tools.running`. This is exactly the shape
896
+ * `agentIsResumable` re-derived by hand.
897
+ * - `done` — the pipeline finished; `output` is the terminal model turn
898
+ * stamped on `state.output` (issue #46), `null` if the run
899
+ * produced no turn.
900
+ * - `failed` — terminal failure; `failure` is the UNIFIED channel
901
+ * (`AgentTerminalFailure`), absorbing the `state.failure` vs
902
+ * `state.run.failure` dual channel so callers stop unioning.
903
+ * - `cancelled` — stopped because the caller asked — an aborted `AbortSignal`,
904
+ * or their own `stopWhen` answering `true` at a turn boundary;
905
+ * `at` is when the stop landed. Terminal and distinct from
906
+ * `failed`: nothing went wrong, the caller asked, so a consumer
907
+ * branching on failure does not have to except one reason. There is no
908
+ * `output` — a cancelled run produced no terminal turn, and a
909
+ * `null` one here would be indistinguishable from a `done` run
910
+ * that produced none.
911
+ */
912
+ type AgentStatus<Stage> = {
913
+ readonly kind: "idle";
914
+ } | {
915
+ readonly kind: "running";
916
+ } | {
917
+ readonly kind: "suspended";
918
+ readonly pending: readonly ToolCall[];
919
+ } | {
920
+ readonly kind: "done";
921
+ readonly output: AgentTurn | null;
922
+ } | {
923
+ readonly kind: "failed";
924
+ readonly failure: AgentTerminalFailure<Stage>;
925
+ } | {
926
+ readonly kind: "cancelled";
927
+ readonly at: number;
928
+ };
929
+ /**
930
+ * Ask where an agent run stands: pass its state, get back one of `idle`,
931
+ * `running`, `suspended` (with the tool calls it is waiting on), `done` (with
932
+ * the output) or `failed` (with the failure).
933
+ *
934
+ * Read this instead of picking at the state's own fields. PURE — reads no
935
+ * clock or randomness, allocates one small record.
936
+ *
937
+ * Ordering is terminal-first so a settled run never reports `running`, and a
938
+ * never-started one never reports live:
939
+ *
940
+ * 1. `state.failure` (the agent's own annotation, set WITHOUT moving
941
+ * `run.phase`) → `failed`. Checked first because `turn_limit` / `llm`
942
+ * leave `run.phase === "running"`; reading `run.phase` first would
943
+ * misreport such a run as `running`. This is the canonical failure source
944
+ * when present.
945
+ * 2. `run.phase === "idle"` → `idle`. Never started (#92); after the failure
946
+ * check so the annotation stays canonical, before every live reading so
947
+ * an `init` slice is never mistaken for a run in flight.
948
+ * 3. `run.phase === "failed"` → `failed`, carrying `run.failure` (deadline /
949
+ * stage). The fallback channel.
950
+ * 4. `run.phase === "done"` → `done` with `state.output` (#46).
951
+ * 5. `run.phase === "cancelled"` → `cancelled`, carrying when the stop landed.
952
+ * 6. `running` / `stale` + conversation + `awaiting.kind === "tools"` →
953
+ * `suspended` with the outstanding tool calls (`tools.running`). THE
954
+ * resumability condition; otherwise the run reads `running`.
955
+ *
956
+ * Steps 2–6 are ONE exhaustive `switch` over `run.phase` closed by `absurd`, not
957
+ * an `if` chain with a trailing `return { kind: "running" }`. Under the chain a
958
+ * phase added to the slice and forgotten here reported as `running` — a terminal
959
+ * run described as live, which is the worst answer this function can give and one
960
+ * nothing would have caught. The switch turns that omission into a type error.
961
+ */
962
+ declare function status<Stage, P extends string, O extends Record<P, unknown>, R>(s: AgentState<Stage, P, O, R>): AgentStatus<Stage>;
963
+
964
+ /**
965
+ * @demlik/tea/agent — the context-compaction seam.
966
+ *
967
+ * The opt-in transcript snapshot-and-compact policy, shaped exactly like
968
+ * `AgentSnapshotConfig` (see `./types`) so a short agent pays nothing and cannot
969
+ * even mention the machinery. This module owns the whole `$compact` vocabulary:
970
+ * the reserved purpose, the summary schema, the consumer policy, the config
971
+ * discriminant, and the dedicated `compact_run` / `compact_ok` / `compact_err`
972
+ * Cmd + Msgs re-keyed off the composed resilient call at the agent boundary.
973
+ */
974
+
975
+ /**
976
+ * The reserved purpose the compaction round-trip runs under. Compaction
977
+ * is a DEDICATED resilient LLM call (design B1), NOT one of the consumer's brain
978
+ * purposes `P` — so it carries its own purpose literal, kept in the agent's
979
+ * private `$`-namespace (the same reserved-namespace discipline `with-resilience`
980
+ * uses) so it never collides with a consumer purpose. A consumer never names it.
981
+ */
982
+ type CompactionPurpose = "$compact";
983
+ /** The reserved compaction purpose's value — the single in-flight summarize call's key. */
984
+ declare const COMPACTION_PURPOSE: CompactionPurpose;
985
+ /**
986
+ * The purpose→output map for the compaction LLM call — the single reserved
987
+ * `$compact` purpose mapping to a {@link CompactionSummary}. Mirrors the brain
988
+ * call's `O` map, scoped to the one compaction purpose, so the composed
989
+ * `createLlmCall` parses the summarize output under the same structured-output
990
+ * contract the brain call uses.
991
+ */
992
+ interface CompactionOutputs extends Record<CompactionPurpose, unknown> {
993
+ readonly $compact: CompactionSummary;
994
+ }
995
+ /**
996
+ * Narrow an unknown to a {@link CompactionSummary} — the runtime witness for the
997
+ * compaction call's structured output. Checks the one load-bearing field
998
+ * (`summary` is a string). PURE — allocates no Error.
999
+ */
1000
+ declare function isCompactionSummary(value: unknown): value is CompactionSummary;
1001
+ /**
1002
+ * The `Schema<CompactionSummary>` the compaction call binds — tea's own parse
1003
+ * target for the summarize round-trip (it OWNS the `$compact` purpose's output).
1004
+ * Throws on a non-summary (the zod-style `parse` contract the llm-call handler
1005
+ * relies on), so a malformed summary is a `compact_err` (errors are data), never
1006
+ * a corrupt fold-back.
1007
+ */
1008
+ declare const compactionSummarySchema: Schema<CompactionSummary>;
1009
+ /**
1010
+ * The result a compaction round-trip produces — the model's summary of the
1011
+ * folded-away turns. Tea OWNS this shape (the `$compact` purpose's output): the
1012
+ * fold-back (`compact_ok`) writes `summary` into a synthetic head `AgentTurn`
1013
+ * (design A1), so a consumer's `loadMessages` reads it as a normal turn with no
1014
+ * watermark to learn. Generic-free — the summary is always plain text.
1015
+ */
1016
+ interface CompactionSummary {
1017
+ /** The model's summary of the folded-away (oldest) turns + their tool records. */
1018
+ readonly summary: string;
1019
+ }
1020
+ /**
1021
+ * The consumer's compaction policy. One PURE trigger; the impure
1022
+ * summarize round-trip is composed by the agent (a dedicated resilient LLM call
1023
+ * under the reserved `$compact` purpose, inheriting retry/backoff — design B1),
1024
+ * so the policy never reaches the model itself.
1025
+ *
1026
+ * - `planCompaction` — PURE: given the live conversation ABOUT to fire a brain
1027
+ * call, return how many of the OLDEST turns to fold into a summary, or `0`
1028
+ * to skip. No clock, no RNG → replay re-decides identically (design D). A
1029
+ * char-length / turn-count / real deterministic-tokenizer heuristic all
1030
+ * qualify. Returning `>= turns.length` is clamped to "fold all but keep the
1031
+ * loop alive" by the trigger (it never folds the turn currently in flight).
1032
+ * - `payloadOf` — build the per-call prompt payload the compaction
1033
+ * `MessageLoader` reads (the turns being folded). Omit → `null` (the loader,
1034
+ * if any, reads the conversation off the agent's own state). Opaque to the
1035
+ * agent, exactly like the brain call's `payloadOf`.
1036
+ */
1037
+ interface CompactionPolicy<R, Msg = unknown> {
1038
+ /** PURE trigger: how many OLDEST turns to fold (`0` = skip). No clock/RNG. */
1039
+ readonly planCompaction: (conversation: Conversation<R>) => number;
1040
+ /** Build the summarize call's prompt payload from the turns being folded. Omit → `null`. */
1041
+ readonly payloadOf?: (conversation: Conversation<R>, folding: number) => unknown;
1042
+ /** DI port — the SDK / message loader for the summarize call. Omit → invoke with `[]`. */
1043
+ readonly loadMessages?: MessageLoader<CompactionPurpose, Msg>;
1044
+ }
1045
+ /**
1046
+ * The compaction discriminant, shaped exactly like {@link
1047
+ * AgentSnapshotConfig}. Compaction is either OFF —
1048
+ * `compaction` is structurally absent and the agent never emits a `compact_run`
1049
+ * Cmd — or ON, in which case `compaction` is a {@link CompactionPolicy}. A `{
1050
+ * compaction?: never }` member (rather than a bare optional) makes the OFF case
1051
+ * load-bearing: it forbids passing `compaction` at all, so `toMachine`
1052
+ * config-derives whether the `compact_run` interpret handler is REQUIRED (ON) or
1053
+ * FORBIDDEN (OFF) — never a silent no-op handler, the same type-lie-killer
1054
+ * `AgentSnapshotConfig` uses.
1055
+ */
1056
+ type AgentCompactionConfig<R, Msg> = {
1057
+ readonly compaction?: never;
1058
+ } | {
1059
+ readonly compaction: CompactionPolicy<R, Msg>;
1060
+ };
1061
+ /**
1062
+ * The "summarize the oldest N turns" effect Cmd — the compaction round-trip's
1063
+ * carrier. It mirrors the brain `resilient_run` Cmd's shape (a `key` + the
1064
+ * plain `LlmCall<CompactionPurpose>` input, no closures) but under the dedicated
1065
+ * `compact_run` discriminant so it routes to the compaction interpret handler, not
1066
+ * the brain one. The handler composes the resilient-call wrapper (retry/backoff) and
1067
+ * returns the re-keyed `compact_ok` / `compact_err` settle for re-entry.
1068
+ */
1069
+ type AgentCompactRunCmd = Cmd<typeof MsgType.CompactRun> & {
1070
+ readonly key: CompactionPurpose;
1071
+ readonly input: LlmCall<CompactionPurpose>;
1072
+ };
1073
+ /** The compaction round-trip success settle Msg — carries the parsed {@link CompactionSummary}. */
1074
+ type AgentCompactOkMsg = {
1075
+ readonly type: typeof MsgType.CompactOk;
1076
+ readonly key: CompactionPurpose;
1077
+ readonly result: LlmOk<CompactionPurpose, CompactionOutputs>;
1078
+ readonly at: number;
1079
+ };
1080
+ /** The compaction round-trip failure settle Msg — carries the typed {@link LlmErr}. */
1081
+ type AgentCompactErrMsg = {
1082
+ readonly type: typeof MsgType.CompactErr;
1083
+ readonly key: CompactionPurpose;
1084
+ readonly error: LlmErr<CompactionPurpose>;
1085
+ readonly at: number;
1086
+ };
1087
+ /**
1088
+ * The CONFIG-DERIVED compaction obligation on `toMachine`'s `toolInterpret`
1089
+ * — the exact twin of {@link SnapshotInterpret}.
1090
+ * Resolves on the `Compact` discriminant the compaction overload of
1091
+ * `createAgent` fixes:
1092
+ *
1093
+ * - compaction ON → a REQUIRED `compact_run` handler
1094
+ * (`Interpret<M, AgentCompactRunCmd, Ctx>`). The summarize round-trip MUST be
1095
+ * wired — the agent never defaults it to a no-op.
1096
+ * - compaction OFF → `{ compact_run?: never }`. The handler is FORBIDDEN: with no
1097
+ * policy the agent never emits a `compact_run` Cmd, so wiring it would be
1098
+ * dead code. The consumer cannot even mention `compact_run`.
1099
+ *
1100
+ * Same type-lie-killer as the snapshot derivation: the obligation is present
1101
+ * EXACTLY when the Cmd can fire, never as a silent gap the agent backfills.
1102
+ */
1103
+ type CompactInterpret<M extends {
1104
+ type: string;
1105
+ }, Compact extends boolean, Ctx> = Compact extends true ? Interpret<M, AgentCompactRunCmd, Ctx> : {
1106
+ readonly compact_run?: never;
1107
+ };
1108
+
1109
+ /**
1110
+ * @demlik/tea/agent — `tool()` + `toolRouter()`: declare a tool once and derive
1111
+ * what a consumer used to hand-write twice — the `toolOf` mapping from a
1112
+ * model's `ToolCall` to an effect Cmd, and the interpret handler that runs it
1113
+ * and settles it.
1114
+ *
1115
+ * A tool is a `Cmd.define`d effect whose input is the model's call —
1116
+ * `{ callId, args }` — with the handler colocated on the constructor. The
1117
+ * router folds a set of them into one `toolOf` and one interpret table; the
1118
+ * handlers settle through the minted `<name>_ok` / `<name>_err` Msgs, errors as
1119
+ * `{ _tag }` data (ADR 0011). `createAgent(...).toMachine({ tools })` folds
1120
+ * those settles into the conversation, so a consumer names nothing twice.
1121
+ */
1122
+
1123
+ /**
1124
+ * The prefix a protocol discriminant was minted from: `resilient_ok` →
1125
+ * `resilient`, `compact_run` → `compact`. A tool named by that prefix would
1126
+ * mint the same `<name>_ok` / `<name>_err` the agent's reducer already owns.
1127
+ */
1128
+ type SettlePrefixOf<T extends string> = T extends `${infer P}_ok` | `${infer P}_err` | `${infer P}_run` ? P : never;
1129
+ declare const REJECTED_TYPE = "tool_rejected";
1130
+ declare const SNAPSHOT_WRITE_TYPE = "snapshot_write";
1131
+ /**
1132
+ * A tool name `tool()` refuses. A tool's name is its Cmd `type` — so
1133
+ * its interpret key — and the prefix of its settle Msgs, so every string
1134
+ * already spoken by the protocol is taken twice over: the settle prefixes
1135
+ * (`resilient`, `agent_tool`, `compact`) would overwrite the agent's own
1136
+ * reducer handlers through `toMachine`'s last-wins spread, and the discriminants
1137
+ * themselves (`compact_run`, `resilient_run`, …) would shadow the interpret
1138
+ * handler of that name. Both halves derive from `MsgType`: a new entry there
1139
+ * reserves its name and its prefix with no second edit. The two names outside
1140
+ * the protocol are the router's own `tool_rejected` and the checkpoint handler
1141
+ * `snapshot_write`, which `toMachine` merges under the consumer's key.
1142
+ */
1143
+ type ReservedToolName = MsgTypeValue | SettlePrefixOf<MsgTypeValue> | typeof REJECTED_TYPE | typeof SNAPSHOT_WRITE_TYPE;
1144
+ /**
1145
+ * Widens to `unknown` for a name outside the reserved set and to `never`
1146
+ * inside it, so `Name & NotReserved<Name>` is the name itself or
1147
+ * unconstructible. A widened `string` passes here — the runtime check in
1148
+ * `tool()` is what catches a reserved name built from one.
1149
+ */
1150
+ type NotReserved<Name extends string> = Name extends ReservedToolName ? never : unknown;
1151
+ /** Whether `name` is one `tool()` refuses — the set `ReservedToolName` types. */
1152
+ declare function isReservedToolName(name: string): name is ReservedToolName;
1153
+ /**
1154
+ * The input a tool Cmd carries: the model's `callId` (the fan-out identity the
1155
+ * settle folds back on) and the `args` already parsed against the tool's
1156
+ * `input` schema — the boundary parses, the handler trusts.
1157
+ */
1158
+ type ToolInput<Args> = {
1159
+ readonly callId: string;
1160
+ readonly args: Args;
1161
+ };
1162
+ /**
1163
+ * The router-minted failure beside a tool's declared tags: the handler threw
1164
+ * (or rejected) with something that is not a declared `{ _tag }`. Plain data
1165
+ * the model sees as a reason, never a rejection out of the interpret handler.
1166
+ */
1167
+ type ToolThrown = {
1168
+ readonly _tag: "thrown";
1169
+ readonly message: string;
1170
+ };
1171
+ /**
1172
+ * The typed success constructor a handler receives: `ok(value)` with `Ok`
1173
+ * fixed to what the `ok` schema parses, so a value of the wrong shape is
1174
+ * refused where it is written.
1175
+ */
1176
+ type ToolOk<Ok, E extends Tagged> = (value: Ok) => Result<Ok, E>;
1177
+ /**
1178
+ * The typed failure constructor a handler receives: `fail({ _tag })` with `E`
1179
+ * fixed to the declared tags, so the literal is checked against them where it
1180
+ * is written. (A bare `{ _tag: "x" }` built elsewhere infers `_tag: string`
1181
+ * and cannot be — the parameter type is what keeps it literal.)
1182
+ */
1183
+ type ToolFail<Ok, E extends Tagged> = (error: E) => Result<Ok, E>;
1184
+ /**
1185
+ * The two constructors a handler is handed, one per channel — `ok` for the
1186
+ * value the `ok` schema parses, `fail` for a declared `{ _tag }`. Both are
1187
+ * tea's, so a handler settles either arm without naming the result library
1188
+ * underneath.
1189
+ */
1190
+ type ToolConstructors<Ok, E extends Tagged> = {
1191
+ readonly ok: ToolOk<Ok, E>;
1192
+ readonly fail: ToolFail<Ok, E>;
1193
+ };
1194
+ /**
1195
+ * A tool's handler: the parsed `args`, the ctx slice `requirements` named, and the
1196
+ * typed `{ ok, fail }`, to a result over the declared channels — `Ok` is what
1197
+ * the `ok` schema parses, `E` the declared `_tag` union. An undeclared tag
1198
+ * does not compile.
1199
+ */
1200
+ type ToolHandler<Args, Ok, E extends Tagged, R> = (args: Args, ctx: R & PortEmitter, settle: ToolConstructors<Ok, E>) => Promise<Result<Ok, E>>;
1201
+ /**
1202
+ * What `tool()` returns: the `Cmd.define`d constructor (so `Settled<typeof t>`
1203
+ * / `CmdOf<typeof t>` read it like any def) plus the colocated `interpret` handler,
1204
+ * the bare `args` schema the router parses a call against, and the
1205
+ * `description` a provider adapter declares to the model beside that schema.
1206
+ * `E` is the full failure union the Cmd settles with — the declared tags plus
1207
+ * `thrown`.
1208
+ */
1209
+ type ToolDef<Name extends string, Args, Ok, E extends Tagged, R> = CmdDef<Name, ToolInput<Args>, Ok, E, R> & {
1210
+ readonly description: string;
1211
+ readonly args: z.ZodType<Args>;
1212
+ /**
1213
+ * The timeout / retry knob this tool declared, or `null` when it declared
1214
+ * neither. `toolRouter` serves it to the agent as `resilienceOf`.
1215
+ */
1216
+ readonly resilience: ToolResilience | null;
1217
+ readonly interpret: (cmd: CmdValue<Name, ToolInput<Args>, E, R>, ctx: R & PortEmitter) => Promise<Settled<CmdDef<Name, ToolInput<Args>, Ok, E, R>>>;
1218
+ };
1219
+ /** The declaration-erased view the router reads. */
1220
+ type AnyToolDef = AnyCmdDef & {
1221
+ readonly description: string;
1222
+ readonly args: z.ZodType;
1223
+ readonly resilience: ToolResilience | null;
1224
+ readonly interpret: (cmd: never, ctx: never) => Promise<unknown>;
1225
+ };
1226
+ /**
1227
+ * Declare one tool the model may call — its name, the schemas for its arguments
1228
+ * and result, the failures it may return and the handler that runs it — and get
1229
+ * back a `Cmd<T, E, R>` definition, whose `T` is what `ok` parses and whose `E`
1230
+ * is the `err` tag union, that you pass to `toolRouter` or `defineAgent`.
1231
+ *
1232
+ * So a tool's two declared channels ARE the kernel's two typed effect channels
1233
+ * (ADR 0014), spelled in schemas rather than in type parameters: a settled
1234
+ * failure keeps its `_tag` into the conversation, so a reducer switching over
1235
+ * `err`'s tags is exhaustive and an unhandled one is a compile error.
1236
+ *
1237
+ * `name` is the name the model calls it
1238
+ * by; `description` is the model-facing sentence — the one place it lives — a
1239
+ * provider adapter declares to the model beside the schema (Anthropic
1240
+ * `description`, OpenAI `function.description`) so the model can tell when to
1241
+ * call the tool, read off `def.description`, never off the `input` schema;
1242
+ * `input` parses the model's `args`; `ok` parses the handler's value at the
1243
+ * edge; `err` is the `_tag` list the handler may fail with; `requirements` is the ctx
1244
+ * slice it reads, demanded at `run`. The handler returns one of the two
1245
+ * constructors it is handed — `ok(value)` or the typed `fail({ _tag })`; a
1246
+ * throw settles `<name>_err` — with the thrown `_tag` when it is a declared
1247
+ * one, else as `{ _tag: "thrown", message }`.
1248
+ *
1249
+ * A `ReservedToolName` does not compile as `name`, and one that reaches here
1250
+ * as a widened `string` throws — the same declaration-bug refusal
1251
+ * `toolRouter` gives a name declared twice.
1252
+ */
1253
+ declare function tool<const Name extends string, Args, Ok, const Tags extends readonly string[], R = unknown>(name: Name & NotReserved<Name>, spec: {
1254
+ readonly description: string;
1255
+ readonly input: z.ZodType<Args>;
1256
+ readonly ok: z.ZodType<Ok>;
1257
+ readonly err: Tags;
1258
+ readonly requirements?: Requirements<R>;
1259
+ /**
1260
+ * The budget one call of this tool gets, in ms — the overall cap, measured
1261
+ * from the first attempt and not restarted by a retry. When it elapses the
1262
+ * call settles as a `ToolOutcome` error carrying `_tag: "timeout"` beside
1263
+ * its `reason`, and the loop moves on; the attempt is NOT cancelled (a promise cannot be), so it runs to its
1264
+ * own end and its late settle folds nothing. Omit → no cap.
1265
+ */
1266
+ readonly timeoutMs?: number;
1267
+ /**
1268
+ * The backoff ladder a failed attempt of this tool climbs — the same
1269
+ * `{ baseMs, factor, capMs, jitter, maxAttempts }` shape the brain call's
1270
+ * `retry` takes. The ladder is folded into the Model and its wait is a timer
1271
+ * Sub, so a process killed between two attempts resumes at the attempt it
1272
+ * was on. A spent budget settles as a `ToolOutcome` error carrying
1273
+ * `_tag: "retry_exhausted"` beside its `reason`, with the attempt count and
1274
+ * the last attempt's reason as the `attempts` / `last` fields.
1275
+ * Omit → the first failure is the outcome.
1276
+ */
1277
+ readonly retry?: ToolResilience["retry"];
1278
+ }, handler: ToolHandler<Args, Ok, TaggedError<Tags[number]>, R>): ToolDef<Name, Args, Ok, TaggedError<Tags[number] | "thrown">, R>;
1279
+ /**
1280
+ * A call the router could not hand to a tool: the model named a tool nobody
1281
+ * declared, or its `args` failed the tool's `input` schema. `toolOf` is total —
1282
+ * it never throws inside the reducer — so the refusal rides its own Cmd and
1283
+ * settles `tool_rejected_err`, which the loop folds like any tool failure.
1284
+ */
1285
+ type ToolRejection = {
1286
+ readonly _tag: "unknown_tool";
1287
+ readonly name: string;
1288
+ } | {
1289
+ readonly _tag: "malformed_args";
1290
+ readonly name: string;
1291
+ readonly issues: ReadonlyArray<{
1292
+ readonly path: string;
1293
+ readonly message: string;
1294
+ }>;
1295
+ };
1296
+ declare const rejected: CmdDef<"tool_rejected", {
1297
+ readonly callId: string;
1298
+ readonly error: ToolRejection;
1299
+ }, never, {
1300
+ readonly [detail: string]: unknown;
1301
+ readonly _tag: "unknown_tool";
1302
+ } | {
1303
+ readonly [detail: string]: unknown;
1304
+ readonly _tag: "malformed_args";
1305
+ }, unknown>;
1306
+ /** The Cmd `tool_rejected` builds — the router-owned variant of `ToolCmd`. */
1307
+ type ToolRejectedCmd = CmdOf<typeof rejected>;
1308
+ /** The Cmd union a router's `toolOf` produces — `TC` for `createAgent`. */
1309
+ type ToolCmd<T extends AnyToolDef> = CmdOf<T> | ToolRejectedCmd;
1310
+ /** The settled Msg union a router's handlers return — folded by `toMachine`. */
1311
+ type ToolMsg<T extends AnyToolDef> = Settled<T> | Settled<typeof rejected>;
1312
+ /**
1313
+ * `ToolCmd<T>` as `toMachine` reads it: `never` for `T = never` — the "no
1314
+ * router" reading it defaults to — so the router-owned `tool_rejected` arm
1315
+ * does not leak into a machine that wired no router.
1316
+ */
1317
+ type WiredToolCmd<T extends AnyToolDef> = [T] extends [never] ? never : ToolCmd<T>;
1318
+ /** `ToolMsg<T>` as `toMachine` / `agentEvents` read it — see `WiredToolCmd`. */
1319
+ type WiredToolMsg<T extends AnyToolDef> = [T] extends [never] ? never : ToolMsg<T>;
1320
+ /** The union of every tool's `ok` value — `R` for `createAgent`. */
1321
+ type ToolResult<T extends AnyToolDef> = OkOf<T>;
1322
+ /**
1323
+ * Every failure a router over `T` can settle with — the union `outcomeOf`'s
1324
+ * error arm is typed from. Five sources, and a consumer branching on `_tag`
1325
+ * meets all five: each tool's DECLARED tags plus the `thrown` `tool()` appends
1326
+ * (`ErrOf<T>`), the kernel's `malformed_result` (a handler returned a value its
1327
+ * own `ok` schema rejects), the router's own `unknown_tool` / `malformed_args`
1328
+ * rejections, and the ladder's `timeout` / `retry_exhausted` (#117) — which end
1329
+ * a call from outside the handler and so are nothing a tool can declare.
1330
+ */
1331
+ type ToolError<T extends AnyToolDef> = ErrOf<T> | MalformedResult | ToolRejection | ToolResilienceError;
1332
+ /**
1333
+ * The error outcome a router over `T` produces: `{ kind: "error", _tag,
1334
+ * …payload, reason }`, discriminable on `_tag` over {@link ToolError}. This is
1335
+ * what `defineAgent`'s `onToolError` hands the consumer.
1336
+ */
1337
+ type ToolFailureOf<T extends AnyToolDef> = TaggedFailure<ToolError<T>>;
1338
+ /** One settled tool, read back off a `ToolMsg` by `outcomeOf`. */
1339
+ type ToolSettlement<R, E extends Tagged = Tagged> = {
1340
+ readonly callId: string;
1341
+ readonly outcome: {
1342
+ readonly kind: "ok";
1343
+ readonly result: R;
1344
+ } | TaggedFailure<E>;
1345
+ };
1346
+ /**
1347
+ * What `toolRouter()` returns: the derived `toolOf` for `createAgent`'s config,
1348
+ * the interpret table `toMachine({ tools })` merges, the defs it puts on
1349
+ * `Machine.cmds`, and the one reader that turns a settled Msg back into the
1350
+ * conversation's `ToolOutcome`.
1351
+ */
1352
+ interface ToolRouter<T extends AnyToolDef> {
1353
+ /** Every def the router settles through — hand to `Machine.cmds`. */
1354
+ readonly defs: readonly AnyCmdDef[];
1355
+ /** The `toolOf` for `createAgent`: total, pure, parses `args` at the edge. */
1356
+ readonly toolOf: (call: ToolCall) => ToolCmd<T>;
1357
+ /** One interpret handler per tool plus the `tool_rejected` handler. */
1358
+ readonly interpret: Interpret<ToolMsg<T>, ToolCmd<T>, NoCtx>;
1359
+ /**
1360
+ * The timeout / retry knob the called tool declared — `AgentConfigCore`'s
1361
+ * `toolResilienceOf` seam, filled from the `tool()` specs. `null` for a tool
1362
+ * that declared neither field and for a call no tool answers (the rejection
1363
+ * path settles in the reducer and never runs an effect to time out). PURE.
1364
+ */
1365
+ readonly resilienceOf: (call: ToolCall) => ToolResilience | null;
1366
+ /**
1367
+ * Read a settled tool off a Msg: `null` when the Msg is not one of this
1368
+ * router's `<name>_ok` / `<name>_err`. The one place a `{ _tag }` failure is
1369
+ * rendered to the `reason` string the conversation carries — and the tag and
1370
+ * its payload ride beside that rendering, never instead of it (#115).
1371
+ */
1372
+ readonly outcomeOf: (msg: {
1373
+ readonly type: string;
1374
+ }) => ToolSettlement<ToolResult<T>, ToolError<T>> | null;
1375
+ }
1376
+ /**
1377
+ * Fold a set of `tool()`s into one router — pass it the tools, get back the
1378
+ * lookup `createAgent` needs, the handlers `toMachine` merges, and a reader that
1379
+ * turns a settled message back into a plain outcome.
1380
+ *
1381
+ * Two tools with one name is a declaration bug, refused here rather than by a
1382
+ * silent last-wins map.
1383
+ */
1384
+ declare function toolRouter<T extends AnyToolDef>(tools: readonly T[]): ToolRouter<T>;
1385
+ /**
1386
+ * Give a router's interpret cells real wall-clock overlap without touching the
1387
+ * kernel — pass the table `toolRouter` built, get back one whose cells launch
1388
+ * their tool and RETURN, so `runInterpret` reaches the next Cmd of the turn
1389
+ * while the first tool is still running.
1390
+ *
1391
+ * This is ADR 0018's option (c), and the whole of it. `runInterpret` stays the
1392
+ * serial loop the ADR ruled it must be: it still awaits one handler before
1393
+ * reaching the next Cmd — the handlers just stop being the thing that takes the
1394
+ * time. Three properties are what make that safe, and each is a line below:
1395
+ *
1396
+ * - **Settles fold in Cmd-EMISSION order, never completion order.** Each cell
1397
+ * chains its dispatch behind the previous cell's, so two tools that overlap
1398
+ * on the clock still settle a-then-b when a's Cmd was emitted first, whichever
1399
+ * finished first. That is invariant 2's serializability, and it is what keeps
1400
+ * a replay of a fanned run identical to the run itself.
1401
+ * - **The settle crosses the SAME edge.** A returned Msg is parsed and stamped
1402
+ * by `run`'s `cmdEdge`; a dispatched one would not be, so the cell settles
1403
+ * through `cmdEdgeOf(ctx)` — the edge `run` hands handlers for exactly this.
1404
+ * One parse, one clock, fanned or not.
1405
+ * - **The work stays counted.** The promise the cell does not return is enlisted
1406
+ * with `detachWorkOf(ctx)`, so `inFlightCmds` and the dispatch tail see it and
1407
+ * `stop()` / `idle()` answer under fan-out what they answer serially.
1408
+ *
1409
+ * The ordering has a price, and it is the honest one: a call whose Cmd was
1410
+ * emitted FIRST holds its siblings' settles until it finishes. They still RUN
1411
+ * in parallel — the turn costs the slowest call, not the sum — but a first call
1412
+ * that never returns leaves the later folds parked behind it, exactly as a
1413
+ * serial run would leave them unstarted. `timeoutMs` on the tool is what bounds
1414
+ * that, fanned or not.
1415
+ *
1416
+ * The per-turn LIMIT is not this function's: the agent's fan-out slice already
1417
+ * launches at most `toolConcurrency` calls per transition, so the table simply
1418
+ * must not block. Nothing here is applied below that knob — `toMachine` wires
1419
+ * the bare cells at the serial default, and a tool that never overlaps is the
1420
+ * exact function `toolRouter` built.
1421
+ */
1422
+ declare function fanOutInterpret<T extends AnyToolDef>(interpret: Interpret<ToolMsg<T>, ToolCmd<T>, NoCtx>): Interpret<ToolMsg<T>, ToolCmd<T>, NoCtx>;
1423
+ /**
1424
+ * Turn a tool failure into the human-readable reason string the conversation
1425
+ * carries — pass the `{ _tag, ...detail }` a tool failed with, get the tag
1426
+ * followed by any remaining detail as JSON.
1427
+ *
1428
+ * The
1429
+ * model reads this next turn, so the data survives the rendering intact.
1430
+ */
1431
+ declare function toolErrorReason(error: Tagged): string;
1432
+
1433
+ /**
1434
+ * @demlik/tea/agent — the wired-machine surface.
1435
+ *
1436
+ * The Cmd / Msg vocabulary the agent speaks, the handle interface `createAgent`
1437
+ * returns (`AgentKnob` / `AgentToMachine`), the do↔agent boot port, the
1438
+ * semantic lifecycle event stream + its projector (`agentEvents`), and the two
1439
+ * pure wiring helpers `mergeInterpret` / `liftAgent`. The reducer core (the
1440
+ * `createAgent` factory that implements this surface) lives in `./index`.
1441
+ */
1442
+
1443
+ /** The brain-call effect Cmd, inherited from `../llm-call`. */
1444
+ type AgentLlmRunCmd<P extends string> = LlmRunCmd<P>;
1445
+ /**
1446
+ * The Cmd union the agent emits, as a CLOSED discriminated union (precise `TC`,
1447
+ * not the open `Cmd`) so `Interpret<M, AgentCmd<P, TC>, Ctx>` maps each key
1448
+ * precisely and `toMachine` merges the interpret halves with no laundering cast:
1449
+ *
1450
+ * - `AgentLlmRunCmd<P>` — the brain-call run Cmd (`resilient_run`), folded
1451
+ * by the wired `brainHandlers` handler.
1452
+ * - `MonitoredRunCmd<unknown>` — the durable checkpoint write the monitored-run
1453
+ * slice emits, present in the union ONLY when
1454
+ * checkpointing is on (`Snap = true`). With
1455
+ * checkpointing off the monitored-run slice never
1456
+ * emits a `snapshot_write` Cmd, so it is config-derived
1457
+ * OUT of the emitted set — the consumer is never asked
1458
+ * to interpret a Cmd that can never fire.
1459
+ * - `TC` — the consumer's per-tool effect, mapped to the
1460
+ * consumer's own tool interpret handler.
1461
+ *
1462
+ * `Snap` defaults to `true` so the verb-internal usage (which forwards whatever
1463
+ * monitored-run emits) and the published type stay a safe superset; the wired
1464
+ * machine `toMachine` returns is parametrized on the overload-fixed `Snap` so its
1465
+ * Cmd set is exact (`MonitoredRunCmd` present only when checkpointing is on).
1466
+ */
1467
+ type AgentCmd<P extends string, TC extends Cmd = Cmd, Snap extends boolean = true, Compact extends boolean = true> = AgentLlmRunCmd<P> | (Snap extends true ? MonitoredRunCmd<unknown> : never) | (Compact extends true ? AgentCompactRunCmd : never) | TC;
1468
+ /**
1469
+ * The CONFIG-DERIVED snapshot obligation on `toMachine`'s `toolInterpret`.
1470
+ * Resolves on the `Snap` discriminant the snapshotting overload of `createAgent`
1471
+ * fixes (`true` checkpointing-on / `false` off):
1472
+ *
1473
+ * - checkpointing ON → a REQUIRED `snapshot_write` handler
1474
+ * (`Interpret<M, MonitoredRunCmd<unknown>, Ctx>`). A real checkpoint write
1475
+ * MUST be wired — the agent never defaults it to a no-op.
1476
+ * - checkpointing OFF → `{ snapshot_write?: never }`. The handler is FORBIDDEN:
1477
+ * the Cmd is config-derived out of the emitted set, so wiring it would be
1478
+ * dead code. The consumer cannot even mention `snapshot_write`.
1479
+ *
1480
+ * This is the type that kills the `snapshot_write: async () => undefined`
1481
+ * ceremony: the obligation is present in the contract EXACTLY when the Cmd can
1482
+ * fire, never as a silent gap the agent backfills.
1483
+ */
1484
+ type SnapshotInterpret<M extends {
1485
+ type: string;
1486
+ }, Snap extends boolean, Ctx> = Snap extends true ? Interpret<M, MonitoredRunCmd<unknown>, Ctx> : {
1487
+ readonly snapshot_write?: never;
1488
+ };
1489
+ /**
1490
+ * The `toMachine` signature, parametrized on the `Snap` + `Compact` discriminants
1491
+ * so the snapshotting / compaction overloads of `createAgent` hand back the right
1492
+ * obligations. The `toolInterpret` requires (ON) or forbids (OFF) the
1493
+ * `snapshot_write` handler via {@link SnapshotInterpret} and the `compact_run` handler
1494
+ * via {@link CompactInterpret}, and the machine's Cmd type is the config-derived
1495
+ * `AgentCmd<P, TC, Snap, Compact>`.
1496
+ *
1497
+ * `tools` is a `toolRouter`: its handlers are merged in, its settled
1498
+ * `<name>_ok` / `<name>_err` Msgs join the machine's `M` and fold into the
1499
+ * conversation, and its Cmds leave the `toolInterpret` obligation — a consumer
1500
+ * whose `toolOf` is the router's supplies only the snapshot / compaction handlers.
1501
+ * With no router (`T = never`) every type here reads exactly as before.
1502
+ */
1503
+ type AgentToMachine<Stage, P extends string, O extends Record<P, AgentTurn>, R, TC extends Cmd, Snap extends boolean, Compact extends boolean> = <Ctx = object, T extends AnyToolDef = never>(opts?: {
1504
+ readonly tools?: ToolRouter<T>;
1505
+ readonly toolInterpret?: Interpret<AgentMachineMsg<P, O, R> | WiredToolMsg<T>, Exclude<TC, WiredToolCmd<T>>, Ctx> & SnapshotInterpret<AgentMachineMsg<P, O, R> | WiredToolMsg<T>, Snap, Ctx> & CompactInterpret<AgentMachineMsg<P, O, R> | WiredToolMsg<T>, Compact, Ctx>;
1506
+ }) => Machine<AgentState<Stage, P, O, R>, AgentMachineMsg<P, O, R> | WiredToolMsg<T>, AgentCmd<P, TC, Snap, Compact>, DeadlineSub, Ctx>;
1507
+ /**
1508
+ * The agent handle `createAgent` returns — the uniform verb contract every tea
1509
+ * composition exposes, plus the wired `toMachine` and the `unsafeDetachedHandlers`
1510
+ * escape hatch. `Snap` flows ONLY into `toMachine`'s `toolInterpret` obligation
1511
+ * (the snapshot derivation); every verb is snapshot-agnostic. The model
1512
+ * message shape `Msg` does not appear on the handle's surface (it is internal to the
1513
+ * brain call's loader), so it is not a type parameter here — only `createAgent`
1514
+ * carries it, to thread the config's `loadMessages` / `model` ports.
1515
+ */
1516
+ interface AgentKnob<Stage, P extends string, O extends Record<P, AgentTurn>, R, TC extends Cmd, Snap extends boolean, Compact extends boolean> {
1517
+ readonly init: () => AgentState<Stage, P, O, R>;
1518
+ readonly start: AgentVerb1<Stage, P, O, R, TC, [runId: string, at: number]>;
1519
+ readonly turn: AgentVerb1<Stage, P, O, R, TC, [
1520
+ result: AgentTurn,
1521
+ at: number
1522
+ ]>;
1523
+ readonly toolOk: AgentVerb1<Stage, P, O, R, TC, [
1524
+ callId: string,
1525
+ result: R,
1526
+ at: number
1527
+ ]>;
1528
+ /**
1529
+ * A bare `reason` string still works and settles an untagged failure — the
1530
+ * hand-wired shape this verb has always had. Hand it a whole `ToolFailure`
1531
+ * instead to keep the `{ _tag, …payload }` beside that reason, which is what
1532
+ * `onToolError` and any host code discriminating on `_tag` then read (#115).
1533
+ */
1534
+ readonly toolErr: AgentVerb1<Stage, P, O, R, TC, [
1535
+ callId: string,
1536
+ failure: string | ToolFailure,
1537
+ at: number
1538
+ ]>;
1539
+ readonly succeed: AgentVerb1<Stage, P, O, R, TC, [
1540
+ key: string,
1541
+ msg: AgentLlmOkMsg<P, O>,
1542
+ at: number
1543
+ ]>;
1544
+ readonly fail: AgentVerb1<Stage, P, O, R, TC, [
1545
+ key: string,
1546
+ msg: AgentLlmErrMsg<P>,
1547
+ at: number
1548
+ ]>;
1549
+ readonly compactOk: AgentVerb1<Stage, P, O, R, TC, [
1550
+ key: string,
1551
+ msg: AgentCompactOkMsg,
1552
+ at: number
1553
+ ]>;
1554
+ readonly compactErr: AgentVerb1<Stage, P, O, R, TC, [
1555
+ key: string,
1556
+ msg: AgentCompactErrMsg,
1557
+ at: number
1558
+ ]>;
1559
+ readonly onTimer: AgentVerb1<Stage, P, O, R, TC, [msg: AgentTimerMsg]>;
1560
+ readonly boot: AgentVerb1<Stage, P, O, R, TC, [at: number]>;
1561
+ readonly isSettled: (s: AgentState<Stage, P, O, R>) => boolean;
1562
+ readonly currentStage: (s: AgentState<Stage, P, O, R>) => Stage | undefined;
1563
+ readonly brainCall: (s: AgentState<Stage, P, O, R>) => LlmCall<P>;
1564
+ readonly subs: (s: AgentState<Stage, P, O, R>) => readonly DeadlineSub[];
1565
+ readonly toMachine: AgentToMachine<Stage, P, O, R, TC, Snap, Compact>;
1566
+ readonly unsafeDetachedHandlers: <M>(ports: AgentPorts<P, O, M>) => AgentDetachedHandlers<P, M>;
1567
+ }
1568
+ /** A verb taking the state + `Args`, returning the agent's `[State, Cmd[]]` tuple. */
1569
+ type AgentVerb1<Stage, P extends string, O extends Record<P, AgentTurn>, R, TC extends Cmd, Args extends readonly unknown[]> = (s: AgentState<Stage, P, O, R>, ...args: Args) => readonly [AgentState<Stage, P, O, R>, readonly AgentCmd<P, TC>[]];
1570
+ /** The brain-call SUCCESS settle Msg, inherited from `../llm-call`. */
1571
+ type AgentLlmOkMsg<P extends string, O extends Record<P, unknown>> = LlmSucceedMsg<P, O>;
1572
+ /**
1573
+ * The brain-call FAILURE settle Msg, inherited from `../llm-call` — it re-enters
1574
+ * the agent's `fail` verb, which backs off via the retry ladder rather than
1575
+ * ending the run.
1576
+ */
1577
+ type AgentLlmErrMsg<P extends string> = LlmFailMsg<P>;
1578
+ /**
1579
+ * The timer Msg (retry + safety deadline) — `DeadlineExceeded`, the shared
1580
+ * shape of both composed wrappers' timer Msgs (`LlmTimerMsg` and `MonitoredRunTimerMsg`
1581
+ * are both `DeadlineExceeded`). One Msg variant covers both timers; `onTimer`
1582
+ * disambiguates by Sub id. This is also the machine Msg the `subscribeDeadline`
1583
+ * handler dispatches directly (no wrapping), matching the sibling gold standard.
1584
+ */
1585
+ type AgentTimerMsg = LlmTimerMsg;
1586
+ /** Ports the consumer supplies to the llm-call handler — re-exported shape. */
1587
+ type AgentPorts<P extends string, O extends Record<P, unknown>, M> = LlmCallPorts<P, O, M>;
1588
+ /**
1589
+ * The LEGACY detached brain-call handler dictionary `handlers(ports)` returns,
1590
+ * superseded by the `Interpret` table `AgentKnob.toMachine()` wires — reach for
1591
+ * `toMachine()` unless you are hand-wiring the verbs yourself.
1592
+ *
1593
+ * It is the inherited `../llm-call` detached form's exact shape, NOT an
1594
+ * `Interpret`.
1595
+ * The `resilient_run` handler runs the invoke inside `ctx.waitUntil` and dispatches
1596
+ * the consumer's `onOk` / `onErr` Msg directly (returning `void`), so it is a
1597
+ * fire-and-forget handler with a structural `{ waitUntil, dispatch }` ctx — it
1598
+ * does not re-enter the resilient settle Msg and so does not drive the retry
1599
+ * loop. Naming the type precisely (rather than laundering it through
1600
+ * `as unknown as Interpret<...>`) keeps `agent.unsafeDetachedHandlers(ports)` honest: the
1601
+ * consumer that wires the verbs by hand gets the real detached shape, and its
1602
+ * `resilient_run` is callable with a plain Cmd + a `{ waitUntil, dispatch }` ctx
1603
+ * with no `as never` at the call site.
1604
+ */
1605
+ type AgentDetachedHandlers<P extends string, M> = {
1606
+ readonly resilient_run: (cmd: AgentLlmRunCmd<P>, ctx: {
1607
+ waitUntil(p: Promise<unknown>): void;
1608
+ dispatch(msg: M): unknown;
1609
+ }) => void;
1610
+ };
1611
+ /** The Msg `do/host`'s `autoBoot` fires to re-enter the agent's `boot` verb on rehydrate. */
1612
+ type AgentBootMsg = {
1613
+ readonly type: typeof MsgType.AgentBoot;
1614
+ readonly at: number;
1615
+ };
1616
+ /**
1617
+ * The do↔agent boot port: construct the `agent_boot` Msg `autoBoot` dispatches
1618
+ * on a resumable rehydrate. The agent owns this constructor so the boot Msg
1619
+ * shape lives in ONE place — the host fires it through here, never as a raw
1620
+ * `{ type: "agent_boot" }` literal.
1621
+ */
1622
+ declare function agentBootMsg(at: number): AgentBootMsg;
1623
+ /**
1624
+ * The Msg an aborted `AbortSignal` fires to settle the run `cancelled`. Owned
1625
+ * here beside the boot Msg for the same reason: the cancel seam lives on the
1626
+ * drive (`driveToDone`'s `cancel`, the lid's `signal`), which is a different
1627
+ * module from the reducer that folds it, so the shape gets ONE home and a
1628
+ * constructor rather than a literal duplicated across the seam.
1629
+ */
1630
+ type AgentCancelMsg = {
1631
+ readonly type: typeof MsgType.AgentCancel;
1632
+ readonly at: number;
1633
+ };
1634
+ /** Construct the `agent_cancel` Msg an abort dispatches. `at` stamps the outcome. */
1635
+ declare function agentCancelMsg(at: number): AgentCancelMsg;
1636
+ /**
1637
+ * The agent machine's Msg union — one variant per reducer entry point. A
1638
+ * consumer using `toMachine` dispatches `agent_start` to begin and `agent_tool_ok`
1639
+ * / `agent_tool_err` to route settled tools back; the brain-call settle Msgs
1640
+ * (`resilient_ok` / `resilient_err`) RE-ENTER from the FIXED `brainHandlers`
1641
+ * (the substrate enqueues an interpret handler's returned Msg as a follow-up),
1642
+ * driving `succeed` / `fail`. Time enters via `at` on every variant — the
1643
+ * reducer never reads the clock.
1644
+ *
1645
+ * There is deliberately NO `agent_turn` variant here. The wired loop folds a
1646
+ * model turn INSIDE `succeed` from the re-entered `resilient_ok` — a single
1647
+ * settle Msg advances both the retry slice and the conversation (the L3 fix).
1648
+ * Exposing `agent_turn` as a dispatchable Msg re-opened the stuck-`running` bug:
1649
+ * a hand-fed turn folds the conversation without ever re-entering `resilient_ok`,
1650
+ * so `succeed` never runs and the resilient slice stays `running`. The
1651
+ * `turn` verb remains on the handle for the consumer that wires the verbs by hand
1652
+ * (manual wiring), but it is not part of the one wired machine's Msg surface.
1653
+ */
1654
+ type AgentMachineMsg<P extends string, O extends Record<P, unknown>, R> = {
1655
+ readonly type: typeof MsgType.AgentStart;
1656
+ readonly runId: string;
1657
+ readonly at: number;
1658
+ } | {
1659
+ readonly type: typeof MsgType.AgentToolOk;
1660
+ readonly callId: string;
1661
+ readonly result: R;
1662
+ readonly at: number;
1663
+ } | {
1664
+ readonly type: typeof MsgType.AgentToolErr;
1665
+ readonly callId: string;
1666
+ readonly reason: string;
1667
+ readonly at: number;
1668
+ } | AgentLlmOkMsg<P, O> | AgentLlmErrMsg<P> | AgentCompactOkMsg | AgentCompactErrMsg | AgentTimerMsg | AgentBootMsg | AgentCancelMsg;
1669
+ /**
1670
+ * The agent's PUBLIC lifecycle events — the semantic stream a consumer
1671
+ * subscribes to via `runtime.on(type, …)`. This is the seam that
1672
+ * DECOUPLES observability/SSE code from the agent's PRIVATE retry/loop Msg
1673
+ * vocabulary: where the old code switched on `resilient_ok` / `agent_tool_ok`
1674
+ * (the inherited resilient-call / tool-fan-out plumbing) off the raw `observe`
1675
+ * firehose, a consumer now folds these named events. The private Msg names live
1676
+ * ONLY inside `agentEvents` (the projector) — they appear nowhere in this union
1677
+ * or any exported type, so a UI built on `TurnSettled` does not break the day
1678
+ * the retry plumbing is renamed.
1679
+ *
1680
+ * - `TurnSettled` — a brain turn settled (the model produced an `AgentTurn`).
1681
+ * Projected off the private `resilient_ok` settle Msg; carries the parsed
1682
+ * `turn` (the narration + tool calls the model asked for).
1683
+ * - `ToolSettled` — a tool call settled OK. Projected off the private
1684
+ * `agent_tool_ok` Msg; carries the `callId` and the tool `result`.
1685
+ * - `RunDone` — the run finished. Projected off the post-transition State
1686
+ * reaching `run.phase === "done"`; carries the run's `output` (the terminal
1687
+ * model turn, or `null`) — the same first-class result `Runtime.result()`
1688
+ * reads (#46), surfaced as an event for the streaming consumer.
1689
+ */
1690
+ type AgentEvent<R> = {
1691
+ readonly type: "TurnSettled";
1692
+ readonly turn: AgentTurn;
1693
+ } | {
1694
+ readonly type: "ToolSettled";
1695
+ readonly callId: string;
1696
+ readonly result: R;
1697
+ } | {
1698
+ readonly type: "RunDone";
1699
+ readonly output: AgentTurn | null;
1700
+ };
1701
+ /**
1702
+ * Project one APPLIED agent transition `(msg, state)` to its semantic
1703
+ * {@link AgentEvent}s — the `events` projector a consumer passes to
1704
+ * `run(machine, { events: agentEvents() })` to light up `runtime.on(...)`.
1705
+ *
1706
+ * This is the ONE place the agent's PRIVATE Msg names are read: it maps
1707
+ * `resilient_ok` → `TurnSettled` and `agent_tool_ok` → `ToolSettled`, and reads
1708
+ * the post-transition `run.phase` for `RunDone`. The mapping is total over the
1709
+ * Msg union (a `default`-free switch on the discriminant) and returns `[]` for
1710
+ * the transitions that carry no public event (start / boot / timer / the error
1711
+ * arms), so a private name never escapes into `AgentEvent`.
1712
+ *
1713
+ * A single transition may emit more than one event: the brain turn that retires
1714
+ * the final stage settles a turn (`TurnSettled`) AND finishes the run
1715
+ * (`RunDone`) — both are projected from that one `resilient_ok` transition.
1716
+ * `RunDone` is gated on `run.phase === "done"`, which the wired loop reaches
1717
+ * exactly once (the agent is terminal there and dispatches no further
1718
+ * transition), so the event fires once per run.
1719
+ *
1720
+ * A `ToolSettled` is gated on `state.refusedCalls` (#145): a call whose public
1721
+ * outcome was already a failure — the ladder's `timeout` / `retry_exhausted`,
1722
+ * or the tool's own error — never emits a success here, however late its
1723
+ * abandoned attempt resolves. Both settle arms read the same list, so a
1724
+ * router-wired agent and a fan-out-wired one are silent on the same calls, and
1725
+ * the decision is made in the PURE layer rather than filtered at a
1726
+ * subscription seam — `runtime.on` and `defineAgent`'s `onEvent` see one
1727
+ * stream.
1728
+ *
1729
+ * A machine wired with `toMachine({ tools })` settles tools through the
1730
+ * router's `<name>_ok` Msgs instead of `agent_tool_ok`; pass the same router
1731
+ * here so those settles project to `ToolSettled` too.
1732
+ *
1733
+ * PURE — reads only the passed `(msg, state)`; no clock, no RNG, no throw.
1734
+ *
1735
+ * @typeParam P Brain-call purposes.
1736
+ * @typeParam O Per-purpose outputs (bound to `AgentTurn`, the agentic shape).
1737
+ * @typeParam R Tool result type.
1738
+ * @typeParam Stage Pipeline stage type.
1739
+ * @typeParam T The router's tool defs, when one is wired.
1740
+ */
1741
+ declare function agentEvents<Stage, P extends string, O extends Record<P, AgentTurn>, R, T extends AnyToolDef = never>(opts?: {
1742
+ readonly tools?: ToolRouter<T>;
1743
+ }): (msg: AgentMachineMsg<P, O, R> | WiredToolMsg<T>, state: AgentState<Stage, P, O, R>) => readonly AgentEvent<R>[];
1744
+ /**
1745
+ * Join two `Interpret` dictionaries over DISJOINT Cmd subsets `A` and `B` (over
1746
+ * the same Msg union `M` and Ctx) into the full `Interpret<M, A | B, Ctx>`. The
1747
+ * agent uses it to merge the consumer's per-tool / snapshot interpret (`A`) with
1748
+ * the agent-owned brain-call handler (`B = AgentLlmRunCmd`) into the wired
1749
+ * machine's single interpret table.
1750
+ *
1751
+ * The runtime result is exactly the spread of the two key-disjoint records. The
1752
+ * single `as` is a SOUND mapped-type identity, not a laundering cast: `Interpret`
1753
+ * is a homomorphic mapped type keyed by `Cmd["type"]`, so
1754
+ * `Interpret<M, A, Ctx> & Interpret<M, B, Ctx>` IS `Interpret<M, A | B, Ctx>`
1755
+ * (`(A | B)["type"] = A["type"] | B["type"]`). TypeScript does not reduce that
1756
+ * intersection of two GENERIC mapped types on its own, so the equality is
1757
+ * asserted ONCE here — preserving `M` and `Ctx` exactly — rather than smuggled
1758
+ * through `as unknown as Interpret<...>` at every wiring site. Pure.
1759
+ */
1760
+ declare function mergeInterpret<M extends {
1761
+ type: string;
1762
+ }, A extends Cmd, B extends Cmd, Ctx>(a: Interpret<M, A, Ctx> | undefined, b: Interpret<M, B, Ctx>): Interpret<M, A | B, Ctx>;
1763
+ /**
1764
+ * Lift an agent result `[slice, cmds]` into a host `[State, cmds]` where the slice
1765
+ * lives at `state.agent`. Convenience for a host that nests the agent slice
1766
+ * under a named field; the single-slice host uses the verbs' tuple directly.
1767
+ * PURE — a thin record rebuild, no clock / RNG.
1768
+ */
1769
+ declare function liftAgent<S extends {
1770
+ agent: AgentState<Stage, P, O, R>;
1771
+ }, Stage, P extends string, O extends Record<P, unknown>, R, C extends Cmd>(state: S, [slice, cmds]: readonly [AgentState<Stage, P, O, R>, readonly C[]]): readonly [S, readonly C[]];
1772
+
1773
+ export { PLAIN_MODEL_MISROUTE_REASON as $, type AnyToolDef as A, type AgentSnapshotConfig as B, type Conversation as C, type AgentStatus as D, type AgentTerminalFailure as E, type AgentTimerMsg as F, type AgentToMachine as G, type Awaiting as H, COMPACTION_PURPOSE as I, type CompactInterpret as J, type CompactionOutputs as K, type CompactionPurpose as L, type CompactionSummary as M, type LlmCall as N, type LlmErr as O, type PlainModel as P, type LlmFailMsg as Q, type LlmOk as R, type StreamingModel as S, type ToolCall as T, type LlmRunCmd as U, type LlmSucceedMsg as V, type WiredToolMsg as W, type MessageLoader as X, type ModelFactory as Y, type ModelPort as Z, type ModelStream as _, type ToolOutcome as a, type ReservedToolName as a0, type Schema as a1, type SnapshotInterpret as a2, TOOL_RETRY_EXHAUSTED_TAG as a3, TOOL_TIMEOUT_TAG as a4, type TaggedFailure as a5, type ToolConstructors as a6, type ToolDef as a7, type ToolError as a8, type ToolFail as a9, liftAgent as aA, mergeInterpret as aB, plainModel as aC, status as aD, tool as aE, toolErrorReason as aF, toolRouter as aG, type ToolFailure as aa, type ToolHandler as ab, type ToolInput as ac, type ToolMsg as ad, type ToolOk as ae, type ToolRecord as af, type ToolRejectedCmd as ag, type ToolRejection as ah, type ToolResilience as ai, type ToolResilienceError as aj, type ToolRetryExhausted as ak, type ToolRouter as al, type ToolSettlement as am, type ToolThrown as an, type ToolTimedOut as ao, type WiredToolCmd as ap, agentBootMsg as aq, agentCancelMsg as ar, agentEvents as as, agentTurnSchema as at, compactionSummarySchema as au, fanOutInterpret as av, isAgentTurn as aw, isCompactionSummary as ax, isReservedToolName as ay, isStreamingModel as az, type AgentTurn as b, type AgentState as c, type ToolResult as d, type ToolFailureOf as e, type ToolCmd as f, type AgentEvent as g, type TurnChunk as h, type AgentMachineMsg as i, type AgentCmd as j, type AgentConfigCore as k, type CompactionPolicy as l, type AgentKnob as m, type AgentBootMsg as n, type AgentCancelMsg as o, type AgentCompactErrMsg as p, type AgentCompactOkMsg as q, type AgentCompactRunCmd as r, type AgentCompactionConfig as s, type AgentConfig as t, type AgentDetachedHandlers as u, type AgentFailure as v, type AgentLlmErrMsg as w, type AgentLlmOkMsg as x, type AgentLlmRunCmd as y, type AgentPorts as z };