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