@animalabs/agent-framework 0.23.3 → 0.24.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (355) hide show
  1. package/README.md +212 -42
  2. package/dist/src/agent.d.ts +65 -9
  3. package/dist/src/agent.d.ts.map +1 -1
  4. package/dist/src/agent.js +98 -12
  5. package/dist/src/agent.js.map +1 -1
  6. package/dist/src/api/server.d.ts.map +1 -1
  7. package/dist/src/api/server.js +14 -12
  8. package/dist/src/api/server.js.map +1 -1
  9. package/dist/src/clock-rows.d.ts +115 -0
  10. package/dist/src/clock-rows.d.ts.map +1 -0
  11. package/dist/src/clock-rows.js +222 -0
  12. package/dist/src/clock-rows.js.map +1 -0
  13. package/dist/src/code-execution/engine.d.ts +177 -0
  14. package/dist/src/code-execution/engine.d.ts.map +1 -0
  15. package/dist/src/code-execution/engine.js +494 -0
  16. package/dist/src/code-execution/engine.js.map +1 -0
  17. package/dist/src/code-execution/index.d.ts +5 -10
  18. package/dist/src/code-execution/index.d.ts.map +1 -1
  19. package/dist/src/code-execution/index.js +5 -9
  20. package/dist/src/code-execution/index.js.map +1 -1
  21. package/dist/src/code-execution/isolate/calls.d.ts +114 -0
  22. package/dist/src/code-execution/isolate/calls.d.ts.map +1 -0
  23. package/dist/src/code-execution/isolate/calls.js +145 -0
  24. package/dist/src/code-execution/isolate/calls.js.map +1 -0
  25. package/dist/src/code-execution/isolate/child-entry.d.ts +2 -0
  26. package/dist/src/code-execution/isolate/child-entry.d.ts.map +1 -0
  27. package/dist/src/code-execution/isolate/child-entry.js +5 -0
  28. package/dist/src/code-execution/isolate/child-entry.js.map +1 -0
  29. package/dist/src/code-execution/isolate/child-main.d.ts +26 -0
  30. package/dist/src/code-execution/isolate/child-main.d.ts.map +1 -0
  31. package/dist/src/code-execution/isolate/child-main.js +132 -0
  32. package/dist/src/code-execution/isolate/child-main.js.map +1 -0
  33. package/dist/src/code-execution/isolate/child.d.ts +44 -0
  34. package/dist/src/code-execution/isolate/child.d.ts.map +1 -0
  35. package/dist/src/code-execution/isolate/child.js +315 -0
  36. package/dist/src/code-execution/isolate/child.js.map +1 -0
  37. package/dist/src/code-execution/isolate/frames.d.ts +80 -0
  38. package/dist/src/code-execution/isolate/frames.d.ts.map +1 -0
  39. package/dist/src/code-execution/isolate/frames.js +210 -0
  40. package/dist/src/code-execution/isolate/frames.js.map +1 -0
  41. package/dist/src/code-execution/isolate/output.d.ts +68 -0
  42. package/dist/src/code-execution/isolate/output.d.ts.map +1 -0
  43. package/dist/src/code-execution/isolate/output.js +143 -0
  44. package/dist/src/code-execution/isolate/output.js.map +1 -0
  45. package/dist/src/code-execution/isolate/prelude.d.ts +109 -0
  46. package/dist/src/code-execution/isolate/prelude.d.ts.map +1 -0
  47. package/dist/src/code-execution/isolate/prelude.js +401 -0
  48. package/dist/src/code-execution/isolate/prelude.js.map +1 -0
  49. package/dist/src/code-execution/isolate/protocol.d.ts +151 -0
  50. package/dist/src/code-execution/isolate/protocol.d.ts.map +1 -0
  51. package/dist/src/code-execution/isolate/protocol.js +150 -0
  52. package/dist/src/code-execution/isolate/protocol.js.map +1 -0
  53. package/dist/src/code-execution/isolate/render.d.ts +57 -0
  54. package/dist/src/code-execution/isolate/render.d.ts.map +1 -0
  55. package/dist/src/code-execution/isolate/render.js +214 -0
  56. package/dist/src/code-execution/isolate/render.js.map +1 -0
  57. package/dist/src/code-execution/isolate/runner.d.ts +250 -0
  58. package/dist/src/code-execution/isolate/runner.d.ts.map +1 -0
  59. package/dist/src/code-execution/isolate/runner.js +854 -0
  60. package/dist/src/code-execution/isolate/runner.js.map +1 -0
  61. package/dist/src/code-execution/isolate/scripts.d.ts +175 -0
  62. package/dist/src/code-execution/isolate/scripts.d.ts.map +1 -0
  63. package/dist/src/code-execution/isolate/scripts.js +357 -0
  64. package/dist/src/code-execution/isolate/scripts.js.map +1 -0
  65. package/dist/src/code-execution/quickjs.wasm +0 -0
  66. package/dist/src/code-execution/tool-definition.d.ts +93 -43
  67. package/dist/src/code-execution/tool-definition.d.ts.map +1 -1
  68. package/dist/src/code-execution/tool-definition.js +176 -142
  69. package/dist/src/code-execution/tool-definition.js.map +1 -1
  70. package/dist/src/deadline-timer.d.ts +3 -0
  71. package/dist/src/deadline-timer.d.ts.map +1 -1
  72. package/dist/src/deadline-timer.js +1 -1
  73. package/dist/src/deadline-timer.js.map +1 -1
  74. package/dist/src/framework.d.ts +1120 -457
  75. package/dist/src/framework.d.ts.map +1 -1
  76. package/dist/src/framework.js +4635 -2505
  77. package/dist/src/framework.js.map +1 -1
  78. package/dist/src/gate/event-gate.d.ts +28 -4
  79. package/dist/src/gate/event-gate.d.ts.map +1 -1
  80. package/dist/src/gate/event-gate.js +89 -13
  81. package/dist/src/gate/event-gate.js.map +1 -1
  82. package/dist/src/held-writes.d.ts +16 -3
  83. package/dist/src/held-writes.d.ts.map +1 -1
  84. package/dist/src/held-writes.js +16 -3
  85. package/dist/src/held-writes.js.map +1 -1
  86. package/dist/src/index.d.ts +8 -6
  87. package/dist/src/index.d.ts.map +1 -1
  88. package/dist/src/index.js +10 -8
  89. package/dist/src/index.js.map +1 -1
  90. package/dist/src/mcpl/channel-registry.d.ts +483 -115
  91. package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
  92. package/dist/src/mcpl/channel-registry.js +1735 -425
  93. package/dist/src/mcpl/channel-registry.js.map +1 -1
  94. package/dist/src/mcpl/conversation-router.d.ts +19 -39
  95. package/dist/src/mcpl/conversation-router.d.ts.map +1 -1
  96. package/dist/src/mcpl/conversation-router.js +27 -59
  97. package/dist/src/mcpl/conversation-router.js.map +1 -1
  98. package/dist/src/mcpl/convert-block.d.ts.map +1 -1
  99. package/dist/src/mcpl/convert-block.js +9 -5
  100. package/dist/src/mcpl/convert-block.js.map +1 -1
  101. package/dist/src/mcpl/inbound-source.d.ts +50 -0
  102. package/dist/src/mcpl/inbound-source.d.ts.map +1 -1
  103. package/dist/src/mcpl/inbound-source.js +130 -0
  104. package/dist/src/mcpl/inbound-source.js.map +1 -1
  105. package/dist/src/mcpl/index.d.ts +2 -1
  106. package/dist/src/mcpl/index.d.ts.map +1 -1
  107. package/dist/src/mcpl/index.js +3 -2
  108. package/dist/src/mcpl/index.js.map +1 -1
  109. package/dist/src/mcpl/log-value.d.ts +6 -0
  110. package/dist/src/mcpl/log-value.d.ts.map +1 -1
  111. package/dist/src/mcpl/log-value.js +8 -0
  112. package/dist/src/mcpl/log-value.js.map +1 -1
  113. package/dist/src/mcpl/modern-connection.d.ts +15 -6
  114. package/dist/src/mcpl/modern-connection.d.ts.map +1 -1
  115. package/dist/src/mcpl/modern-connection.js +168 -53
  116. package/dist/src/mcpl/modern-connection.js.map +1 -1
  117. package/dist/src/mcpl/prose-grammar.d.ts +4 -5
  118. package/dist/src/mcpl/prose-grammar.d.ts.map +1 -1
  119. package/dist/src/mcpl/prose-grammar.js +4 -5
  120. package/dist/src/mcpl/prose-grammar.js.map +1 -1
  121. package/dist/src/mcpl/protocol-family.d.ts +97 -10
  122. package/dist/src/mcpl/protocol-family.d.ts.map +1 -1
  123. package/dist/src/mcpl/protocol-family.js +174 -17
  124. package/dist/src/mcpl/protocol-family.js.map +1 -1
  125. package/dist/src/mcpl/push-coalescer.d.ts +132 -14
  126. package/dist/src/mcpl/push-coalescer.d.ts.map +1 -1
  127. package/dist/src/mcpl/push-coalescer.js +227 -50
  128. package/dist/src/mcpl/push-coalescer.js.map +1 -1
  129. package/dist/src/mcpl/push-handler.d.ts +9 -20
  130. package/dist/src/mcpl/push-handler.d.ts.map +1 -1
  131. package/dist/src/mcpl/push-handler.js +7 -49
  132. package/dist/src/mcpl/push-handler.js.map +1 -1
  133. package/dist/src/mcpl/reference-fetcher.d.ts +2 -2
  134. package/dist/src/mcpl/reference-fetcher.d.ts.map +1 -1
  135. package/dist/src/mcpl/reference-fetcher.js +4 -4
  136. package/dist/src/mcpl/reference-fetcher.js.map +1 -1
  137. package/dist/src/mcpl/server-connection.d.ts +50 -21
  138. package/dist/src/mcpl/server-connection.d.ts.map +1 -1
  139. package/dist/src/mcpl/server-connection.js +158 -74
  140. package/dist/src/mcpl/server-connection.js.map +1 -1
  141. package/dist/src/mcpl/tags.d.ts +24 -0
  142. package/dist/src/mcpl/tags.d.ts.map +1 -1
  143. package/dist/src/mcpl/tags.js +33 -0
  144. package/dist/src/mcpl/tags.js.map +1 -1
  145. package/dist/src/mcpl/tool-result-normalize.d.ts +2 -1
  146. package/dist/src/mcpl/tool-result-normalize.d.ts.map +1 -1
  147. package/dist/src/mcpl/tool-result-normalize.js.map +1 -1
  148. package/dist/src/mcpl/transport.d.ts +55 -7
  149. package/dist/src/mcpl/transport.d.ts.map +1 -1
  150. package/dist/src/mcpl/transport.js +163 -34
  151. package/dist/src/mcpl/transport.js.map +1 -1
  152. package/dist/src/mcpl/types.d.ts +22 -6
  153. package/dist/src/mcpl/types.d.ts.map +1 -1
  154. package/dist/src/mcpl/types.js.map +1 -1
  155. package/dist/src/module-registry.d.ts +4 -2
  156. package/dist/src/module-registry.d.ts.map +1 -1
  157. package/dist/src/module-registry.js +100 -13
  158. package/dist/src/module-registry.js.map +1 -1
  159. package/dist/src/modules/discord/index.d.ts.map +1 -1
  160. package/dist/src/modules/discord/index.js +8 -13
  161. package/dist/src/modules/discord/index.js.map +1 -1
  162. package/dist/src/modules/history/index.d.ts.map +1 -1
  163. package/dist/src/modules/history/index.js +27 -4
  164. package/dist/src/modules/history/index.js.map +1 -1
  165. package/dist/src/modules/history/semantic.d.ts +15 -3
  166. package/dist/src/modules/history/semantic.d.ts.map +1 -1
  167. package/dist/src/modules/history/semantic.js +27 -5
  168. package/dist/src/modules/history/semantic.js.map +1 -1
  169. package/dist/src/modules/index.d.ts +1 -1
  170. package/dist/src/modules/index.d.ts.map +1 -1
  171. package/dist/src/modules/index.js.map +1 -1
  172. package/dist/src/modules/unknown-tool.d.ts +4 -1
  173. package/dist/src/modules/unknown-tool.d.ts.map +1 -1
  174. package/dist/src/modules/unknown-tool.js +4 -1
  175. package/dist/src/modules/unknown-tool.js.map +1 -1
  176. package/dist/src/modules/workspace/branch-intent.d.ts +3 -1
  177. package/dist/src/modules/workspace/branch-intent.d.ts.map +1 -1
  178. package/dist/src/modules/workspace/branch-intent.js +3 -1
  179. package/dist/src/modules/workspace/branch-intent.js.map +1 -1
  180. package/dist/src/modules/workspace/edit-plan.d.ts +265 -0
  181. package/dist/src/modules/workspace/edit-plan.d.ts.map +1 -0
  182. package/dist/src/modules/workspace/edit-plan.js +794 -0
  183. package/dist/src/modules/workspace/edit-plan.js.map +1 -0
  184. package/dist/src/modules/workspace/edit-text.d.ts +117 -0
  185. package/dist/src/modules/workspace/edit-text.d.ts.map +1 -0
  186. package/dist/src/modules/workspace/edit-text.js +584 -0
  187. package/dist/src/modules/workspace/edit-text.js.map +1 -0
  188. package/dist/src/modules/workspace/effects.d.ts +5 -4
  189. package/dist/src/modules/workspace/effects.d.ts.map +1 -1
  190. package/dist/src/modules/workspace/effects.js +78 -25
  191. package/dist/src/modules/workspace/effects.js.map +1 -1
  192. package/dist/src/modules/workspace/index.d.ts +493 -62
  193. package/dist/src/modules/workspace/index.d.ts.map +1 -1
  194. package/dist/src/modules/workspace/index.js +2216 -652
  195. package/dist/src/modules/workspace/index.js.map +1 -1
  196. package/dist/src/modules/workspace/observe.d.ts +213 -38
  197. package/dist/src/modules/workspace/observe.d.ts.map +1 -1
  198. package/dist/src/modules/workspace/observe.js +416 -36
  199. package/dist/src/modules/workspace/observe.js.map +1 -1
  200. package/dist/src/modules/workspace/reconcile.d.ts.map +1 -1
  201. package/dist/src/modules/workspace/reconcile.js +15 -8
  202. package/dist/src/modules/workspace/reconcile.js.map +1 -1
  203. package/dist/src/modules/workspace/text.d.ts +32 -0
  204. package/dist/src/modules/workspace/text.d.ts.map +1 -0
  205. package/dist/src/modules/workspace/text.js +67 -0
  206. package/dist/src/modules/workspace/text.js.map +1 -0
  207. package/dist/src/modules/workspace/types.d.ts +210 -6
  208. package/dist/src/modules/workspace/types.d.ts.map +1 -1
  209. package/dist/src/modules/workspace/types.js.map +1 -1
  210. package/dist/src/modules/workspace/watcher.d.ts +3 -2
  211. package/dist/src/modules/workspace/watcher.d.ts.map +1 -1
  212. package/dist/src/modules/workspace/watcher.js.map +1 -1
  213. package/dist/src/operator-log.d.ts +52 -24
  214. package/dist/src/operator-log.d.ts.map +1 -1
  215. package/dist/src/operator-log.js.map +1 -1
  216. package/dist/src/recovery/discord-awareness-outbox.d.ts +496 -72
  217. package/dist/src/recovery/discord-awareness-outbox.d.ts.map +1 -1
  218. package/dist/src/recovery/discord-awareness-outbox.js +1196 -289
  219. package/dist/src/recovery/discord-awareness-outbox.js.map +1 -1
  220. package/dist/src/recovery/offline-branch.d.ts +26 -1
  221. package/dist/src/recovery/offline-branch.d.ts.map +1 -1
  222. package/dist/src/recovery/offline-branch.js +164 -39
  223. package/dist/src/recovery/offline-branch.js.map +1 -1
  224. package/dist/src/recovery/recover-cli.js +23 -4
  225. package/dist/src/recovery/recover-cli.js.map +1 -1
  226. package/dist/src/send-tools.d.ts +11 -0
  227. package/dist/src/send-tools.d.ts.map +1 -0
  228. package/dist/src/send-tools.js +11 -0
  229. package/dist/src/send-tools.js.map +1 -0
  230. package/dist/src/timezone.d.ts +4 -2
  231. package/dist/src/timezone.d.ts.map +1 -1
  232. package/dist/src/timezone.js +4 -2
  233. package/dist/src/timezone.js.map +1 -1
  234. package/dist/src/tool-image-ledger.d.ts +46 -7
  235. package/dist/src/tool-image-ledger.d.ts.map +1 -1
  236. package/dist/src/tool-image-ledger.js +60 -7
  237. package/dist/src/tool-image-ledger.js.map +1 -1
  238. package/dist/src/tool-result-guard.d.ts +14 -11
  239. package/dist/src/tool-result-guard.d.ts.map +1 -1
  240. package/dist/src/tool-result-guard.js +17 -14
  241. package/dist/src/tool-result-guard.js.map +1 -1
  242. package/dist/src/tool-result-history.d.ts +3 -2
  243. package/dist/src/tool-result-history.d.ts.map +1 -1
  244. package/dist/src/tool-result-history.js +3 -2
  245. package/dist/src/tool-result-history.js.map +1 -1
  246. package/dist/src/tune-out/coordinator.d.ts +21 -0
  247. package/dist/src/tune-out/coordinator.d.ts.map +1 -1
  248. package/dist/src/tune-out/coordinator.js +142 -40
  249. package/dist/src/tune-out/coordinator.js.map +1 -1
  250. package/dist/src/types/agent.d.ts +31 -6
  251. package/dist/src/types/agent.d.ts.map +1 -1
  252. package/dist/src/types/events.d.ts +66 -9
  253. package/dist/src/types/events.d.ts.map +1 -1
  254. package/dist/src/types/framework.d.ts +69 -62
  255. package/dist/src/types/framework.d.ts.map +1 -1
  256. package/dist/src/types/module.d.ts +40 -8
  257. package/dist/src/types/module.d.ts.map +1 -1
  258. package/dist/src/types/trace.d.ts +111 -10
  259. package/dist/src/types/trace.d.ts.map +1 -1
  260. package/dist/src/usage/types.d.ts +16 -0
  261. package/dist/src/usage/types.d.ts.map +1 -1
  262. package/dist/src/usage/usage-tracker.d.ts +14 -1
  263. package/dist/src/usage/usage-tracker.d.ts.map +1 -1
  264. package/dist/src/usage/usage-tracker.js +81 -41
  265. package/dist/src/usage/usage-tracker.js.map +1 -1
  266. package/package.json +6 -8
  267. package/src/agent.ts +99 -12
  268. package/src/api/server.ts +14 -12
  269. package/src/clock-rows.ts +302 -0
  270. package/src/code-execution/engine.ts +595 -0
  271. package/src/code-execution/index.ts +5 -17
  272. package/src/code-execution/isolate/calls.ts +199 -0
  273. package/src/code-execution/isolate/child-entry.ts +5 -0
  274. package/src/code-execution/isolate/child-main.ts +132 -0
  275. package/src/code-execution/isolate/child.ts +327 -0
  276. package/src/code-execution/isolate/frames.ts +209 -0
  277. package/src/code-execution/isolate/output.ts +161 -0
  278. package/src/code-execution/isolate/prelude.ts +409 -0
  279. package/src/code-execution/isolate/protocol.ts +240 -0
  280. package/src/code-execution/isolate/render.ts +230 -0
  281. package/src/code-execution/isolate/runner.ts +911 -0
  282. package/src/code-execution/isolate/scripts.ts +479 -0
  283. package/src/code-execution/quickjs.wasm +0 -0
  284. package/src/code-execution/quickjs.wasm.LICENSES +149 -0
  285. package/src/code-execution/tool-definition.ts +236 -167
  286. package/src/deadline-timer.ts +1 -1
  287. package/src/framework.ts +4978 -2671
  288. package/src/gate/event-gate.ts +79 -17
  289. package/src/held-writes.ts +17 -3
  290. package/src/index.ts +32 -22
  291. package/src/mcpl/channel-registry.ts +1892 -471
  292. package/src/mcpl/conversation-router.ts +26 -72
  293. package/src/mcpl/convert-block.ts +9 -5
  294. package/src/mcpl/inbound-source.ts +131 -0
  295. package/src/mcpl/index.ts +4 -2
  296. package/src/mcpl/log-value.ts +9 -0
  297. package/src/mcpl/modern-connection.ts +162 -53
  298. package/src/mcpl/prose-grammar.ts +4 -5
  299. package/src/mcpl/protocol-family.ts +200 -22
  300. package/src/mcpl/push-coalescer.ts +306 -62
  301. package/src/mcpl/push-handler.ts +12 -54
  302. package/src/mcpl/reference-fetcher.ts +4 -4
  303. package/src/mcpl/server-connection.ts +180 -79
  304. package/src/mcpl/tags.ts +36 -0
  305. package/src/mcpl/tool-result-normalize.ts +2 -1
  306. package/src/mcpl/transport.ts +162 -33
  307. package/src/mcpl/types.ts +23 -6
  308. package/src/module-registry.ts +92 -13
  309. package/src/modules/discord/index.ts +8 -13
  310. package/src/modules/history/index.ts +25 -3
  311. package/src/modules/history/semantic.ts +29 -6
  312. package/src/modules/index.ts +1 -0
  313. package/src/modules/unknown-tool.ts +4 -1
  314. package/src/modules/workspace/branch-intent.ts +3 -1
  315. package/src/modules/workspace/edit-plan.ts +954 -0
  316. package/src/modules/workspace/edit-text.ts +618 -0
  317. package/src/modules/workspace/effects.ts +70 -19
  318. package/src/modules/workspace/index.ts +2293 -650
  319. package/src/modules/workspace/observe.ts +465 -56
  320. package/src/modules/workspace/reconcile.ts +14 -7
  321. package/src/modules/workspace/text.ts +68 -0
  322. package/src/modules/workspace/types.ts +211 -6
  323. package/src/modules/workspace/watcher.ts +3 -2
  324. package/src/operator-log.ts +47 -19
  325. package/src/recovery/discord-awareness-outbox.ts +1500 -356
  326. package/src/recovery/offline-branch.ts +189 -55
  327. package/src/recovery/recover-cli.ts +25 -4
  328. package/src/send-tools.ts +11 -0
  329. package/src/timezone.ts +4 -2
  330. package/src/tool-image-ledger.ts +62 -8
  331. package/src/tool-result-guard.ts +18 -15
  332. package/src/tool-result-history.ts +3 -2
  333. package/src/tune-out/coordinator.ts +166 -45
  334. package/src/types/agent.ts +32 -6
  335. package/src/types/events.ts +66 -9
  336. package/src/types/framework.ts +69 -62
  337. package/src/types/module.ts +40 -8
  338. package/src/types/trace.ts +121 -15
  339. package/src/usage/types.ts +16 -0
  340. package/src/usage/usage-tracker.ts +86 -43
  341. package/dist/src/code-execution/py-runner.d.ts +0 -191
  342. package/dist/src/code-execution/py-runner.d.ts.map +0 -1
  343. package/dist/src/code-execution/py-runner.js +0 -655
  344. package/dist/src/code-execution/py-runner.js.map +0 -1
  345. package/dist/src/code-execution/runtime-py.d.ts +0 -50
  346. package/dist/src/code-execution/runtime-py.d.ts.map +0 -1
  347. package/dist/src/code-execution/runtime-py.js +0 -677
  348. package/dist/src/code-execution/runtime-py.js.map +0 -1
  349. package/dist/src/mcpl/prose-stream-router.d.ts +0 -88
  350. package/dist/src/mcpl/prose-stream-router.d.ts.map +0 -1
  351. package/dist/src/mcpl/prose-stream-router.js +0 -291
  352. package/dist/src/mcpl/prose-stream-router.js.map +0 -1
  353. package/src/code-execution/py-runner.ts +0 -791
  354. package/src/code-execution/runtime-py.ts +0 -677
  355. package/src/mcpl/prose-stream-router.ts +0 -268
