@animalabs/agent-framework 0.23.2 → 0.24.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 (338) hide show
  1. package/README.md +212 -42
  2. package/dist/src/agent.d.ts +60 -9
  3. package/dist/src/agent.d.ts.map +1 -1
  4. package/dist/src/agent.js +92 -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/code-execution/engine.d.ts +177 -0
  10. package/dist/src/code-execution/engine.d.ts.map +1 -0
  11. package/dist/src/code-execution/engine.js +494 -0
  12. package/dist/src/code-execution/engine.js.map +1 -0
  13. package/dist/src/code-execution/index.d.ts +5 -10
  14. package/dist/src/code-execution/index.d.ts.map +1 -1
  15. package/dist/src/code-execution/index.js +5 -9
  16. package/dist/src/code-execution/index.js.map +1 -1
  17. package/dist/src/code-execution/isolate/calls.d.ts +114 -0
  18. package/dist/src/code-execution/isolate/calls.d.ts.map +1 -0
  19. package/dist/src/code-execution/isolate/calls.js +145 -0
  20. package/dist/src/code-execution/isolate/calls.js.map +1 -0
  21. package/dist/src/code-execution/isolate/child-entry.d.ts +2 -0
  22. package/dist/src/code-execution/isolate/child-entry.d.ts.map +1 -0
  23. package/dist/src/code-execution/isolate/child-entry.js +5 -0
  24. package/dist/src/code-execution/isolate/child-entry.js.map +1 -0
  25. package/dist/src/code-execution/isolate/child-main.d.ts +26 -0
  26. package/dist/src/code-execution/isolate/child-main.d.ts.map +1 -0
  27. package/dist/src/code-execution/isolate/child-main.js +132 -0
  28. package/dist/src/code-execution/isolate/child-main.js.map +1 -0
  29. package/dist/src/code-execution/isolate/child.d.ts +44 -0
  30. package/dist/src/code-execution/isolate/child.d.ts.map +1 -0
  31. package/dist/src/code-execution/isolate/child.js +315 -0
  32. package/dist/src/code-execution/isolate/child.js.map +1 -0
  33. package/dist/src/code-execution/isolate/frames.d.ts +80 -0
  34. package/dist/src/code-execution/isolate/frames.d.ts.map +1 -0
  35. package/dist/src/code-execution/isolate/frames.js +210 -0
  36. package/dist/src/code-execution/isolate/frames.js.map +1 -0
  37. package/dist/src/code-execution/isolate/output.d.ts +68 -0
  38. package/dist/src/code-execution/isolate/output.d.ts.map +1 -0
  39. package/dist/src/code-execution/isolate/output.js +143 -0
  40. package/dist/src/code-execution/isolate/output.js.map +1 -0
  41. package/dist/src/code-execution/isolate/prelude.d.ts +109 -0
  42. package/dist/src/code-execution/isolate/prelude.d.ts.map +1 -0
  43. package/dist/src/code-execution/isolate/prelude.js +401 -0
  44. package/dist/src/code-execution/isolate/prelude.js.map +1 -0
  45. package/dist/src/code-execution/isolate/protocol.d.ts +151 -0
  46. package/dist/src/code-execution/isolate/protocol.d.ts.map +1 -0
  47. package/dist/src/code-execution/isolate/protocol.js +150 -0
  48. package/dist/src/code-execution/isolate/protocol.js.map +1 -0
  49. package/dist/src/code-execution/isolate/render.d.ts +57 -0
  50. package/dist/src/code-execution/isolate/render.d.ts.map +1 -0
  51. package/dist/src/code-execution/isolate/render.js +214 -0
  52. package/dist/src/code-execution/isolate/render.js.map +1 -0
  53. package/dist/src/code-execution/isolate/runner.d.ts +250 -0
  54. package/dist/src/code-execution/isolate/runner.d.ts.map +1 -0
  55. package/dist/src/code-execution/isolate/runner.js +854 -0
  56. package/dist/src/code-execution/isolate/runner.js.map +1 -0
  57. package/dist/src/code-execution/isolate/scripts.d.ts +175 -0
  58. package/dist/src/code-execution/isolate/scripts.d.ts.map +1 -0
  59. package/dist/src/code-execution/isolate/scripts.js +357 -0
  60. package/dist/src/code-execution/isolate/scripts.js.map +1 -0
  61. package/dist/src/code-execution/quickjs.wasm +0 -0
  62. package/dist/src/code-execution/tool-definition.d.ts +93 -43
  63. package/dist/src/code-execution/tool-definition.d.ts.map +1 -1
  64. package/dist/src/code-execution/tool-definition.js +176 -142
  65. package/dist/src/code-execution/tool-definition.js.map +1 -1
  66. package/dist/src/deadline-timer.d.ts +3 -0
  67. package/dist/src/deadline-timer.d.ts.map +1 -1
  68. package/dist/src/deadline-timer.js +1 -1
  69. package/dist/src/deadline-timer.js.map +1 -1
  70. package/dist/src/framework.d.ts +1027 -440
  71. package/dist/src/framework.d.ts.map +1 -1
  72. package/dist/src/framework.js +4093 -2238
  73. package/dist/src/framework.js.map +1 -1
  74. package/dist/src/gate/event-gate.d.ts +28 -1
  75. package/dist/src/gate/event-gate.d.ts.map +1 -1
  76. package/dist/src/gate/event-gate.js +88 -10
  77. package/dist/src/gate/event-gate.js.map +1 -1
  78. package/dist/src/held-writes.d.ts +16 -3
  79. package/dist/src/held-writes.d.ts.map +1 -1
  80. package/dist/src/held-writes.js +16 -3
  81. package/dist/src/held-writes.js.map +1 -1
  82. package/dist/src/index.d.ts +6 -6
  83. package/dist/src/index.d.ts.map +1 -1
  84. package/dist/src/index.js +9 -8
  85. package/dist/src/index.js.map +1 -1
  86. package/dist/src/mcpl/channel-registry.d.ts +471 -75
  87. package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
  88. package/dist/src/mcpl/channel-registry.js +1673 -337
  89. package/dist/src/mcpl/channel-registry.js.map +1 -1
  90. package/dist/src/mcpl/conversation-router.d.ts +12 -7
  91. package/dist/src/mcpl/conversation-router.d.ts.map +1 -1
  92. package/dist/src/mcpl/conversation-router.js +12 -7
  93. package/dist/src/mcpl/conversation-router.js.map +1 -1
  94. package/dist/src/mcpl/convert-block.d.ts.map +1 -1
  95. package/dist/src/mcpl/convert-block.js +9 -5
  96. package/dist/src/mcpl/convert-block.js.map +1 -1
  97. package/dist/src/mcpl/inbound-source.d.ts +50 -0
  98. package/dist/src/mcpl/inbound-source.d.ts.map +1 -1
  99. package/dist/src/mcpl/inbound-source.js +130 -0
  100. package/dist/src/mcpl/inbound-source.js.map +1 -1
  101. package/dist/src/mcpl/index.d.ts +2 -1
  102. package/dist/src/mcpl/index.d.ts.map +1 -1
  103. package/dist/src/mcpl/index.js +3 -2
  104. package/dist/src/mcpl/index.js.map +1 -1
  105. package/dist/src/mcpl/log-value.d.ts +6 -0
  106. package/dist/src/mcpl/log-value.d.ts.map +1 -1
  107. package/dist/src/mcpl/log-value.js +8 -0
  108. package/dist/src/mcpl/log-value.js.map +1 -1
  109. package/dist/src/mcpl/modern-connection.d.ts +15 -6
  110. package/dist/src/mcpl/modern-connection.d.ts.map +1 -1
  111. package/dist/src/mcpl/modern-connection.js +168 -53
  112. package/dist/src/mcpl/modern-connection.js.map +1 -1
  113. package/dist/src/mcpl/prose-grammar.d.ts +4 -5
  114. package/dist/src/mcpl/prose-grammar.d.ts.map +1 -1
  115. package/dist/src/mcpl/prose-grammar.js +4 -5
  116. package/dist/src/mcpl/prose-grammar.js.map +1 -1
  117. package/dist/src/mcpl/protocol-family.d.ts +97 -10
  118. package/dist/src/mcpl/protocol-family.d.ts.map +1 -1
  119. package/dist/src/mcpl/protocol-family.js +173 -16
  120. package/dist/src/mcpl/protocol-family.js.map +1 -1
  121. package/dist/src/mcpl/push-coalescer.d.ts +132 -14
  122. package/dist/src/mcpl/push-coalescer.d.ts.map +1 -1
  123. package/dist/src/mcpl/push-coalescer.js +227 -50
  124. package/dist/src/mcpl/push-coalescer.js.map +1 -1
  125. package/dist/src/mcpl/push-handler.d.ts +6 -1
  126. package/dist/src/mcpl/push-handler.d.ts.map +1 -1
  127. package/dist/src/mcpl/push-handler.js +4 -1
  128. package/dist/src/mcpl/push-handler.js.map +1 -1
  129. package/dist/src/mcpl/reference-fetcher.d.ts +2 -2
  130. package/dist/src/mcpl/reference-fetcher.d.ts.map +1 -1
  131. package/dist/src/mcpl/reference-fetcher.js +4 -4
  132. package/dist/src/mcpl/reference-fetcher.js.map +1 -1
  133. package/dist/src/mcpl/server-connection.d.ts +50 -21
  134. package/dist/src/mcpl/server-connection.d.ts.map +1 -1
  135. package/dist/src/mcpl/server-connection.js +158 -74
  136. package/dist/src/mcpl/server-connection.js.map +1 -1
  137. package/dist/src/mcpl/tags.d.ts +24 -0
  138. package/dist/src/mcpl/tags.d.ts.map +1 -1
  139. package/dist/src/mcpl/tags.js +33 -0
  140. package/dist/src/mcpl/tags.js.map +1 -1
  141. package/dist/src/mcpl/tool-result-normalize.d.ts +2 -1
  142. package/dist/src/mcpl/tool-result-normalize.d.ts.map +1 -1
  143. package/dist/src/mcpl/tool-result-normalize.js.map +1 -1
  144. package/dist/src/mcpl/transport.d.ts +55 -7
  145. package/dist/src/mcpl/transport.d.ts.map +1 -1
  146. package/dist/src/mcpl/transport.js +163 -34
  147. package/dist/src/mcpl/transport.js.map +1 -1
  148. package/dist/src/mcpl/types.d.ts +22 -6
  149. package/dist/src/mcpl/types.d.ts.map +1 -1
  150. package/dist/src/mcpl/types.js.map +1 -1
  151. package/dist/src/module-registry.d.ts +4 -2
  152. package/dist/src/module-registry.d.ts.map +1 -1
  153. package/dist/src/module-registry.js +100 -13
  154. package/dist/src/module-registry.js.map +1 -1
  155. package/dist/src/modules/discord/index.d.ts.map +1 -1
  156. package/dist/src/modules/discord/index.js +8 -13
  157. package/dist/src/modules/discord/index.js.map +1 -1
  158. package/dist/src/modules/history/index.d.ts.map +1 -1
  159. package/dist/src/modules/history/index.js +27 -4
  160. package/dist/src/modules/history/index.js.map +1 -1
  161. package/dist/src/modules/history/semantic.d.ts +15 -3
  162. package/dist/src/modules/history/semantic.d.ts.map +1 -1
  163. package/dist/src/modules/history/semantic.js +27 -5
  164. package/dist/src/modules/history/semantic.js.map +1 -1
  165. package/dist/src/modules/index.d.ts +1 -1
  166. package/dist/src/modules/index.d.ts.map +1 -1
  167. package/dist/src/modules/index.js.map +1 -1
  168. package/dist/src/modules/unknown-tool.d.ts +4 -1
  169. package/dist/src/modules/unknown-tool.d.ts.map +1 -1
  170. package/dist/src/modules/unknown-tool.js +4 -1
  171. package/dist/src/modules/unknown-tool.js.map +1 -1
  172. package/dist/src/modules/workspace/branch-intent.d.ts +3 -1
  173. package/dist/src/modules/workspace/branch-intent.d.ts.map +1 -1
  174. package/dist/src/modules/workspace/branch-intent.js +3 -1
  175. package/dist/src/modules/workspace/branch-intent.js.map +1 -1
  176. package/dist/src/modules/workspace/edit-plan.d.ts +265 -0
  177. package/dist/src/modules/workspace/edit-plan.d.ts.map +1 -0
  178. package/dist/src/modules/workspace/edit-plan.js +794 -0
  179. package/dist/src/modules/workspace/edit-plan.js.map +1 -0
  180. package/dist/src/modules/workspace/edit-text.d.ts +117 -0
  181. package/dist/src/modules/workspace/edit-text.d.ts.map +1 -0
  182. package/dist/src/modules/workspace/edit-text.js +584 -0
  183. package/dist/src/modules/workspace/edit-text.js.map +1 -0
  184. package/dist/src/modules/workspace/effects.d.ts +5 -4
  185. package/dist/src/modules/workspace/effects.d.ts.map +1 -1
  186. package/dist/src/modules/workspace/effects.js +78 -25
  187. package/dist/src/modules/workspace/effects.js.map +1 -1
  188. package/dist/src/modules/workspace/index.d.ts +484 -61
  189. package/dist/src/modules/workspace/index.d.ts.map +1 -1
  190. package/dist/src/modules/workspace/index.js +2173 -645
  191. package/dist/src/modules/workspace/index.js.map +1 -1
  192. package/dist/src/modules/workspace/observe.d.ts +213 -38
  193. package/dist/src/modules/workspace/observe.d.ts.map +1 -1
  194. package/dist/src/modules/workspace/observe.js +416 -36
  195. package/dist/src/modules/workspace/observe.js.map +1 -1
  196. package/dist/src/modules/workspace/reconcile.d.ts.map +1 -1
  197. package/dist/src/modules/workspace/reconcile.js +15 -8
  198. package/dist/src/modules/workspace/reconcile.js.map +1 -1
  199. package/dist/src/modules/workspace/text.d.ts +32 -0
  200. package/dist/src/modules/workspace/text.d.ts.map +1 -0
  201. package/dist/src/modules/workspace/text.js +67 -0
  202. package/dist/src/modules/workspace/text.js.map +1 -0
  203. package/dist/src/modules/workspace/types.d.ts +210 -6
  204. package/dist/src/modules/workspace/types.d.ts.map +1 -1
  205. package/dist/src/modules/workspace/types.js.map +1 -1
  206. package/dist/src/modules/workspace/watcher.d.ts +3 -2
  207. package/dist/src/modules/workspace/watcher.d.ts.map +1 -1
  208. package/dist/src/modules/workspace/watcher.js.map +1 -1
  209. package/dist/src/operator-log.d.ts +52 -24
  210. package/dist/src/operator-log.d.ts.map +1 -1
  211. package/dist/src/operator-log.js.map +1 -1
  212. package/dist/src/recovery/discord-awareness-outbox.d.ts +496 -72
  213. package/dist/src/recovery/discord-awareness-outbox.d.ts.map +1 -1
  214. package/dist/src/recovery/discord-awareness-outbox.js +1196 -289
  215. package/dist/src/recovery/discord-awareness-outbox.js.map +1 -1
  216. package/dist/src/recovery/offline-branch.d.ts +26 -1
  217. package/dist/src/recovery/offline-branch.d.ts.map +1 -1
  218. package/dist/src/recovery/offline-branch.js +164 -39
  219. package/dist/src/recovery/offline-branch.js.map +1 -1
  220. package/dist/src/recovery/recover-cli.js +23 -4
  221. package/dist/src/recovery/recover-cli.js.map +1 -1
  222. package/dist/src/send-tools.d.ts +11 -0
  223. package/dist/src/send-tools.d.ts.map +1 -0
  224. package/dist/src/send-tools.js +11 -0
  225. package/dist/src/send-tools.js.map +1 -0
  226. package/dist/src/tool-result-guard.d.ts +4 -3
  227. package/dist/src/tool-result-guard.d.ts.map +1 -1
  228. package/dist/src/tool-result-guard.js +5 -4
  229. package/dist/src/tool-result-guard.js.map +1 -1
  230. package/dist/src/tool-result-history.d.ts +1 -1
  231. package/dist/src/tool-result-history.js +1 -1
  232. package/dist/src/tune-out/coordinator.d.ts +21 -0
  233. package/dist/src/tune-out/coordinator.d.ts.map +1 -1
  234. package/dist/src/tune-out/coordinator.js +139 -37
  235. package/dist/src/tune-out/coordinator.js.map +1 -1
  236. package/dist/src/types/agent.d.ts +4 -0
  237. package/dist/src/types/agent.d.ts.map +1 -1
  238. package/dist/src/types/events.d.ts +62 -9
  239. package/dist/src/types/events.d.ts.map +1 -1
  240. package/dist/src/types/framework.d.ts +62 -58
  241. package/dist/src/types/framework.d.ts.map +1 -1
  242. package/dist/src/types/module.d.ts +40 -8
  243. package/dist/src/types/module.d.ts.map +1 -1
  244. package/dist/src/types/trace.d.ts +111 -10
  245. package/dist/src/types/trace.d.ts.map +1 -1
  246. package/dist/src/usage/types.d.ts +16 -0
  247. package/dist/src/usage/types.d.ts.map +1 -1
  248. package/dist/src/usage/usage-tracker.d.ts +14 -1
  249. package/dist/src/usage/usage-tracker.d.ts.map +1 -1
  250. package/dist/src/usage/usage-tracker.js +81 -41
  251. package/dist/src/usage/usage-tracker.js.map +1 -1
  252. package/package.json +6 -5
  253. package/src/agent.ts +93 -12
  254. package/src/api/server.ts +14 -12
  255. package/src/code-execution/engine.ts +595 -0
  256. package/src/code-execution/index.ts +5 -17
  257. package/src/code-execution/isolate/calls.ts +199 -0
  258. package/src/code-execution/isolate/child-entry.ts +5 -0
  259. package/src/code-execution/isolate/child-main.ts +132 -0
  260. package/src/code-execution/isolate/child.ts +327 -0
  261. package/src/code-execution/isolate/frames.ts +209 -0
  262. package/src/code-execution/isolate/output.ts +161 -0
  263. package/src/code-execution/isolate/prelude.ts +409 -0
  264. package/src/code-execution/isolate/protocol.ts +240 -0
  265. package/src/code-execution/isolate/render.ts +230 -0
  266. package/src/code-execution/isolate/runner.ts +911 -0
  267. package/src/code-execution/isolate/scripts.ts +479 -0
  268. package/src/code-execution/quickjs.wasm +0 -0
  269. package/src/code-execution/quickjs.wasm.LICENSES +149 -0
  270. package/src/code-execution/tool-definition.ts +236 -167
  271. package/src/deadline-timer.ts +1 -1
  272. package/src/framework.ts +4468 -2418
  273. package/src/gate/event-gate.ts +78 -11
  274. package/src/held-writes.ts +17 -3
  275. package/src/index.ts +30 -22
  276. package/src/mcpl/channel-registry.ts +1825 -368
  277. package/src/mcpl/conversation-router.ts +12 -7
  278. package/src/mcpl/convert-block.ts +9 -5
  279. package/src/mcpl/inbound-source.ts +131 -0
  280. package/src/mcpl/index.ts +4 -2
  281. package/src/mcpl/log-value.ts +9 -0
  282. package/src/mcpl/modern-connection.ts +162 -53
  283. package/src/mcpl/prose-grammar.ts +4 -5
  284. package/src/mcpl/protocol-family.ts +199 -21
  285. package/src/mcpl/push-coalescer.ts +306 -62
  286. package/src/mcpl/push-handler.ts +10 -2
  287. package/src/mcpl/reference-fetcher.ts +4 -4
  288. package/src/mcpl/server-connection.ts +180 -79
  289. package/src/mcpl/tags.ts +36 -0
  290. package/src/mcpl/tool-result-normalize.ts +2 -1
  291. package/src/mcpl/transport.ts +162 -33
  292. package/src/mcpl/types.ts +23 -6
  293. package/src/module-registry.ts +92 -13
  294. package/src/modules/discord/index.ts +8 -13
  295. package/src/modules/history/index.ts +25 -3
  296. package/src/modules/history/semantic.ts +29 -6
  297. package/src/modules/index.ts +1 -0
  298. package/src/modules/unknown-tool.ts +4 -1
  299. package/src/modules/workspace/branch-intent.ts +3 -1
  300. package/src/modules/workspace/edit-plan.ts +954 -0
  301. package/src/modules/workspace/edit-text.ts +618 -0
  302. package/src/modules/workspace/effects.ts +70 -19
  303. package/src/modules/workspace/index.ts +2247 -642
  304. package/src/modules/workspace/observe.ts +465 -56
  305. package/src/modules/workspace/reconcile.ts +14 -7
  306. package/src/modules/workspace/text.ts +68 -0
  307. package/src/modules/workspace/types.ts +211 -6
  308. package/src/modules/workspace/watcher.ts +3 -2
  309. package/src/operator-log.ts +47 -19
  310. package/src/recovery/discord-awareness-outbox.ts +1500 -356
  311. package/src/recovery/offline-branch.ts +189 -55
  312. package/src/recovery/recover-cli.ts +25 -4
  313. package/src/send-tools.ts +11 -0
  314. package/src/tool-result-guard.ts +6 -5
  315. package/src/tool-result-history.ts +1 -1
  316. package/src/tune-out/coordinator.ts +163 -42
  317. package/src/types/agent.ts +4 -0
  318. package/src/types/events.ts +62 -9
  319. package/src/types/framework.ts +62 -58
  320. package/src/types/module.ts +40 -8
  321. package/src/types/trace.ts +121 -15
  322. package/src/usage/types.ts +16 -0
  323. package/src/usage/usage-tracker.ts +86 -43
  324. package/dist/src/code-execution/py-runner.d.ts +0 -191
  325. package/dist/src/code-execution/py-runner.d.ts.map +0 -1
  326. package/dist/src/code-execution/py-runner.js +0 -655
  327. package/dist/src/code-execution/py-runner.js.map +0 -1
  328. package/dist/src/code-execution/runtime-py.d.ts +0 -50
  329. package/dist/src/code-execution/runtime-py.d.ts.map +0 -1
  330. package/dist/src/code-execution/runtime-py.js +0 -677
  331. package/dist/src/code-execution/runtime-py.js.map +0 -1
  332. package/dist/src/mcpl/prose-stream-router.d.ts +0 -88
  333. package/dist/src/mcpl/prose-stream-router.d.ts.map +0 -1
  334. package/dist/src/mcpl/prose-stream-router.js +0 -291
  335. package/dist/src/mcpl/prose-stream-router.js.map +0 -1
  336. package/src/code-execution/py-runner.ts +0 -791
  337. package/src/code-execution/runtime-py.ts +0 -677
  338. 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';