@@ -14,6 +14,7 @@
14
14
  import { existsSync, readFileSync, statSync, writeFileSync, mkdirSync } from 'node:fs';
15
15
  import { dirname, join } from 'node:path';
16
16
  import { GateScript } from './gate-script.js';
17
+ import { MAX_TIMER_MS } from '../deadline-timer.js';
17
18
  import { safeSlice } from '../safe-slice.js';
18
19
 
19
20
  import type { ToolDefinition } from '../types/events.js';
@@ -130,9 +131,6 @@ export interface WakeProvenance {
130
131
  * (2026-09-30: a DM reply published into a guild channel). Ambient-only
131
132
  * batches still set nothing and keep the legacy fallback. */
132
133
  routeChannelId?: string;
133
- /** The server whose event `routeChannelId` came from: the turn's replies
134
- * to that channel go out through this server only. */
135
- routeServerId?: string;
136
134
  /** Timestamp (ms) of the chosen event, so a consumer coalescing several
137
135
  * requests can order by event recency, not by flush order. */
138
136
  at?: number;
@@ -238,9 +236,7 @@ export function wakeProvenance(events: PendingEvent[]): WakeProvenance | undefin
238
236
  ...(channelId ? { channelId } : {}),
239
237
  ...(pick.authorId ? { counterparty: `${ns}:user:${pick.authorId}` } : {}),
240
238
  ...(pick.addressed ? { addressed: true } : {}),
241
- ...(pick.addressed && pick.routeChannelId
242
- ? { routeChannelId: pick.routeChannelId, ...(pick.serverId ? { routeServerId: pick.serverId } : {}) }
243
- : {}),
239
+ ...(pick.addressed && pick.routeChannelId ? { routeChannelId: pick.routeChannelId } : {}),
244
240
  at: pick.timestamp,
245
241
  };