@@ -602,6 +603,9 @@ export class EventGate {
602
603
  private sleepSuppressed = 0;
603
604
  private sleepTimer: ReturnType<typeof setTimeout> | null = null;
604
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;
605
609
 
606
610
  // Self-wake timers per agent (skip_reply's wake_in_seconds). Unlike sleep,
607
611
  // a self-wake suppresses NOTHING — it means "if nothing else wakes me by
@@ -1048,11 +1052,13 @@ export class EventGate {
1048
1052
  // rouse the agent — its own heartbeat (an internal clock, not an outside
1049
1053
  // interruption: each tick lets the agent reconsider and optionally `wake`)
1050
1054
  // and a privileged user's ping. The event always enters context regardless
1051
- // (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.
1052
1059
  if (this.sleepUntil > this.now()) {
1053
1060
  this.reloadPrivilegedIfChanged();
1054
- const isHeartbeat =
1055
- info.metadata?.source === 'heartbeat' || info.serverId === 'heartbeat';
1061
+ const isHeartbeat = info.serverId === 'heartbeat';
1056
1062
  const authorId = this.extractAuthorId(info.metadata);
1057
1063
  const privileged = authorId !== null && this.privilegedUserIds.has(authorId);
1058
1064
  if (!isHeartbeat && !privileged) {
@@ -1733,9 +1739,9 @@ export class EventGate {
1733
1739
  this.sleepSuppressed = 0;
1734
1740
  // Arm the self-wake: when the window elapses, clear sleep and request an
1735
1741
  // inference so the agent resumes on its own (not dependent on a heartbeat
1736
- // tick or an incoming message). Cancelled by clearSleep()/`wake`.
1737
- if (this.sleepTimer) clearTimeout(this.sleepTimer);
1738
- 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();
1739
1745
  this.reloadPrivilegedIfChanged();
1740
1746
  this.emitTrace({
1741
1747
  type: 'gate:decision',
@@ -1748,6 +1754,48 @@ export class EventGate {
1748
1754
  return { until: this.sleepUntil };
1749
1755
  }
1750
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
+
1751
1799
  // =========================================================================
1752
1800
  // Self-wake (skip_reply wake_in_seconds)
1753
1801
  // =========================================================================
@@ -1759,8 +1807,11 @@ export class EventGate {
1759
1807
  * Cancelled by the agent's next turn start (see onInferenceStarted):
1760
1808
  * the semantics are "if nothing else wakes me by then, wake me".
1761
1809
  */
1762
- armSelfWake(agentName: string, seconds: number, source = 'skip_reply'): { inMs: number } {
1810
+ armSelfWake(agentName: string, seconds: number, source = 'skip_reply'): { inMs: number; armed: boolean } {
1763
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 };
1764
1815
  const prev = this.selfWakeTimers.get(agentName);
1765
1816
  if (prev) clearTimeout(prev);
1766
1817
  const timer = setTimeout(() => {
@@ -1801,7 +1852,7 @@ export class EventGate {
1801
1852
  behavior: 'skip',
1802
1853
  timestamp: this.now(),
1803
1854
  });
1804
- return { inMs: ms };
1855
+ return { inMs: ms, armed: true };
1805
1856
  }
1806
1857
 
1807
1858
  /** End sleep immediately. Returns true if the agent was asleep. */
@@ -1819,11 +1870,20 @@ export class EventGate {
1819
1870
  * Clears the sleep state and requests an inference so the agent wakes on its
1820
1871
  * own — this is what makes `sleep(N)` a real "wake me in N seconds" rather
1821
1872
  * than just a suppression window. No-op if sleep was already cleared (via
1822
- * `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.
1823
1876
  */
1824
1877
  private wakeFromSleep(reason: string): void {
1825
- this.sleepTimer = null;
1826
- 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
+ }
1827
1887
  const note = this.sleepNote;
1828
1888
  const agent = this.sleepAgent;
1829
1889
  this.sleepUntil = 0;
@@ -2001,6 +2061,13 @@ export class EventGate {
2001
2061
  clearTimeout(timer);
2002
2062
  }
2003
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;
2004
2071
  this.rateLimitBuckets.clear();
2005
2072
  this.passiveSampleCounters.clear();
2006
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
@@ -59,23 +59,9 @@ export type {
59
59
  // Usage tracking
60
60
  export { UsageTracker } from './usage/index.js';
61
61
 
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';
62
+ // Client-side programmatic tool calling (code_execution): the tool's name,
63
+ // and its definition as an agent reads it.
64
+ export { buildCodeExecutionToolDefinition, CODE_EXECUTION_TOOL_NAME } from './code-execution/index.js';
79
65
  export type { SessionUsage, AgentUsage, SessionUsageSnapshot, UsageUpdatedEvent } from './usage/index.js';
80
66
 
81
67
  // EventGate
@@ -84,9 +70,12 @@ export type { GateConfig, GateOptions, GatePolicy, GatePolicyMatch, GateBehavior
84
70
 
85
71
  // MCPL channel registry (exposed for modules that need channel-level operations)
86
72
  export { ChannelRegistry } from './mcpl/index.js';
73
+ export type { PublishRefusalReason } from './mcpl/index.js';
87
74
 
88
- // Where each accepted inbound item came from (`metadata.inboundSource`)
89
- export { INBOUND_SOURCE_KEY, readInboundSource, conversationKey } from './mcpl/index.js';
75
+ // Where each accepted inbound item came from (`metadata.inboundSource`), and
76
+ // the digest its delivered and stored bodies are stamped with
77
+ // (`metadata.sourceBodyDigest`, `metadata.storedBodyDigest`)
78
+ export { INBOUND_SOURCE_KEY, readInboundSource, conversationKey, sourceBodyDigest } from './mcpl/index.js';
90
79
  export type {
91
80
  InboundSource,
92
81
  InboundChannelSource,
@@ -150,18 +139,35 @@ export { PassthroughStrategy, AutobiographicalStrategy, KnowledgeStrategy } from
150
139
  export type { KnowledgeConfig, PhaseType } from '@animalabs/context-manager';
151
140
  export type { Membrane, NormalizedMessage, NormalizedRequest, ContentBlock } from '@animalabs/membrane';
152
141
 
153
- // Offline outage recovery and branch-independent Discord awareness markers
142
+ // Offline outage recovery and the Discord awareness-mark ledger
154
143
  export {
155
144
  DiscordAwarenessOutbox,
145
+ DiscordAwarenessRefusal,
156
146
  DEFAULT_DISCORD_AWARENESS_EMOJI,
157
147
  defaultDiscordAwarenessOutboxPath,
158
148
  extractDiscordAwarenessRefs,
149
+ isPermanentDiscordReactionFailure,
150
+ selectDiscordAwarenessRefs,
159
151
  } from './recovery/discord-awareness-outbox.js';
160
152
  export type {
153
+ DiscordAwarenessAction,
161
154
  DiscordAwarenessBatch,
162
- DiscordAwarenessEntry,
163
- DiscordAwarenessOperation,
155
+ DiscordAwarenessBatchStatus,
156
+ DiscordAwarenessBatchView,
157
+ DiscordAwarenessRetractView,
158
+ DiscordAwarenessView,
159
+ DiscordAwarenessCancelReceipt,
160
+ DiscordAwarenessMarks,
161
+ DiscordAwarenessOutcome,
162
+ DiscordAwarenessPrepareInput,
163
+ DiscordAwarenessReactionState,
164
+ DiscordAwarenessImportedUnsent,
164
165
  DiscordAwarenessRef,
166
+ DiscordAwarenessRequest,
167
+ DiscordAwarenessRetractReceipt,
168
+ DiscordAwarenessRetirement,
169
+ DiscordAwarenessScope,
170
+ DiscordAwarenessSettlement,
165
171
  DiscordSuppressionInterval,
166
172
  } from './recovery/discord-awareness-outbox.js';
167
173
  // Live operator surgery (rollback / suppress) and its durable action log
@@ -170,7 +176,9 @@ export type {
170
176
  OperatorLogEntry,
171
177
  OperatorLogInput,
172
178
  OperatorRequester,
179
+ SurgeryMarkerFacts,
173
180
  SurgeryMarkerReceipt,
181
+ SurgeryMarksPreview,
174
182
  } from './operator-log.js';
175
183
  export { createOfflineRecoveryBranch } from './recovery/offline-branch.js';
176
184
  export type {