246
242
  }
@@ -607,6 +603,9 @@ export class EventGate {
607
603
  private sleepSuppressed = 0;
608
604
  private sleepTimer: ReturnType<typeof setTimeout> | null = null;
609
605
  private sleepAgent: string | undefined;
606
+ // From dispose() to the next resumeSleep(): no sleep or self-wake timer is
607
+ // armed, though a turn a failed stop() left running can still ask for one.
608
+ private disposed = false;
610
609
 
611
610
  // Self-wake timers per agent (skip_reply's wake_in_seconds). Unlike sleep,
612
611
  // a self-wake suppresses NOTHING — it means "if nothing else wakes me by
@@ -1053,11 +1052,13 @@ export class EventGate {
1053
1052
  // rouse the agent — its own heartbeat (an internal clock, not an outside
1054
1053
  // interruption: each tick lets the agent reconsider and optionally `wake`)
1055
1054
  // and a privileged user's ping. The event always enters context regardless
1056
- // (the gate only governs inference triggering).
1055
+ // (the gate only governs inference triggering). The heartbeat is the
1056
+ // server the host knows as `heartbeat`, the server id the silent-heartbeat
1057
+ // marker requires too: a `source` in an event's metadata is the server's
1058
+ // own word, which any server can give.
1057
1059
  if (this.sleepUntil > this.now()) {
1058
1060
  this.reloadPrivilegedIfChanged();
1059
- const isHeartbeat =
1060
- info.metadata?.source === 'heartbeat' || info.serverId === 'heartbeat';
1061
+ const isHeartbeat = info.serverId === 'heartbeat';
1061
1062
  const authorId = this.extractAuthorId(info.metadata);
1062
1063
  const privileged = authorId !== null && this.privilegedUserIds.has(authorId);
1063
1064
  if (!isHeartbeat && !privileged) {
@@ -1738,9 +1739,9 @@ export class EventGate {
1738
1739
  this.sleepSuppressed = 0;
1739
1740
  // Arm the self-wake: when the window elapses, clear sleep and request an
1740
1741
  // inference so the agent resumes on its own (not dependent on a heartbeat
1741
- // tick or an incoming message). Cancelled by clearSleep()/`wake`.
1742
- if (this.sleepTimer) clearTimeout(this.sleepTimer);
1743
- this.sleepTimer = setTimeout(() => this.wakeFromSleep('sleep-expired'), ms);
1742
+ // tick or an incoming message). Cancelled by clearSleep()/`wake`, and by
1743
+ // dispose(), after which start() arms it again (resumeSleep).
1744
+ this.armSleepWake();
1744
1745
  this.reloadPrivilegedIfChanged();
1745
1746
  this.emitTrace({
1746
1747
  type: 'gate:decision',
@@ -1753,6 +1754,48 @@ export class EventGate {
1753
1754
  return { until: this.sleepUntil };
1754
1755
  }
1755
1756
 
1757
+ /**
1758
+ * Arm timers again for a lifecycle that starts after a stop(), and the
1759
+ * sleep's wake first: dispose() clears its timer and keeps the sleep. A
1760
+ * sleep still ahead wakes the agent at its end; one that ended while
1761
+ * stopped wakes it now, since that wake is what the agent asked for. With
1762
+ * no sleep, wakeFromSleep does nothing.
1763
+ */
1764
+ resumeSleep(): void {
1765
+ this.disposed = false;
1766
+ if (this.sleepUntil > this.now()) this.armSleepWake();
1767
+ else this.wakeFromSleep('sleep-expired');
1768
+ }
1769
+
1770
+ /**
1771
+ * Arm the sleep's wake for its end by the gate's own clock. One timer holds
1772
+ * at most MAX_TIMER_MS, about 24.8 days, so a longer sleep waits in steps,
1773
+ * and wakeFromSleep reads the clock as each one fires. Nothing is armed
1774
+ * while the gate is disposed: resumeSleep() arms it at the next start().
1775
+ */
1776
+ private armSleepWake(): void {
1777
+ if (this.sleepTimer) { clearTimeout(this.sleepTimer); this.sleepTimer = null; }
1778
+ if (this.disposed) return;
1779
+ const remaining = Math.max(0, this.sleepUntil - this.now());
1780
+ this.sleepTimer = setTimeout(() => this.wakeFromSleep('sleep-expired'), Math.min(remaining, MAX_TIMER_MS));
1781
+ }
1782
+
1783
+ /**
1784
+ * `agentName` is gone, as a conversation fork's end or an ephemeral run's
1785
+ * removes one: its pending self-wake is cancelled, and a sleep it set ends.
1786
+ * The gate's sleep holds back every agent's wakes, so nobody is asleep once
1787
+ * its agent is gone, and neither wake would reach a name that no longer
1788
+ * exists. A sleep another agent set, or one set with no agent, stays.
1789
+ */
1790
+ agentGone(agentName: string): void {
1791
+ const selfWake = this.selfWakeTimers.get(agentName);
1792
+ if (selfWake) {
1793
+ clearTimeout(selfWake);
1794
+ this.selfWakeTimers.delete(agentName);
1795
+ }
1796
+ if (this.sleepUntil !== 0 && this.sleepAgent === agentName) this.clearSleep();
1797
+ }
1798
+
1756
1799
  // =========================================================================
1757
1800
  // Self-wake (skip_reply wake_in_seconds)
1758
1801
  // =========================================================================
@@ -1764,8 +1807,11 @@ export class EventGate {
1764
1807
  * Cancelled by the agent's next turn start (see onInferenceStarted):
1765
1808
  * the semantics are "if nothing else wakes me by then, wake me".
1766
1809
  */
1767
- armSelfWake(agentName: string, seconds: number, source = 'skip_reply'): { inMs: number } {
1810
+ armSelfWake(agentName: string, seconds: number, source = 'skip_reply'): { inMs: number; armed: boolean } {
1768
1811
  const ms = Math.max(1_000, Math.min(3_600_000, Math.floor(seconds * 1000)));
1812
+ // A stopped framework's late turn arms no timer (disposed). A self-wake
1813
+ // doesn't outlive a stop, as dispose() clearing the pending ones says.
1814
+ if (this.disposed) return { inMs: ms, armed: false };
1769
1815
  const prev = this.selfWakeTimers.get(agentName);
1770
1816
  if (prev) clearTimeout(prev);
1771
1817
  const timer = setTimeout(() => {
@@ -1806,7 +1852,7 @@ export class EventGate {
1806
1852
  behavior: 'skip',
1807
1853
  timestamp: this.now(),
1808
1854
  });
1809
- return { inMs: ms };
1855
+ return { inMs: ms, armed: true };
1810
1856
  }
1811
1857
 
1812
1858
  /** End sleep immediately. Returns true if the agent was asleep. */
@@ -1824,11 +1870,20 @@ export class EventGate {
1824
1870
  * Clears the sleep state and requests an inference so the agent wakes on its
1825
1871
  * own — this is what makes `sleep(N)` a real "wake me in N seconds" rather
1826
1872
  * than just a suppression window. No-op if sleep was already cleared (via
1827
- * `wake`) or re-armed to a later time by a fresh `sleep` call.
1873
+ * `wake`). A timer that fires before the sleep's end by the gate's clock
1874
+ * arms the rest: a step of a sleep longer than one timer holds, a timer that
1875
+ * fires early (Node's can, by a millisecond), or a clock set back.
1828
1876
  */
1829
1877
  private wakeFromSleep(reason: string): void {
1830
- this.sleepTimer = null;
1831
- if (this.sleepUntil === 0 || this.sleepUntil > this.now()) return;
1878
+ // The timer that called it has fired; from resumeSleep(), for a sleep
1879
+ // already over, one may still be armed, and it goes, so no stale step of
1880
+ // it can fire later.
1881
+ if (this.sleepTimer) { clearTimeout(this.sleepTimer); this.sleepTimer = null; }
1882
+ if (this.sleepUntil === 0) return;
1883
+ if (this.sleepUntil > this.now()) {
1884
+ this.armSleepWake();
1885
+ return;
1886
+ }
1832
1887
  const note = this.sleepNote;
1833
1888
  const agent = this.sleepAgent;
1834
1889
  this.sleepUntil = 0;
@@ -2006,6 +2061,13 @@ export class EventGate {
2006
2061
  clearTimeout(timer);
2007
2062
  }
2008
2063
  this.selfWakeTimers.clear();
2064
+ // The sleep stays, with its note and agent, and its timer goes: fired
2065
+ // after a stop(), its wake reached a framework that had stopped, and the
2066
+ // timer held the process until the sleep's end. The next start() arms it
2067
+ // again (resumeSleep). Until then nothing arms one, nor a self-wake: a
2068
+ // turn a failed stop() left running can still call sleep or skip_reply.
2069
+ if (this.sleepTimer) { clearTimeout(this.sleepTimer); this.sleepTimer = null; }
2070
+ this.disposed = true;
2009
2071
  this.rateLimitBuckets.clear();
2010
2072
  this.passiveSampleCounters.clear();
2011
2073
  this.rateLimitDenied.clear();
@@ -25,9 +25,9 @@ export function heldWriteId(id: MessageId): string | undefined {
25
25
 
26
26
  /**
27
27
  * Whether a row matches `filter` as context-manager's queryMessages matches a
28
- * stored one. That's its MessageStore's private matchesFilter at 0.14.1, which
29
- * the package doesn't export, so the rule is copied here, and a test compares
30
- * the two on the same rows. A row matches the external source, one of the
28
+ * stored one. That's its MessageStore's private matchesFilter, the same at
29
+ * 0.14.1, 0.16.0, 0.17.1 and 0.18.0, which the package doesn't export, so the rule is copied
30
+ * here, and a test compares the two on the same rows. A row matches the external source, one of the
31
31
  * external ids (an empty list filters nothing), the participant, and each
32
32
  * metadata path, dot-separated, by strict equality.
33
33
  */
@@ -57,3 +57,17 @@ function valueAt(value: unknown, path: string): unknown {
57
57
  }
58
58
  return value;
59
59
  }
60
+
61
+ /**
62
+ * A row as a module's context answers it: marked `heldFromResidents` when it
63
+ * carries the stamp a tune-out puts on a message it holds from the residents
64
+ * (`metadata.tuneOut`). Every resident's viewFilter leaves a stamped row out
65
+ * of its compiled view (framework.ts, createAgent), and a tool boundary
66
+ * stores a stamped write without injecting it into the live turn, so a
67
+ * marked row is one the store keeps and no resident is shown
68
+ * (ModuleMessage.heldFromResidents says where its text can still reach
69
+ * one). Any other row comes back as it is.
70
+ */
71
+ export function asModuleRow<T extends Pick<StoredMessage, 'metadata'>>(row: T): T & { heldFromResidents?: true } {
72
+ return (row.metadata as { tuneOut?: unknown } | undefined)?.tuneOut ? { ...row, heldFromResidents: true } : row;
73
+ }
package/src/index.ts CHANGED
@@ -10,6 +10,8 @@ export { ProcessQueueImpl } from './queue.js';
10
10
  export { ModuleRegistry } from './module-registry.js';
11
11
  export { ShutdownTimeoutError, DEFAULT_SHUTDOWN_TIMEOUT_MS } from './shutdown.js';
12
12
  export { formatZonedDateTime, formatZonedTime, isValidTimeZone, resolveTimeZone } from './timezone.js';
13
+ export { CLOCK_ROW_KIND, resolveClockConfig } from './clock-rows.js';
14
+ export type { ClockConfig, ClockStamp, ResolvedClockConfig } from './clock-rows.js';
13
15
  export { REFUSAL_REACTIONS, REFUSAL_REACTION_FALLBACK, REFUSAL_REACTION_BASELINE } from './refusal-reactions.js';
14
16
 
15
17
  // Built-in modules
@@ -59,23 +61,9 @@ export type {
59
61
  // Usage tracking
60
62
  export { UsageTracker } from './usage/index.js';
61
63
 
62
- // Client-side programmatic tool calling (code_execution): exposed so external
63
- // tooling can drive the python runtime the way the framework does (protocol
64
- // harnesses, runtime smoke tests).
65
- export {
66
- PyRunner,
67
- buildInjectedTools,
68
- buildCodeExecutionToolDefinition,
69
- CODE_EXECUTION_TOOL_NAME,
70
- PYTHON_RUNTIME_SOURCE,
71
- } from './code-execution/index.js';
72
- export type {
73
- InjectedTool,
74
- ExecResult,
75
- PyRunnerOptions,
76
- ScriptToolCallHandler,
77
- ScriptToolResult,
78
- } from './code-execution/index.js';
64
+ // Client-side programmatic tool calling (code_execution): the tool's name,
65
+ // and its definition as an agent reads it.
66
+ export { buildCodeExecutionToolDefinition, CODE_EXECUTION_TOOL_NAME } from './code-execution/index.js';
79
67
  export type { SessionUsage, AgentUsage, SessionUsageSnapshot, UsageUpdatedEvent } from './usage/index.js';
80
68
 
81
69
  // EventGate
@@ -84,9 +72,12 @@ export type { GateConfig, GateOptions, GatePolicy, GatePolicyMatch, GateBehavior
84
72
 
85
73
  // MCPL channel registry (exposed for modules that need channel-level operations)
86
74
  export { ChannelRegistry } from './mcpl/index.js';
75
+ export type { PublishRefusalReason } from './mcpl/index.js';
87
76
 
88
- // Where each accepted inbound item came from (`metadata.inboundSource`)
89
- export { INBOUND_SOURCE_KEY, readInboundSource, conversationKey } from './mcpl/index.js';
77
+ // Where each accepted inbound item came from (`metadata.inboundSource`), and
78
+ // the digest its delivered and stored bodies are stamped with
79
+ // (`metadata.sourceBodyDigest`, `metadata.storedBodyDigest`)
80
+ export { INBOUND_SOURCE_KEY, readInboundSource, conversationKey, sourceBodyDigest } from './mcpl/index.js';
90
81
  export type {
91
82
  InboundSource,
92
83
  InboundChannelSource,
@@ -150,18 +141,35 @@ export { PassthroughStrategy, AutobiographicalStrategy, KnowledgeStrategy } from
150
141
  export type { KnowledgeConfig, PhaseType } from '@animalabs/context-manager';
151
142
  export type { Membrane, NormalizedMessage, NormalizedRequest, ContentBlock } from '@animalabs/membrane';
152
143
 
153
- // Offline outage recovery and branch-independent Discord awareness markers
144
+ // Offline outage recovery and the Discord awareness-mark ledger
154
145
  export {
155
146
  DiscordAwarenessOutbox,
147
+ DiscordAwarenessRefusal,
156
148
  DEFAULT_DISCORD_AWARENESS_EMOJI,
157
149
  defaultDiscordAwarenessOutboxPath,
158
150
  extractDiscordAwarenessRefs,
151
+ isPermanentDiscordReactionFailure,
152
+ selectDiscordAwarenessRefs,
159
153
  } from './recovery/discord-awareness-outbox.js';
160
154
  export type {
155
+ DiscordAwarenessAction,
161
156
  DiscordAwarenessBatch,
162
- DiscordAwarenessEntry,
163
- DiscordAwarenessOperation,
157
+ DiscordAwarenessBatchStatus,
158
+ DiscordAwarenessBatchView,
159
+ DiscordAwarenessRetractView,
160
+ DiscordAwarenessView,
161
+ DiscordAwarenessCancelReceipt,
162
+ DiscordAwarenessMarks,
163
+ DiscordAwarenessOutcome,
164
+ DiscordAwarenessPrepareInput,
165
+ DiscordAwarenessReactionState,
166
+ DiscordAwarenessImportedUnsent,
164
167
  DiscordAwarenessRef,
168
+ DiscordAwarenessRequest,
169
+ DiscordAwarenessRetractReceipt,
170
+ DiscordAwarenessRetirement,
171
+ DiscordAwarenessScope,
172
+ DiscordAwarenessSettlement,
165
173
  DiscordSuppressionInterval,
166
174
  } from './recovery/discord-awareness-outbox.js';
167
175
  // Live operator surgery (rollback / suppress) and its durable action log
@@ -170,7 +178,9 @@ export type {
170
178
  OperatorLogEntry,
171
179
  OperatorLogInput,
172
180
  OperatorRequester,
181
+ SurgeryMarkerFacts,
173
182
  SurgeryMarkerReceipt,
183
+ SurgeryMarksPreview,
174
184
  } from './operator-log.js';
175
185
  export { createOfflineRecoveryBranch } from './recovery/offline-branch.js';
176
186
  export type {