@animalabs/agent-framework 0.22.2 → 0.22.3

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 (935) hide show
  1. package/README.md +3 -1
  2. package/dist/src/agent.d.ts +77 -12
  3. package/dist/src/agent.d.ts.map +1 -1
  4. package/dist/src/agent.js +136 -40
  5. package/dist/src/agent.js.map +1 -1
  6. package/dist/src/api/mcp-server-core.js +1 -1
  7. package/dist/src/api/mcp-server-core.js.map +1 -1
  8. package/dist/src/api/server.d.ts.map +1 -1
  9. package/dist/src/api/server.js +5 -1
  10. package/dist/src/api/server.js.map +1 -1
  11. package/dist/src/api/types.d.ts +1 -1
  12. package/dist/src/api/types.d.ts.map +1 -1
  13. package/dist/src/branch-names.d.ts +14 -0
  14. package/dist/src/branch-names.d.ts.map +1 -0
  15. package/dist/src/branch-names.js +22 -0
  16. package/dist/src/branch-names.js.map +1 -0
  17. package/dist/src/closest-names.d.ts +28 -0
  18. package/dist/src/closest-names.d.ts.map +1 -0
  19. package/dist/src/closest-names.js +98 -0
  20. package/dist/src/closest-names.js.map +1 -0
  21. package/dist/src/code-execution/py-runner.d.ts +16 -5
  22. package/dist/src/code-execution/py-runner.d.ts.map +1 -1
  23. package/dist/src/code-execution/py-runner.js +186 -74
  24. package/dist/src/code-execution/py-runner.js.map +1 -1
  25. package/dist/src/code-execution/runtime-py.d.ts.map +1 -1
  26. package/dist/src/code-execution/runtime-py.js +49 -3
  27. package/dist/src/code-execution/runtime-py.js.map +1 -1
  28. package/dist/src/code-execution/tool-definition.d.ts +12 -1
  29. package/dist/src/code-execution/tool-definition.d.ts.map +1 -1
  30. package/dist/src/code-execution/tool-definition.js +21 -3
  31. package/dist/src/code-execution/tool-definition.js.map +1 -1
  32. package/dist/src/config-checks.d.ts +28 -0
  33. package/dist/src/config-checks.d.ts.map +1 -0
  34. package/dist/src/config-checks.js +52 -0
  35. package/dist/src/config-checks.js.map +1 -0
  36. package/dist/src/deadline-timer.d.ts +21 -0
  37. package/dist/src/deadline-timer.d.ts.map +1 -0
  38. package/dist/src/deadline-timer.js +43 -0
  39. package/dist/src/deadline-timer.js.map +1 -0
  40. package/dist/src/error-message.d.ts +30 -0
  41. package/dist/src/error-message.d.ts.map +1 -0
  42. package/dist/src/error-message.js +50 -0
  43. package/dist/src/error-message.js.map +1 -0
  44. package/dist/src/framework.d.ts +828 -88
  45. package/dist/src/framework.d.ts.map +1 -1
  46. package/dist/src/framework.js +5011 -1326
  47. package/dist/src/framework.js.map +1 -1
  48. package/dist/src/gate/event-gate.d.ts +8 -0
  49. package/dist/src/gate/event-gate.d.ts.map +1 -1
  50. package/dist/src/gate/event-gate.js +27 -3
  51. package/dist/src/gate/event-gate.js.map +1 -1
  52. package/dist/src/index.d.ts +4 -2
  53. package/dist/src/index.d.ts.map +1 -1
  54. package/dist/src/index.js +4 -2
  55. package/dist/src/index.js.map +1 -1
  56. package/dist/src/mcpl/channel-registry.d.ts +144 -6
  57. package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
  58. package/dist/src/mcpl/channel-registry.js +424 -263
  59. package/dist/src/mcpl/channel-registry.js.map +1 -1
  60. package/dist/src/mcpl/checkpoint-manager.d.ts +21 -1
  61. package/dist/src/mcpl/checkpoint-manager.d.ts.map +1 -1
  62. package/dist/src/mcpl/checkpoint-manager.js +91 -30
  63. package/dist/src/mcpl/checkpoint-manager.js.map +1 -1
  64. package/dist/src/mcpl/conversation-router.d.ts +19 -3
  65. package/dist/src/mcpl/conversation-router.d.ts.map +1 -1
  66. package/dist/src/mcpl/conversation-router.js +23 -8
  67. package/dist/src/mcpl/conversation-router.js.map +1 -1
  68. package/dist/src/mcpl/convert-block.d.ts +20 -0
  69. package/dist/src/mcpl/convert-block.d.ts.map +1 -0
  70. package/dist/src/mcpl/convert-block.js +89 -0
  71. package/dist/src/mcpl/convert-block.js.map +1 -0
  72. package/dist/src/mcpl/errors.d.ts +13 -0
  73. package/dist/src/mcpl/errors.d.ts.map +1 -1
  74. package/dist/src/mcpl/errors.js +28 -0
  75. package/dist/src/mcpl/errors.js.map +1 -1
  76. package/dist/src/mcpl/hook-orchestrator.d.ts +23 -0
  77. package/dist/src/mcpl/hook-orchestrator.d.ts.map +1 -1
  78. package/dist/src/mcpl/hook-orchestrator.js +83 -72
  79. package/dist/src/mcpl/hook-orchestrator.js.map +1 -1
  80. package/dist/src/mcpl/inbound-source.d.ts +114 -0
  81. package/dist/src/mcpl/inbound-source.d.ts.map +1 -0
  82. package/dist/src/mcpl/inbound-source.js +83 -0
  83. package/dist/src/mcpl/inbound-source.js.map +1 -0
  84. package/dist/src/mcpl/index.d.ts +3 -1
  85. package/dist/src/mcpl/index.d.ts.map +1 -1
  86. package/dist/src/mcpl/index.js +3 -1
  87. package/dist/src/mcpl/index.js.map +1 -1
  88. package/dist/src/mcpl/inference-router.d.ts +15 -11
  89. package/dist/src/mcpl/inference-router.d.ts.map +1 -1
  90. package/dist/src/mcpl/inference-router.js +153 -84
  91. package/dist/src/mcpl/inference-router.js.map +1 -1
  92. package/dist/src/mcpl/push-coalescer.d.ts +33 -11
  93. package/dist/src/mcpl/push-coalescer.d.ts.map +1 -1
  94. package/dist/src/mcpl/push-coalescer.js +52 -20
  95. package/dist/src/mcpl/push-coalescer.js.map +1 -1
  96. package/dist/src/mcpl/push-handler.d.ts +16 -9
  97. package/dist/src/mcpl/push-handler.d.ts.map +1 -1
  98. package/dist/src/mcpl/push-handler.js +18 -83
  99. package/dist/src/mcpl/push-handler.js.map +1 -1
  100. package/dist/src/mcpl/reference-fetcher.d.ts +14 -2
  101. package/dist/src/mcpl/reference-fetcher.d.ts.map +1 -1
  102. package/dist/src/mcpl/reference-fetcher.js +72 -30
  103. package/dist/src/mcpl/reference-fetcher.js.map +1 -1
  104. package/dist/src/mcpl/references.d.ts +47 -12
  105. package/dist/src/mcpl/references.d.ts.map +1 -1
  106. package/dist/src/mcpl/references.js +74 -21
  107. package/dist/src/mcpl/references.js.map +1 -1
  108. package/dist/src/mcpl/server-connection.d.ts +89 -10
  109. package/dist/src/mcpl/server-connection.d.ts.map +1 -1
  110. package/dist/src/mcpl/server-connection.js +405 -129
  111. package/dist/src/mcpl/server-connection.js.map +1 -1
  112. package/dist/src/mcpl/server-registry.d.ts +10 -1
  113. package/dist/src/mcpl/server-registry.d.ts.map +1 -1
  114. package/dist/src/mcpl/server-registry.js +14 -3
  115. package/dist/src/mcpl/server-registry.js.map +1 -1
  116. package/dist/src/mcpl/skip-reply-wake.d.ts +36 -0
  117. package/dist/src/mcpl/skip-reply-wake.d.ts.map +1 -0
  118. package/dist/src/mcpl/skip-reply-wake.js +55 -0
  119. package/dist/src/mcpl/skip-reply-wake.js.map +1 -0
  120. package/dist/src/mcpl/transport.d.ts +51 -2
  121. package/dist/src/mcpl/transport.d.ts.map +1 -1
  122. package/dist/src/mcpl/transport.js +114 -20
  123. package/dist/src/mcpl/transport.js.map +1 -1
  124. package/dist/src/mcpl/types.d.ts +14 -3
  125. package/dist/src/mcpl/types.d.ts.map +1 -1
  126. package/dist/src/mcpl/types.js.map +1 -1
  127. package/dist/src/mcpl/visible-content.d.ts +15 -0
  128. package/dist/src/mcpl/visible-content.d.ts.map +1 -1
  129. package/dist/src/mcpl/visible-content.js +25 -0
  130. package/dist/src/mcpl/visible-content.js.map +1 -1
  131. package/dist/src/module-registry.d.ts +19 -1
  132. package/dist/src/module-registry.d.ts.map +1 -1
  133. package/dist/src/module-registry.js +54 -25
  134. package/dist/src/module-registry.js.map +1 -1
  135. package/dist/src/modules/api/index.js +1 -1
  136. package/dist/src/modules/api/index.js.map +1 -1
  137. package/dist/src/modules/discord/discord-js-client.d.ts +1 -0
  138. package/dist/src/modules/discord/discord-js-client.d.ts.map +1 -1
  139. package/dist/src/modules/discord/discord-js-client.js +25 -9
  140. package/dist/src/modules/discord/discord-js-client.js.map +1 -1
  141. package/dist/src/modules/discord/index.d.ts +29 -3
  142. package/dist/src/modules/discord/index.d.ts.map +1 -1
  143. package/dist/src/modules/discord/index.js +379 -143
  144. package/dist/src/modules/discord/index.js.map +1 -1
  145. package/dist/src/modules/discord/types.d.ts +14 -1
  146. package/dist/src/modules/discord/types.d.ts.map +1 -1
  147. package/dist/src/modules/health/index.d.ts.map +1 -1
  148. package/dist/src/modules/health/index.js +2 -1
  149. package/dist/src/modules/health/index.js.map +1 -1
  150. package/dist/src/modules/history/index.d.ts +3 -1
  151. package/dist/src/modules/history/index.d.ts.map +1 -1
  152. package/dist/src/modules/history/index.js +359 -127
  153. package/dist/src/modules/history/index.js.map +1 -1
  154. package/dist/src/modules/history/semantic.d.ts +28 -1
  155. package/dist/src/modules/history/semantic.d.ts.map +1 -1
  156. package/dist/src/modules/history/semantic.js +177 -32
  157. package/dist/src/modules/history/semantic.js.map +1 -1
  158. package/dist/src/modules/unknown-tool.d.ts +10 -0
  159. package/dist/src/modules/unknown-tool.d.ts.map +1 -0
  160. package/dist/src/modules/unknown-tool.js +17 -0
  161. package/dist/src/modules/unknown-tool.js.map +1 -0
  162. package/dist/src/modules/workspace/disk-agreement.d.ts +32 -2
  163. package/dist/src/modules/workspace/disk-agreement.d.ts.map +1 -1
  164. package/dist/src/modules/workspace/disk-agreement.js +30 -2
  165. package/dist/src/modules/workspace/disk-agreement.js.map +1 -1
  166. package/dist/src/modules/workspace/effects.d.ts +64 -6
  167. package/dist/src/modules/workspace/effects.d.ts.map +1 -1
  168. package/dist/src/modules/workspace/effects.js +291 -44
  169. package/dist/src/modules/workspace/effects.js.map +1 -1
  170. package/dist/src/modules/workspace/index.d.ts +119 -23
  171. package/dist/src/modules/workspace/index.d.ts.map +1 -1
  172. package/dist/src/modules/workspace/index.js +793 -247
  173. package/dist/src/modules/workspace/index.js.map +1 -1
  174. package/dist/src/modules/workspace/observe.d.ts +75 -8
  175. package/dist/src/modules/workspace/observe.d.ts.map +1 -1
  176. package/dist/src/modules/workspace/observe.js +174 -14
  177. package/dist/src/modules/workspace/observe.js.map +1 -1
  178. package/dist/src/modules/workspace/reconcile.d.ts +58 -7
  179. package/dist/src/modules/workspace/reconcile.d.ts.map +1 -1
  180. package/dist/src/modules/workspace/reconcile.js +521 -56
  181. package/dist/src/modules/workspace/reconcile.js.map +1 -1
  182. package/dist/src/modules/workspace/types.d.ts +18 -4
  183. package/dist/src/modules/workspace/types.d.ts.map +1 -1
  184. package/dist/src/modules/workspace/types.js.map +1 -1
  185. package/dist/src/modules/workspace/watcher.d.ts +7 -2
  186. package/dist/src/modules/workspace/watcher.d.ts.map +1 -1
  187. package/dist/src/modules/workspace/watcher.js +28 -4
  188. package/dist/src/modules/workspace/watcher.js.map +1 -1
  189. package/dist/src/prose-drafts.d.ts +240 -0
  190. package/dist/src/prose-drafts.d.ts.map +1 -0
  191. package/dist/src/prose-drafts.js +362 -0
  192. package/dist/src/prose-drafts.js.map +1 -0
  193. package/dist/src/prose-segments.d.ts +21 -2
  194. package/dist/src/prose-segments.d.ts.map +1 -1
  195. package/dist/src/prose-segments.js +46 -9
  196. package/dist/src/prose-segments.js.map +1 -1
  197. package/dist/src/recovery/offline-branch.d.ts +1 -0
  198. package/dist/src/recovery/offline-branch.d.ts.map +1 -1
  199. package/dist/src/recovery/offline-branch.js +3 -1
  200. package/dist/src/recovery/offline-branch.js.map +1 -1
  201. package/dist/src/safe-slice.d.ts +5 -1
  202. package/dist/src/safe-slice.d.ts.map +1 -1
  203. package/dist/src/safe-slice.js +9 -1
  204. package/dist/src/safe-slice.js.map +1 -1
  205. package/dist/src/tool-image-ledger.d.ts +87 -19
  206. package/dist/src/tool-image-ledger.d.ts.map +1 -1
  207. package/dist/src/tool-image-ledger.js +135 -32
  208. package/dist/src/tool-image-ledger.js.map +1 -1
  209. package/dist/src/tool-presentation.d.ts +9 -0
  210. package/dist/src/tool-presentation.d.ts.map +1 -1
  211. package/dist/src/tool-presentation.js +257 -60
  212. package/dist/src/tool-presentation.js.map +1 -1
  213. package/dist/src/tool-result-guard.d.ts.map +1 -1
  214. package/dist/src/tool-result-guard.js +7 -10
  215. package/dist/src/tool-result-guard.js.map +1 -1
  216. package/dist/src/tool-result-history.d.ts +32 -3
  217. package/dist/src/tool-result-history.d.ts.map +1 -1
  218. package/dist/src/tool-result-history.js +106 -19
  219. package/dist/src/tool-result-history.js.map +1 -1
  220. package/dist/src/tune-out/coordinator.d.ts +25 -1
  221. package/dist/src/tune-out/coordinator.d.ts.map +1 -1
  222. package/dist/src/tune-out/coordinator.js +260 -65
  223. package/dist/src/tune-out/coordinator.js.map +1 -1
  224. package/dist/src/types/agent.d.ts +17 -5
  225. package/dist/src/types/agent.d.ts.map +1 -1
  226. package/dist/src/types/events.d.ts +17 -0
  227. package/dist/src/types/events.d.ts.map +1 -1
  228. package/dist/src/types/framework.d.ts +21 -5
  229. package/dist/src/types/framework.d.ts.map +1 -1
  230. package/dist/src/types/inference-log.d.ts +1 -1
  231. package/dist/src/types/inference-log.d.ts.map +1 -1
  232. package/dist/src/types/module.d.ts +23 -4
  233. package/dist/src/types/module.d.ts.map +1 -1
  234. package/dist/src/types/trace.d.ts +95 -6
  235. package/dist/src/types/trace.d.ts.map +1 -1
  236. package/dist/src/usage/usage-tracker.d.ts +5 -0
  237. package/dist/src/usage/usage-tracker.d.ts.map +1 -1
  238. package/dist/src/usage/usage-tracker.js +35 -8
  239. package/dist/src/usage/usage-tracker.js.map +1 -1
  240. package/package.json +3 -4
  241. package/src/agent.ts +162 -40
  242. package/src/api/mcp-server-core.ts +1 -1
  243. package/src/api/server.ts +4 -1
  244. package/src/api/types.ts +1 -1
  245. package/src/branch-names.ts +19 -0
  246. package/src/closest-names.ts +94 -0
  247. package/src/code-execution/py-runner.ts +200 -76
  248. package/src/code-execution/runtime-py.ts +49 -3
  249. package/src/code-execution/tool-definition.ts +28 -4
  250. package/src/config-checks.ts +48 -0
  251. package/src/deadline-timer.ts +44 -0
  252. package/src/error-message.ts +48 -0
  253. package/src/framework.ts +5352 -1388
  254. package/src/gate/event-gate.ts +28 -3
  255. package/src/index.ts +11 -2
  256. package/src/mcpl/channel-registry.ts +517 -286
  257. package/src/mcpl/checkpoint-manager.ts +104 -29
  258. package/src/mcpl/conversation-router.ts +28 -8
  259. package/src/mcpl/convert-block.ts +97 -0
  260. package/src/mcpl/errors.ts +28 -0
  261. package/src/mcpl/hook-orchestrator.ts +84 -77
  262. package/src/mcpl/inbound-source.ts +156 -0
  263. package/src/mcpl/index.ts +10 -1
  264. package/src/mcpl/inference-router.ts +174 -99
  265. package/src/mcpl/push-coalescer.ts +60 -24
  266. package/src/mcpl/push-handler.ts +20 -90
  267. package/src/mcpl/reference-fetcher.ts +71 -26
  268. package/src/mcpl/references.ts +81 -22
  269. package/src/mcpl/server-connection.ts +427 -132
  270. package/src/mcpl/server-registry.ts +15 -4
  271. package/src/mcpl/skip-reply-wake.ts +73 -0
  272. package/src/mcpl/transport.ts +120 -18
  273. package/src/mcpl/types.ts +14 -3
  274. package/src/mcpl/visible-content.ts +27 -0
  275. package/src/module-registry.ts +58 -23
  276. package/src/modules/api/index.ts +1 -1
  277. package/src/modules/discord/discord-js-client.ts +26 -10
  278. package/src/modules/discord/index.ts +391 -158
  279. package/src/modules/discord/types.ts +15 -2
  280. package/src/modules/health/index.ts +2 -1
  281. package/src/modules/history/index.ts +410 -120
  282. package/src/modules/history/semantic.ts +189 -32
  283. package/src/modules/unknown-tool.ts +16 -0
  284. package/src/modules/workspace/disk-agreement.ts +51 -3
  285. package/src/modules/workspace/effects.ts +279 -35
  286. package/src/modules/workspace/index.ts +810 -260
  287. package/src/modules/workspace/observe.ts +194 -20
  288. package/src/modules/workspace/reconcile.ts +619 -64
  289. package/src/modules/workspace/types.ts +18 -4
  290. package/src/modules/workspace/watcher.ts +27 -4
  291. package/src/prose-drafts.ts +481 -0
  292. package/src/prose-segments.ts +51 -8
  293. package/src/recovery/offline-branch.ts +4 -1
  294. package/src/safe-slice.ts +9 -1
  295. package/src/tool-image-ledger.ts +153 -34
  296. package/src/tool-presentation.ts +224 -40
  297. package/src/tool-result-guard.ts +7 -8
  298. package/src/tool-result-history.ts +124 -20
  299. package/src/tune-out/coordinator.ts +259 -65
  300. package/src/types/agent.ts +17 -7
  301. package/src/types/events.ts +17 -0
  302. package/src/types/framework.ts +21 -5
  303. package/src/types/inference-log.ts +1 -1
  304. package/src/types/module.ts +24 -4
  305. package/src/types/trace.ts +101 -6
  306. package/src/usage/usage-tracker.ts +32 -8
  307. package/dist/test/activation-request-sanitize.test.d.ts +0 -2
  308. package/dist/test/activation-request-sanitize.test.d.ts.map +0 -1
  309. package/dist/test/activation-request-sanitize.test.js +0 -89
  310. package/dist/test/activation-request-sanitize.test.js.map +0 -1
  311. package/dist/test/agent-cache-ttl.test.d.ts +0 -2
  312. package/dist/test/agent-cache-ttl.test.d.ts.map +0 -1
  313. package/dist/test/agent-cache-ttl.test.js +0 -41
  314. package/dist/test/agent-cache-ttl.test.js.map +0 -1
  315. package/dist/test/agent-runtime-settings.test.d.ts +0 -2
  316. package/dist/test/agent-runtime-settings.test.d.ts.map +0 -1
  317. package/dist/test/agent-runtime-settings.test.js +0 -1598
  318. package/dist/test/agent-runtime-settings.test.js.map +0 -1
  319. package/dist/test/api-admin-gate.test.d.ts +0 -2
  320. package/dist/test/api-admin-gate.test.d.ts.map +0 -1
  321. package/dist/test/api-admin-gate.test.js +0 -116
  322. package/dist/test/api-admin-gate.test.js.map +0 -1
  323. package/dist/test/assistant-persist-refusal.test.d.ts +0 -2
  324. package/dist/test/assistant-persist-refusal.test.d.ts.map +0 -1
  325. package/dist/test/assistant-persist-refusal.test.js +0 -63
  326. package/dist/test/assistant-persist-refusal.test.js.map +0 -1
  327. package/dist/test/batched-wake-locus.test.d.ts +0 -2
  328. package/dist/test/batched-wake-locus.test.d.ts.map +0 -1
  329. package/dist/test/batched-wake-locus.test.js +0 -166
  330. package/dist/test/batched-wake-locus.test.js.map +0 -1
  331. package/dist/test/busy-agent-scheduler.test.d.ts +0 -2
  332. package/dist/test/busy-agent-scheduler.test.d.ts.map +0 -1
  333. package/dist/test/busy-agent-scheduler.test.js +0 -92
  334. package/dist/test/busy-agent-scheduler.test.js.map +0 -1
  335. package/dist/test/channel-incoming-targeting.test.d.ts +0 -2
  336. package/dist/test/channel-incoming-targeting.test.d.ts.map +0 -1
  337. package/dist/test/channel-incoming-targeting.test.js +0 -81
  338. package/dist/test/channel-incoming-targeting.test.js.map +0 -1
  339. package/dist/test/channel-label-history.test.d.ts +0 -2
  340. package/dist/test/channel-label-history.test.d.ts.map +0 -1
  341. package/dist/test/channel-label-history.test.js +0 -424
  342. package/dist/test/channel-label-history.test.js.map +0 -1
  343. package/dist/test/channel-lifecycle-provenance.test.d.ts +0 -2
  344. package/dist/test/channel-lifecycle-provenance.test.d.ts.map +0 -1
  345. package/dist/test/channel-lifecycle-provenance.test.js +0 -47
  346. package/dist/test/channel-lifecycle-provenance.test.js.map +0 -1
  347. package/dist/test/channel-registry-routing.test.d.ts +0 -2
  348. package/dist/test/channel-registry-routing.test.d.ts.map +0 -1
  349. package/dist/test/channel-registry-routing.test.js +0 -446
  350. package/dist/test/channel-registry-routing.test.js.map +0 -1
  351. package/dist/test/channel-registry-typing.test.d.ts +0 -2
  352. package/dist/test/channel-registry-typing.test.d.ts.map +0 -1
  353. package/dist/test/channel-registry-typing.test.js +0 -91
  354. package/dist/test/channel-registry-typing.test.js.map +0 -1
  355. package/dist/test/channels-changed-respond-first.test.d.ts +0 -2
  356. package/dist/test/channels-changed-respond-first.test.d.ts.map +0 -1
  357. package/dist/test/channels-changed-respond-first.test.js +0 -74
  358. package/dist/test/channels-changed-respond-first.test.js.map +0 -1
  359. package/dist/test/checkpoint-attribution.test.d.ts +0 -2
  360. package/dist/test/checkpoint-attribution.test.d.ts.map +0 -1
  361. package/dist/test/checkpoint-attribution.test.js +0 -200
  362. package/dist/test/checkpoint-attribution.test.js.map +0 -1
  363. package/dist/test/code-execution.test.d.ts +0 -11
  364. package/dist/test/code-execution.test.d.ts.map +0 -1
  365. package/dist/test/code-execution.test.js +0 -1272
  366. package/dist/test/code-execution.test.js.map +0 -1
  367. package/dist/test/component-defaults.test.d.ts +0 -2
  368. package/dist/test/component-defaults.test.d.ts.map +0 -1
  369. package/dist/test/component-defaults.test.js +0 -54
  370. package/dist/test/component-defaults.test.js.map +0 -1
  371. package/dist/test/conversation-fork-injection-scoping.test.d.ts +0 -2
  372. package/dist/test/conversation-fork-injection-scoping.test.d.ts.map +0 -1
  373. package/dist/test/conversation-fork-injection-scoping.test.js +0 -200
  374. package/dist/test/conversation-fork-injection-scoping.test.js.map +0 -1
  375. package/dist/test/conversation-router.test.d.ts +0 -2
  376. package/dist/test/conversation-router.test.d.ts.map +0 -1
  377. package/dist/test/conversation-router.test.js +0 -174
  378. package/dist/test/conversation-router.test.js.map +0 -1
  379. package/dist/test/conversation-routing.test.d.ts +0 -7
  380. package/dist/test/conversation-routing.test.d.ts.map +0 -1
  381. package/dist/test/conversation-routing.test.js +0 -621
  382. package/dist/test/conversation-routing.test.js.map +0 -1
  383. package/dist/test/deferred-wake-integrity.test.d.ts +0 -29
  384. package/dist/test/deferred-wake-integrity.test.d.ts.map +0 -1
  385. package/dist/test/deferred-wake-integrity.test.js +0 -320
  386. package/dist/test/deferred-wake-integrity.test.js.map +0 -1
  387. package/dist/test/discord-awareness-outbox.test.d.ts +0 -2
  388. package/dist/test/discord-awareness-outbox.test.d.ts.map +0 -1
  389. package/dist/test/discord-awareness-outbox.test.js +0 -371
  390. package/dist/test/discord-awareness-outbox.test.js.map +0 -1
  391. package/dist/test/discord-history-delete-window.test.d.ts +0 -2
  392. package/dist/test/discord-history-delete-window.test.d.ts.map +0 -1
  393. package/dist/test/discord-history-delete-window.test.js +0 -81
  394. package/dist/test/discord-history-delete-window.test.js.map +0 -1
  395. package/dist/test/discord-history-sync.test.d.ts +0 -2
  396. package/dist/test/discord-history-sync.test.d.ts.map +0 -1
  397. package/dist/test/discord-history-sync.test.js +0 -56
  398. package/dist/test/discord-history-sync.test.js.map +0 -1
  399. package/dist/test/discord-typing-keepalive.test.d.ts +0 -2
  400. package/dist/test/discord-typing-keepalive.test.d.ts.map +0 -1
  401. package/dist/test/discord-typing-keepalive.test.js +0 -77
  402. package/dist/test/discord-typing-keepalive.test.js.map +0 -1
  403. package/dist/test/ephemeral-settle.test.d.ts +0 -2
  404. package/dist/test/ephemeral-settle.test.d.ts.map +0 -1
  405. package/dist/test/ephemeral-settle.test.js +0 -354
  406. package/dist/test/ephemeral-settle.test.js.map +0 -1
  407. package/dist/test/event-gate-passthrough.test.d.ts +0 -15
  408. package/dist/test/event-gate-passthrough.test.d.ts.map +0 -1
  409. package/dist/test/event-gate-passthrough.test.js +0 -289
  410. package/dist/test/event-gate-passthrough.test.js.map +0 -1
  411. package/dist/test/event-gate-policy-mutation.test.d.ts +0 -2
  412. package/dist/test/event-gate-policy-mutation.test.d.ts.map +0 -1
  413. package/dist/test/event-gate-policy-mutation.test.js +0 -137
  414. package/dist/test/event-gate-policy-mutation.test.js.map +0 -1
  415. package/dist/test/event-gate-rate-limit.test.d.ts +0 -2
  416. package/dist/test/event-gate-rate-limit.test.d.ts.map +0 -1
  417. package/dist/test/event-gate-rate-limit.test.js +0 -627
  418. package/dist/test/event-gate-rate-limit.test.js.map +0 -1
  419. package/dist/test/event-gate-script.test.d.ts +0 -2
  420. package/dist/test/event-gate-script.test.d.ts.map +0 -1
  421. package/dist/test/event-gate-script.test.js +0 -95
  422. package/dist/test/event-gate-script.test.js.map +0 -1
  423. package/dist/test/event-gate-selfwake.test.d.ts +0 -15
  424. package/dist/test/event-gate-selfwake.test.d.ts.map +0 -1
  425. package/dist/test/event-gate-selfwake.test.js +0 -125
  426. package/dist/test/event-gate-selfwake.test.js.map +0 -1
  427. package/dist/test/event-gate-tags.test.d.ts +0 -2
  428. package/dist/test/event-gate-tags.test.d.ts.map +0 -1
  429. package/dist/test/event-gate-tags.test.js +0 -76
  430. package/dist/test/event-gate-tags.test.js.map +0 -1
  431. package/dist/test/event-gate.test.d.ts +0 -2
  432. package/dist/test/event-gate.test.d.ts.map +0 -1
  433. package/dist/test/event-gate.test.js +0 -919
  434. package/dist/test/event-gate.test.js.map +0 -1
  435. package/dist/test/explicit-prose-routing.test.d.ts +0 -11
  436. package/dist/test/explicit-prose-routing.test.d.ts.map +0 -1
  437. package/dist/test/explicit-prose-routing.test.js +0 -1715
  438. package/dist/test/explicit-prose-routing.test.js.map +0 -1
  439. package/dist/test/framework.test.d.ts +0 -5
  440. package/dist/test/framework.test.d.ts.map +0 -1
  441. package/dist/test/framework.test.js +0 -1048
  442. package/dist/test/framework.test.js.map +0 -1
  443. package/dist/test/gather-context-timeout.test.d.ts +0 -2
  444. package/dist/test/gather-context-timeout.test.d.ts.map +0 -1
  445. package/dist/test/gather-context-timeout.test.js +0 -120
  446. package/dist/test/gather-context-timeout.test.js.map +0 -1
  447. package/dist/test/health-snapshot.test.d.ts +0 -2
  448. package/dist/test/health-snapshot.test.d.ts.map +0 -1
  449. package/dist/test/health-snapshot.test.js +0 -74
  450. package/dist/test/health-snapshot.test.js.map +0 -1
  451. package/dist/test/helpers/coalescing-fixture.d.ts +0 -74
  452. package/dist/test/helpers/coalescing-fixture.d.ts.map +0 -1
  453. package/dist/test/helpers/coalescing-fixture.js +0 -152
  454. package/dist/test/helpers/coalescing-fixture.js.map +0 -1
  455. package/dist/test/helpers/coalescing-kill-child.d.ts +0 -2
  456. package/dist/test/helpers/coalescing-kill-child.d.ts.map +0 -1
  457. package/dist/test/helpers/coalescing-kill-child.js +0 -24
  458. package/dist/test/helpers/coalescing-kill-child.js.map +0 -1
  459. package/dist/test/helpers/mock-membrane.d.ts +0 -53
  460. package/dist/test/helpers/mock-membrane.d.ts.map +0 -1
  461. package/dist/test/helpers/mock-membrane.js +0 -168
  462. package/dist/test/helpers/mock-membrane.js.map +0 -1
  463. package/dist/test/helpers/pytc-stop-rows.d.ts +0 -11
  464. package/dist/test/helpers/pytc-stop-rows.d.ts.map +0 -1
  465. package/dist/test/helpers/pytc-stop-rows.js +0 -143
  466. package/dist/test/helpers/pytc-stop-rows.js.map +0 -1
  467. package/dist/test/helpers/quiesce-crash-child.d.ts +0 -2
  468. package/dist/test/helpers/quiesce-crash-child.d.ts.map +0 -1
  469. package/dist/test/helpers/quiesce-crash-child.js +0 -156
  470. package/dist/test/helpers/quiesce-crash-child.js.map +0 -1
  471. package/dist/test/hide-then-turn.test.d.ts +0 -2
  472. package/dist/test/hide-then-turn.test.d.ts.map +0 -1
  473. package/dist/test/hide-then-turn.test.js +0 -101
  474. package/dist/test/hide-then-turn.test.js.map +0 -1
  475. package/dist/test/history-module-overview.test.d.ts +0 -2
  476. package/dist/test/history-module-overview.test.d.ts.map +0 -1
  477. package/dist/test/history-module-overview.test.js +0 -711
  478. package/dist/test/history-module-overview.test.js.map +0 -1
  479. package/dist/test/history-module-realstore.test.d.ts +0 -2
  480. package/dist/test/history-module-realstore.test.d.ts.map +0 -1
  481. package/dist/test/history-module-realstore.test.js +0 -363
  482. package/dist/test/history-module-realstore.test.js.map +0 -1
  483. package/dist/test/history-module-semantic.test.d.ts +0 -2
  484. package/dist/test/history-module-semantic.test.d.ts.map +0 -1
  485. package/dist/test/history-module-semantic.test.js +0 -213
  486. package/dist/test/history-module-semantic.test.js.map +0 -1
  487. package/dist/test/history-module-ux.test.d.ts +0 -2
  488. package/dist/test/history-module-ux.test.d.ts.map +0 -1
  489. package/dist/test/history-module-ux.test.js +0 -304
  490. package/dist/test/history-module-ux.test.js.map +0 -1
  491. package/dist/test/history-module.test.d.ts +0 -2
  492. package/dist/test/history-module.test.d.ts.map +0 -1
  493. package/dist/test/history-module.test.js +0 -619
  494. package/dist/test/history-module.test.js.map +0 -1
  495. package/dist/test/history-semantic-review-findings.test.d.ts +0 -2
  496. package/dist/test/history-semantic-review-findings.test.d.ts.map +0 -1
  497. package/dist/test/history-semantic-review-findings.test.js +0 -338
  498. package/dist/test/history-semantic-review-findings.test.js.map +0 -1
  499. package/dist/test/history-semantic-sync-converges.test.d.ts +0 -2
  500. package/dist/test/history-semantic-sync-converges.test.d.ts.map +0 -1
  501. package/dist/test/history-semantic-sync-converges.test.js +0 -109
  502. package/dist/test/history-semantic-sync-converges.test.js.map +0 -1
  503. package/dist/test/host-quiesce.test.d.ts +0 -2
  504. package/dist/test/host-quiesce.test.d.ts.map +0 -1
  505. package/dist/test/host-quiesce.test.js +0 -988
  506. package/dist/test/host-quiesce.test.js.map +0 -1
  507. package/dist/test/inference-exhaustion-rewind.test.d.ts +0 -2
  508. package/dist/test/inference-exhaustion-rewind.test.d.ts.map +0 -1
  509. package/dist/test/inference-exhaustion-rewind.test.js +0 -387
  510. package/dist/test/inference-exhaustion-rewind.test.js.map +0 -1
  511. package/dist/test/inference-failure-bounds.test.d.ts +0 -2
  512. package/dist/test/inference-failure-bounds.test.d.ts.map +0 -1
  513. package/dist/test/inference-failure-bounds.test.js +0 -1202
  514. package/dist/test/inference-failure-bounds.test.js.map +0 -1
  515. package/dist/test/inference-failure-observability.test.d.ts +0 -2
  516. package/dist/test/inference-failure-observability.test.d.ts.map +0 -1
  517. package/dist/test/inference-failure-observability.test.js +0 -84
  518. package/dist/test/inference-failure-observability.test.js.map +0 -1
  519. package/dist/test/journal-tool.test.d.ts +0 -2
  520. package/dist/test/journal-tool.test.d.ts.map +0 -1
  521. package/dist/test/journal-tool.test.js +0 -33
  522. package/dist/test/journal-tool.test.js.map +0 -1
  523. package/dist/test/kv-unified-open-flight-retry.test.d.ts +0 -2
  524. package/dist/test/kv-unified-open-flight-retry.test.d.ts.map +0 -1
  525. package/dist/test/kv-unified-open-flight-retry.test.js +0 -189
  526. package/dist/test/kv-unified-open-flight-retry.test.js.map +0 -1
  527. package/dist/test/kv-unified-wiring.test.d.ts +0 -2
  528. package/dist/test/kv-unified-wiring.test.d.ts.map +0 -1
  529. package/dist/test/kv-unified-wiring.test.js +0 -95
  530. package/dist/test/kv-unified-wiring.test.js.map +0 -1
  531. package/dist/test/late-events-after-stop.test.d.ts +0 -2
  532. package/dist/test/late-events-after-stop.test.d.ts.map +0 -1
  533. package/dist/test/late-events-after-stop.test.js +0 -122
  534. package/dist/test/late-events-after-stop.test.js.map +0 -1
  535. package/dist/test/liveness-watchdog.test.d.ts +0 -2
  536. package/dist/test/liveness-watchdog.test.d.ts.map +0 -1
  537. package/dist/test/liveness-watchdog.test.js +0 -94
  538. package/dist/test/liveness-watchdog.test.js.map +0 -1
  539. package/dist/test/machine-close-provenance.test.d.ts +0 -2
  540. package/dist/test/machine-close-provenance.test.d.ts.map +0 -1
  541. package/dist/test/machine-close-provenance.test.js +0 -116
  542. package/dist/test/machine-close-provenance.test.js.map +0 -1
  543. package/dist/test/maintenance-timer.test.d.ts +0 -2
  544. package/dist/test/maintenance-timer.test.d.ts.map +0 -1
  545. package/dist/test/maintenance-timer.test.js +0 -1827
  546. package/dist/test/maintenance-timer.test.js.map +0 -1
  547. package/dist/test/mcp-server-bin.test.d.ts +0 -2
  548. package/dist/test/mcp-server-bin.test.d.ts.map +0 -1
  549. package/dist/test/mcp-server-bin.test.js +0 -142
  550. package/dist/test/mcp-server-bin.test.js.map +0 -1
  551. package/dist/test/mcpl-access-provider.test.d.ts +0 -2
  552. package/dist/test/mcpl-access-provider.test.d.ts.map +0 -1
  553. package/dist/test/mcpl-access-provider.test.js +0 -20
  554. package/dist/test/mcpl-access-provider.test.js.map +0 -1
  555. package/dist/test/mcpl-awareness-barrier.test.d.ts +0 -2
  556. package/dist/test/mcpl-awareness-barrier.test.d.ts.map +0 -1
  557. package/dist/test/mcpl-awareness-barrier.test.js +0 -769
  558. package/dist/test/mcpl-awareness-barrier.test.js.map +0 -1
  559. package/dist/test/mcpl-capability-grant.test.d.ts +0 -10
  560. package/dist/test/mcpl-capability-grant.test.d.ts.map +0 -1
  561. package/dist/test/mcpl-capability-grant.test.js +0 -111
  562. package/dist/test/mcpl-capability-grant.test.js.map +0 -1
  563. package/dist/test/mcpl-capability-scoping.test.d.ts +0 -2
  564. package/dist/test/mcpl-capability-scoping.test.d.ts.map +0 -1
  565. package/dist/test/mcpl-capability-scoping.test.js +0 -266
  566. package/dist/test/mcpl-capability-scoping.test.js.map +0 -1
  567. package/dist/test/mcpl-child-env.test.d.ts +0 -2
  568. package/dist/test/mcpl-child-env.test.d.ts.map +0 -1
  569. package/dist/test/mcpl-child-env.test.js +0 -158
  570. package/dist/test/mcpl-child-env.test.js.map +0 -1
  571. package/dist/test/mcpl-coalesced-content-parity.test.d.ts +0 -2
  572. package/dist/test/mcpl-coalesced-content-parity.test.d.ts.map +0 -1
  573. package/dist/test/mcpl-coalesced-content-parity.test.js +0 -532
  574. package/dist/test/mcpl-coalesced-content-parity.test.js.map +0 -1
  575. package/dist/test/mcpl-coalescing.test.d.ts +0 -2
  576. package/dist/test/mcpl-coalescing.test.d.ts.map +0 -1
  577. package/dist/test/mcpl-coalescing.test.js +0 -1125
  578. package/dist/test/mcpl-coalescing.test.js.map +0 -1
  579. package/dist/test/mcpl-config-diagnostics.test.d.ts +0 -2
  580. package/dist/test/mcpl-config-diagnostics.test.d.ts.map +0 -1
  581. package/dist/test/mcpl-config-diagnostics.test.js +0 -452
  582. package/dist/test/mcpl-config-diagnostics.test.js.map +0 -1
  583. package/dist/test/mcpl-empty-content.test.d.ts +0 -2
  584. package/dist/test/mcpl-empty-content.test.d.ts.map +0 -1
  585. package/dist/test/mcpl-empty-content.test.js +0 -368
  586. package/dist/test/mcpl-empty-content.test.js.map +0 -1
  587. package/dist/test/mcpl-gate-roundtrip.test.d.ts +0 -2
  588. package/dist/test/mcpl-gate-roundtrip.test.d.ts.map +0 -1
  589. package/dist/test/mcpl-gate-roundtrip.test.js +0 -285
  590. package/dist/test/mcpl-gate-roundtrip.test.js.map +0 -1
  591. package/dist/test/mcpl-list-status.test.d.ts +0 -2
  592. package/dist/test/mcpl-list-status.test.d.ts.map +0 -1
  593. package/dist/test/mcpl-list-status.test.js +0 -82
  594. package/dist/test/mcpl-list-status.test.js.map +0 -1
  595. package/dist/test/mcpl-manifest-changed.test.d.ts +0 -2
  596. package/dist/test/mcpl-manifest-changed.test.d.ts.map +0 -1
  597. package/dist/test/mcpl-manifest-changed.test.js +0 -178
  598. package/dist/test/mcpl-manifest-changed.test.js.map +0 -1
  599. package/dist/test/mcpl-push-convert.test.d.ts +0 -2
  600. package/dist/test/mcpl-push-convert.test.d.ts.map +0 -1
  601. package/dist/test/mcpl-push-convert.test.js +0 -42
  602. package/dist/test/mcpl-push-convert.test.js.map +0 -1
  603. package/dist/test/mcpl-reconnect-events.test.d.ts +0 -2
  604. package/dist/test/mcpl-reconnect-events.test.d.ts.map +0 -1
  605. package/dist/test/mcpl-reconnect-events.test.js +0 -144
  606. package/dist/test/mcpl-reconnect-events.test.js.map +0 -1
  607. package/dist/test/mcpl-reconnect-reregistration.test.d.ts +0 -2
  608. package/dist/test/mcpl-reconnect-reregistration.test.d.ts.map +0 -1
  609. package/dist/test/mcpl-reconnect-reregistration.test.js +0 -238
  610. package/dist/test/mcpl-reconnect-reregistration.test.js.map +0 -1
  611. package/dist/test/mcpl-reference-fetcher.test.d.ts +0 -2
  612. package/dist/test/mcpl-reference-fetcher.test.d.ts.map +0 -1
  613. package/dist/test/mcpl-reference-fetcher.test.js +0 -427
  614. package/dist/test/mcpl-reference-fetcher.test.js.map +0 -1
  615. package/dist/test/mcpl-reference-fields.test.d.ts +0 -2
  616. package/dist/test/mcpl-reference-fields.test.d.ts.map +0 -1
  617. package/dist/test/mcpl-reference-fields.test.js +0 -149
  618. package/dist/test/mcpl-reference-fields.test.js.map +0 -1
  619. package/dist/test/mcpl-rejection-log-lines.test.d.ts +0 -2
  620. package/dist/test/mcpl-rejection-log-lines.test.d.ts.map +0 -1
  621. package/dist/test/mcpl-rejection-log-lines.test.js +0 -349
  622. package/dist/test/mcpl-rejection-log-lines.test.js.map +0 -1
  623. package/dist/test/mcpl-request-timeout.test.d.ts +0 -2
  624. package/dist/test/mcpl-request-timeout.test.d.ts.map +0 -1
  625. package/dist/test/mcpl-request-timeout.test.js +0 -138
  626. package/dist/test/mcpl-request-timeout.test.js.map +0 -1
  627. package/dist/test/mcpl-runtime-lifecycle.test.d.ts +0 -7
  628. package/dist/test/mcpl-runtime-lifecycle.test.d.ts.map +0 -1
  629. package/dist/test/mcpl-runtime-lifecycle.test.js +0 -142
  630. package/dist/test/mcpl-runtime-lifecycle.test.js.map +0 -1
  631. package/dist/test/mcpl-stderr-tail.test.d.ts +0 -2
  632. package/dist/test/mcpl-stderr-tail.test.d.ts.map +0 -1
  633. package/dist/test/mcpl-stderr-tail.test.js +0 -210
  634. package/dist/test/mcpl-stderr-tail.test.js.map +0 -1
  635. package/dist/test/mcpl-tool-class-listing.test.d.ts +0 -2
  636. package/dist/test/mcpl-tool-class-listing.test.d.ts.map +0 -1
  637. package/dist/test/mcpl-tool-class-listing.test.js +0 -147
  638. package/dist/test/mcpl-tool-class-listing.test.js.map +0 -1
  639. package/dist/test/mcpl-tool-classes.test.d.ts +0 -7
  640. package/dist/test/mcpl-tool-classes.test.d.ts.map +0 -1
  641. package/dist/test/mcpl-tool-classes.test.js +0 -80
  642. package/dist/test/mcpl-tool-classes.test.js.map +0 -1
  643. package/dist/test/mcpl-tool-lifecycle-e2e.test.d.ts +0 -2
  644. package/dist/test/mcpl-tool-lifecycle-e2e.test.d.ts.map +0 -1
  645. package/dist/test/mcpl-tool-lifecycle-e2e.test.js +0 -237
  646. package/dist/test/mcpl-tool-lifecycle-e2e.test.js.map +0 -1
  647. package/dist/test/mcpl-tool-lifecycle-emitter.test.d.ts +0 -11
  648. package/dist/test/mcpl-tool-lifecycle-emitter.test.d.ts.map +0 -1
  649. package/dist/test/mcpl-tool-lifecycle-emitter.test.js +0 -412
  650. package/dist/test/mcpl-tool-lifecycle-emitter.test.js.map +0 -1
  651. package/dist/test/mcpl-tool-lifecycle-script.test.d.ts +0 -2
  652. package/dist/test/mcpl-tool-lifecycle-script.test.d.ts.map +0 -1
  653. package/dist/test/mcpl-tool-lifecycle-script.test.js +0 -288
  654. package/dist/test/mcpl-tool-lifecycle-script.test.js.map +0 -1
  655. package/dist/test/mcpl-tool-lifecycle.test.d.ts +0 -11
  656. package/dist/test/mcpl-tool-lifecycle.test.d.ts.map +0 -1
  657. package/dist/test/mcpl-tool-lifecycle.test.js +0 -270
  658. package/dist/test/mcpl-tool-lifecycle.test.js.map +0 -1
  659. package/dist/test/mcpl-transport-close.test.d.ts +0 -2
  660. package/dist/test/mcpl-transport-close.test.d.ts.map +0 -1
  661. package/dist/test/mcpl-transport-close.test.js +0 -373
  662. package/dist/test/mcpl-transport-close.test.js.map +0 -1
  663. package/dist/test/mcpl-transport-spawn.test.d.ts +0 -2
  664. package/dist/test/mcpl-transport-spawn.test.d.ts.map +0 -1
  665. package/dist/test/mcpl-transport-spawn.test.js +0 -58
  666. package/dist/test/mcpl-transport-spawn.test.js.map +0 -1
  667. package/dist/test/mcpl-ws-transport.test.d.ts +0 -2
  668. package/dist/test/mcpl-ws-transport.test.d.ts.map +0 -1
  669. package/dist/test/mcpl-ws-transport.test.js +0 -259
  670. package/dist/test/mcpl-ws-transport.test.js.map +0 -1
  671. package/dist/test/module-context-integration.test.d.ts +0 -18
  672. package/dist/test/module-context-integration.test.d.ts.map +0 -1
  673. package/dist/test/module-context-integration.test.js +0 -181
  674. package/dist/test/module-context-integration.test.js.map +0 -1
  675. package/dist/test/offline-recovery-branch.test.d.ts +0 -2
  676. package/dist/test/offline-recovery-branch.test.d.ts.map +0 -1
  677. package/dist/test/offline-recovery-branch.test.js +0 -570
  678. package/dist/test/offline-recovery-branch.test.js.map +0 -1
  679. package/dist/test/operator-surgery.test.d.ts +0 -2
  680. package/dist/test/operator-surgery.test.d.ts.map +0 -1
  681. package/dist/test/operator-surgery.test.js +0 -595
  682. package/dist/test/operator-surgery.test.js.map +0 -1
  683. package/dist/test/ops-alert.test.d.ts +0 -2
  684. package/dist/test/ops-alert.test.d.ts.map +0 -1
  685. package/dist/test/ops-alert.test.js +0 -153
  686. package/dist/test/ops-alert.test.js.map +0 -1
  687. package/dist/test/overbudget-drain-breaker.test.d.ts +0 -2
  688. package/dist/test/overbudget-drain-breaker.test.d.ts.map +0 -1
  689. package/dist/test/overbudget-drain-breaker.test.js +0 -198
  690. package/dist/test/overbudget-drain-breaker.test.js.map +0 -1
  691. package/dist/test/pack-installs-alone.test.d.ts +0 -2
  692. package/dist/test/pack-installs-alone.test.d.ts.map +0 -1
  693. package/dist/test/pack-installs-alone.test.js +0 -284
  694. package/dist/test/pack-installs-alone.test.js.map +0 -1
  695. package/dist/test/per-agent-delivery.test.d.ts +0 -2
  696. package/dist/test/per-agent-delivery.test.d.ts.map +0 -1
  697. package/dist/test/per-agent-delivery.test.js +0 -108
  698. package/dist/test/per-agent-delivery.test.js.map +0 -1
  699. package/dist/test/physical-window-restart.test.d.ts +0 -16
  700. package/dist/test/physical-window-restart.test.d.ts.map +0 -1
  701. package/dist/test/physical-window-restart.test.js +0 -487
  702. package/dist/test/physical-window-restart.test.js.map +0 -1
  703. package/dist/test/placed-reaction-baseline.test.d.ts +0 -2
  704. package/dist/test/placed-reaction-baseline.test.d.ts.map +0 -1
  705. package/dist/test/placed-reaction-baseline.test.js +0 -312
  706. package/dist/test/placed-reaction-baseline.test.js.map +0 -1
  707. package/dist/test/present-while-acting.test.d.ts +0 -19
  708. package/dist/test/present-while-acting.test.d.ts.map +0 -1
  709. package/dist/test/present-while-acting.test.js +0 -1649
  710. package/dist/test/present-while-acting.test.js.map +0 -1
  711. package/dist/test/prose-segments.test.d.ts +0 -2
  712. package/dist/test/prose-segments.test.d.ts.map +0 -1
  713. package/dist/test/prose-segments.test.js +0 -52
  714. package/dist/test/prose-segments.test.js.map +0 -1
  715. package/dist/test/prose-stream-router.test.d.ts +0 -2
  716. package/dist/test/prose-stream-router.test.d.ts.map +0 -1
  717. package/dist/test/prose-stream-router.test.js +0 -171
  718. package/dist/test/prose-stream-router.test.js.map +0 -1
  719. package/dist/test/provider-acceleration-cooldown.test.d.ts +0 -2
  720. package/dist/test/provider-acceleration-cooldown.test.d.ts.map +0 -1
  721. package/dist/test/provider-acceleration-cooldown.test.js +0 -435
  722. package/dist/test/provider-acceleration-cooldown.test.js.map +0 -1
  723. package/dist/test/provider-waits.test.d.ts +0 -2
  724. package/dist/test/provider-waits.test.d.ts.map +0 -1
  725. package/dist/test/provider-waits.test.js +0 -2259
  726. package/dist/test/provider-waits.test.js.map +0 -1
  727. package/dist/test/puppet-tool-call.test.d.ts +0 -2
  728. package/dist/test/puppet-tool-call.test.d.ts.map +0 -1
  729. package/dist/test/puppet-tool-call.test.js +0 -226
  730. package/dist/test/puppet-tool-call.test.js.map +0 -1
  731. package/dist/test/puppet-turn-reservation.test.d.ts +0 -2
  732. package/dist/test/puppet-turn-reservation.test.d.ts.map +0 -1
  733. package/dist/test/puppet-turn-reservation.test.js +0 -139
  734. package/dist/test/puppet-turn-reservation.test.js.map +0 -1
  735. package/dist/test/reaction-baseline-platform.test.d.ts +0 -2
  736. package/dist/test/reaction-baseline-platform.test.d.ts.map +0 -1
  737. package/dist/test/reaction-baseline-platform.test.js +0 -124
  738. package/dist/test/reaction-baseline-platform.test.js.map +0 -1
  739. package/dist/test/record-journal.test.d.ts +0 -6
  740. package/dist/test/record-journal.test.d.ts.map +0 -1
  741. package/dist/test/record-journal.test.js +0 -269
  742. package/dist/test/record-journal.test.js.map +0 -1
  743. package/dist/test/refusal-reaction-baseline.test.d.ts +0 -2
  744. package/dist/test/refusal-reaction-baseline.test.d.ts.map +0 -1
  745. package/dist/test/refusal-reaction-baseline.test.js +0 -81
  746. package/dist/test/refusal-reaction-baseline.test.js.map +0 -1
  747. package/dist/test/refusal-rewind.test.d.ts +0 -2
  748. package/dist/test/refusal-rewind.test.d.ts.map +0 -1
  749. package/dist/test/refusal-rewind.test.js +0 -117
  750. package/dist/test/refusal-rewind.test.js.map +0 -1
  751. package/dist/test/refusal-single-call.test.d.ts +0 -2
  752. package/dist/test/refusal-single-call.test.d.ts.map +0 -1
  753. package/dist/test/refusal-single-call.test.js +0 -177
  754. package/dist/test/refusal-single-call.test.js.map +0 -1
  755. package/dist/test/release-bump.test.d.ts +0 -2
  756. package/dist/test/release-bump.test.d.ts.map +0 -1
  757. package/dist/test/release-bump.test.js +0 -248
  758. package/dist/test/release-bump.test.js.map +0 -1
  759. package/dist/test/release-changelog.test.d.ts +0 -2
  760. package/dist/test/release-changelog.test.d.ts.map +0 -1
  761. package/dist/test/release-changelog.test.js +0 -159
  762. package/dist/test/release-changelog.test.js.map +0 -1
  763. package/dist/test/release-holds.test.d.ts +0 -2
  764. package/dist/test/release-holds.test.d.ts.map +0 -1
  765. package/dist/test/release-holds.test.js +0 -456
  766. package/dist/test/release-holds.test.js.map +0 -1
  767. package/dist/test/same-round-think-policy.test.d.ts +0 -2
  768. package/dist/test/same-round-think-policy.test.d.ts.map +0 -1
  769. package/dist/test/same-round-think-policy.test.js +0 -853
  770. package/dist/test/same-round-think-policy.test.js.map +0 -1
  771. package/dist/test/save-recent-image.test.d.ts +0 -26
  772. package/dist/test/save-recent-image.test.d.ts.map +0 -1
  773. package/dist/test/save-recent-image.test.js +0 -974
  774. package/dist/test/save-recent-image.test.js.map +0 -1
  775. package/dist/test/shutdown-errors.test.d.ts +0 -2
  776. package/dist/test/shutdown-errors.test.d.ts.map +0 -1
  777. package/dist/test/shutdown-errors.test.js +0 -662
  778. package/dist/test/shutdown-errors.test.js.map +0 -1
  779. package/dist/test/silent-heartbeat-rows.test.d.ts +0 -2
  780. package/dist/test/silent-heartbeat-rows.test.d.ts.map +0 -1
  781. package/dist/test/silent-heartbeat-rows.test.js +0 -451
  782. package/dist/test/silent-heartbeat-rows.test.js.map +0 -1
  783. package/dist/test/silent-heartbeat.test.d.ts +0 -2
  784. package/dist/test/silent-heartbeat.test.d.ts.map +0 -1
  785. package/dist/test/silent-heartbeat.test.js +0 -165
  786. package/dist/test/silent-heartbeat.test.js.map +0 -1
  787. package/dist/test/state-scaling-e2e.test.d.ts +0 -22
  788. package/dist/test/state-scaling-e2e.test.d.ts.map +0 -1
  789. package/dist/test/state-scaling-e2e.test.js +0 -206
  790. package/dist/test/state-scaling-e2e.test.js.map +0 -1
  791. package/dist/test/state-scaling.test.d.ts +0 -12
  792. package/dist/test/state-scaling.test.d.ts.map +0 -1
  793. package/dist/test/state-scaling.test.js +0 -251
  794. package/dist/test/state-scaling.test.js.map +0 -1
  795. package/dist/test/stop-with-host-operations.test.d.ts +0 -20
  796. package/dist/test/stop-with-host-operations.test.d.ts.map +0 -1
  797. package/dist/test/stop-with-host-operations.test.js +0 -1174
  798. package/dist/test/stop-with-host-operations.test.js.map +0 -1
  799. package/dist/test/stop-with-work-in-flight.test.d.ts +0 -23
  800. package/dist/test/stop-with-work-in-flight.test.d.ts.map +0 -1
  801. package/dist/test/stop-with-work-in-flight.test.js +0 -784
  802. package/dist/test/stop-with-work-in-flight.test.js.map +0 -1
  803. package/dist/test/surgery-marks-receipt.test.d.ts +0 -2
  804. package/dist/test/surgery-marks-receipt.test.d.ts.map +0 -1
  805. package/dist/test/surgery-marks-receipt.test.js +0 -540
  806. package/dist/test/surgery-marks-receipt.test.js.map +0 -1
  807. package/dist/test/thinking-token-stamp.test.d.ts +0 -12
  808. package/dist/test/thinking-token-stamp.test.d.ts.map +0 -1
  809. package/dist/test/thinking-token-stamp.test.js +0 -129
  810. package/dist/test/thinking-token-stamp.test.js.map +0 -1
  811. package/dist/test/timezone.test.d.ts +0 -2
  812. package/dist/test/timezone.test.d.ts.map +0 -1
  813. package/dist/test/timezone.test.js +0 -18
  814. package/dist/test/timezone.test.js.map +0 -1
  815. package/dist/test/tool-batch-hook.test.d.ts +0 -8
  816. package/dist/test/tool-batch-hook.test.d.ts.map +0 -1
  817. package/dist/test/tool-batch-hook.test.js +0 -275
  818. package/dist/test/tool-batch-hook.test.js.map +0 -1
  819. package/dist/test/tool-policy.test.d.ts +0 -2
  820. package/dist/test/tool-policy.test.d.ts.map +0 -1
  821. package/dist/test/tool-policy.test.js +0 -51
  822. package/dist/test/tool-policy.test.js.map +0 -1
  823. package/dist/test/tool-presentation.test.d.ts +0 -2
  824. package/dist/test/tool-presentation.test.d.ts.map +0 -1
  825. package/dist/test/tool-presentation.test.js +0 -268
  826. package/dist/test/tool-presentation.test.js.map +0 -1
  827. package/dist/test/tool-result-content.test.d.ts +0 -2
  828. package/dist/test/tool-result-content.test.d.ts.map +0 -1
  829. package/dist/test/tool-result-content.test.js +0 -37
  830. package/dist/test/tool-result-content.test.js.map +0 -1
  831. package/dist/test/tool-result-guard.test.d.ts +0 -2
  832. package/dist/test/tool-result-guard.test.d.ts.map +0 -1
  833. package/dist/test/tool-result-guard.test.js +0 -3729
  834. package/dist/test/tool-result-guard.test.js.map +0 -1
  835. package/dist/test/tool-result-history.test.d.ts +0 -7
  836. package/dist/test/tool-result-history.test.d.ts.map +0 -1
  837. package/dist/test/tool-result-history.test.js +0 -156
  838. package/dist/test/tool-result-history.test.js.map +0 -1
  839. package/dist/test/tool-result-spill.test.d.ts +0 -13
  840. package/dist/test/tool-result-spill.test.d.ts.map +0 -1
  841. package/dist/test/tool-result-spill.test.js +0 -586
  842. package/dist/test/tool-result-spill.test.js.map +0 -1
  843. package/dist/test/tool-wrapper-prose-guard-integration.test.d.ts +0 -2
  844. package/dist/test/tool-wrapper-prose-guard-integration.test.d.ts.map +0 -1
  845. package/dist/test/tool-wrapper-prose-guard-integration.test.js +0 -485
  846. package/dist/test/tool-wrapper-prose-guard-integration.test.js.map +0 -1
  847. package/dist/test/tool-wrapper-prose-guard.test.d.ts +0 -2
  848. package/dist/test/tool-wrapper-prose-guard.test.d.ts.map +0 -1
  849. package/dist/test/tool-wrapper-prose-guard.test.js +0 -34
  850. package/dist/test/tool-wrapper-prose-guard.test.js.map +0 -1
  851. package/dist/test/tools-observe-parser-conformance.test.d.ts +0 -2
  852. package/dist/test/tools-observe-parser-conformance.test.d.ts.map +0 -1
  853. package/dist/test/tools-observe-parser-conformance.test.js +0 -129
  854. package/dist/test/tools-observe-parser-conformance.test.js.map +0 -1
  855. package/dist/test/trunk-channel-routing.test.d.ts +0 -19
  856. package/dist/test/trunk-channel-routing.test.d.ts.map +0 -1
  857. package/dist/test/trunk-channel-routing.test.js +0 -652
  858. package/dist/test/trunk-channel-routing.test.js.map +0 -1
  859. package/dist/test/tune-out-e2e.test.d.ts +0 -2
  860. package/dist/test/tune-out-e2e.test.d.ts.map +0 -1
  861. package/dist/test/tune-out-e2e.test.js +0 -142
  862. package/dist/test/tune-out-e2e.test.js.map +0 -1
  863. package/dist/test/tune-out-gate-composition.test.d.ts +0 -2
  864. package/dist/test/tune-out-gate-composition.test.d.ts.map +0 -1
  865. package/dist/test/tune-out-gate-composition.test.js +0 -221
  866. package/dist/test/tune-out-gate-composition.test.js.map +0 -1
  867. package/dist/test/tune-out-lifecycle.test.d.ts +0 -2
  868. package/dist/test/tune-out-lifecycle.test.d.ts.map +0 -1
  869. package/dist/test/tune-out-lifecycle.test.js +0 -121
  870. package/dist/test/tune-out-lifecycle.test.js.map +0 -1
  871. package/dist/test/turn-trigger-provenance.test.d.ts +0 -2
  872. package/dist/test/turn-trigger-provenance.test.d.ts.map +0 -1
  873. package/dist/test/turn-trigger-provenance.test.js +0 -137
  874. package/dist/test/turn-trigger-provenance.test.js.map +0 -1
  875. package/dist/test/unconvertible-tool-result.test.d.ts +0 -2
  876. package/dist/test/unconvertible-tool-result.test.d.ts.map +0 -1
  877. package/dist/test/unconvertible-tool-result.test.js +0 -358
  878. package/dist/test/unconvertible-tool-result.test.js.map +0 -1
  879. package/dist/test/unsent-compiles.test.d.ts +0 -2
  880. package/dist/test/unsent-compiles.test.d.ts.map +0 -1
  881. package/dist/test/unsent-compiles.test.js +0 -139
  882. package/dist/test/unsent-compiles.test.js.map +0 -1
  883. package/dist/test/usage-accounting.test.d.ts +0 -2
  884. package/dist/test/usage-accounting.test.d.ts.map +0 -1
  885. package/dist/test/usage-accounting.test.js +0 -13
  886. package/dist/test/usage-accounting.test.js.map +0 -1
  887. package/dist/test/usage-tracker.test.d.ts +0 -2
  888. package/dist/test/usage-tracker.test.d.ts.map +0 -1
  889. package/dist/test/usage-tracker.test.js +0 -129
  890. package/dist/test/usage-tracker.test.js.map +0 -1
  891. package/dist/test/utils-surface.test.d.ts +0 -2
  892. package/dist/test/utils-surface.test.d.ts.map +0 -1
  893. package/dist/test/utils-surface.test.js +0 -145
  894. package/dist/test/utils-surface.test.js.map +0 -1
  895. package/dist/test/workspace-branch-continuation.test.d.ts +0 -15
  896. package/dist/test/workspace-branch-continuation.test.d.ts.map +0 -1
  897. package/dist/test/workspace-branch-continuation.test.js +0 -183
  898. package/dist/test/workspace-branch-continuation.test.js.map +0 -1
  899. package/dist/test/workspace-materialize-freshness.test.d.ts +0 -16
  900. package/dist/test/workspace-materialize-freshness.test.d.ts.map +0 -1
  901. package/dist/test/workspace-materialize-freshness.test.js +0 -252
  902. package/dist/test/workspace-materialize-freshness.test.js.map +0 -1
  903. package/dist/test/workspace-path-containment.test.d.ts +0 -19
  904. package/dist/test/workspace-path-containment.test.d.ts.map +0 -1
  905. package/dist/test/workspace-path-containment.test.js +0 -91
  906. package/dist/test/workspace-path-containment.test.js.map +0 -1
  907. package/dist/test/workspace-read-file-from-disk.test.d.ts +0 -17
  908. package/dist/test/workspace-read-file-from-disk.test.d.ts.map +0 -1
  909. package/dist/test/workspace-read-file-from-disk.test.js +0 -174
  910. package/dist/test/workspace-read-file-from-disk.test.js.map +0 -1
  911. package/dist/test/workspace-read-image.test.d.ts +0 -2
  912. package/dist/test/workspace-read-image.test.d.ts.map +0 -1
  913. package/dist/test/workspace-read-image.test.js +0 -597
  914. package/dist/test/workspace-read-image.test.js.map +0 -1
  915. package/dist/test/workspace-read-text.test.d.ts +0 -2
  916. package/dist/test/workspace-read-text.test.d.ts.map +0 -1
  917. package/dist/test/workspace-read-text.test.js +0 -101
  918. package/dist/test/workspace-read-text.test.js.map +0 -1
  919. package/dist/test/workspace-restore-order.test.d.ts +0 -16
  920. package/dist/test/workspace-restore-order.test.d.ts.map +0 -1
  921. package/dist/test/workspace-restore-order.test.js +0 -140
  922. package/dist/test/workspace-restore-order.test.js.map +0 -1
  923. package/dist/test/workspace-three-way.test.d.ts +0 -12
  924. package/dist/test/workspace-three-way.test.d.ts.map +0 -1
  925. package/dist/test/workspace-three-way.test.js +0 -4094
  926. package/dist/test/workspace-three-way.test.js.map +0 -1
  927. package/dist/test/workspace-watcher.test.d.ts +0 -2
  928. package/dist/test/workspace-watcher.test.d.ts.map +0 -1
  929. package/dist/test/workspace-watcher.test.js +0 -281
  930. package/dist/test/workspace-watcher.test.js.map +0 -1
  931. package/dist/test/xml-round-persist.test.d.ts +0 -19
  932. package/dist/test/xml-round-persist.test.d.ts.map +0 -1
  933. package/dist/test/xml-round-persist.test.js +0 -235
  934. package/dist/test/xml-round-persist.test.js.map +0 -1
  935. package/dist/tsconfig.tsbuildinfo +0 -1
@@ -1,621 +0,0 @@
1
- /**
2
- * Integration tests for per-channel conversation routing: incoming MCPL
3
- * channel messages spawn/route to fork agents instead of the primary
4
- * conversation when FrameworkConfig.conversations is set.
5
- */
6
- import { describe, it, beforeEach, afterEach, mock } from 'node:test';
7
- import assert from 'node:assert/strict';
8
- import { tmpdir } from 'node:os';
9
- import { mkdtempSync, rmSync } from 'node:fs';
10
- import { join } from 'node:path';
11
- import { AgentFramework } from '../src/index.js';
12
- import { Membrane, OpenAIResponsesAPIAdapter, OpenAIResponsesFormatter } from '@animalabs/membrane';
13
- import { MockMembrane, createMockResponse } from './helpers/mock-membrane.js';
14
- function incomingEvent(overrides) {
15
- return {
16
- type: 'mcpl:channel-incoming',
17
- serverId: 'srv',
18
- channelId: overrides.channelId,
19
- messageId: overrides.messageId ?? `m-${Math.random().toString(36).slice(2)}`,
20
- author: { id: 'U1', name: 'alice' },
21
- content: [{ type: 'text', text: overrides.text }],
22
- timestamp: new Date().toISOString(),
23
- metadata: {
24
- mentioned: overrides.mentioned ?? false,
25
- ...(overrides.channelType ? { channel_type: overrides.channelType } : {}),
26
- },
27
- triggerInference: true,
28
- };
29
- }
30
- describe('Conversation routing', () => {
31
- let tempDir;
32
- let membrane;
33
- beforeEach(() => {
34
- tempDir = mkdtempSync(join(tmpdir(), 'conv-routing-test-'));
35
- membrane = new MockMembrane();
36
- });
37
- afterEach(() => {
38
- rmSync(tempDir, { recursive: true, force: true });
39
- });
40
- async function makeFramework(conversations = {}, storeFile = 'test.chronicle') {
41
- return AgentFramework.create({
42
- storePath: join(tempDir, storeFile),
43
- membrane: membrane.asMembrane(),
44
- agents: [
45
- { name: 'trunk', model: 'test-model', systemPrompt: 'You are the trunk.' },
46
- ],
47
- modules: [],
48
- conversations: { templateAgent: 'trunk', ...conversations },
49
- });
50
- }
51
- /** Make a binding look idle past the TTL and re-arm the sweep throttle —
52
- * deterministic expiry instead of racing a 1ms TTL against the wall clock. */
53
- function forceExpiry(framework, channelId, idleTtlMs) {
54
- const binding = framework.getConversationRouter().getBinding(channelId);
55
- assert.ok(binding, `binding for ${channelId} should exist before forcing expiry`);
56
- binding.lastActivity = Date.now() - idleTtlMs - 1_000;
57
- framework.lastConversationSweep = 0;
58
- }
59
- it('rejects an unknown template agent at creation', async () => {
60
- await assert.rejects(() => AgentFramework.create({
61
- storePath: join(tempDir, 'test.chronicle'),
62
- membrane: membrane.asMembrane(),
63
- agents: [{ name: 'trunk', model: 'test-model', systemPrompt: 'x' }],
64
- modules: [],
65
- conversations: { templateAgent: 'nope' },
66
- }), /templateAgent "nope"/);
67
- });
68
- // Deprecation (agent-framework#235): behavior unchanged, one stderr line.
69
- function deprecationWarnings(warn) {
70
- return warn.mock.calls
71
- .map((c) => String(c.arguments[0]))
72
- .filter((line) => line.startsWith('[deprecated]') && line.includes('conversation routing'));
73
- }
74
- it('configured: logs one [deprecated] line per framework and still routes', async () => {
75
- const warn = mock.method(console, 'warn', () => { });
76
- let framework;
77
- try {
78
- framework = await makeFramework();
79
- assert.equal(deprecationWarnings(warn).length, 1, 'warned once at creation');
80
- assert.match(deprecationWarnings(warn)[0], /agent-framework#235/);
81
- // Routing is unchanged: a DM and a channel mention each spawn a fork.
82
- // (One queued response per stream: MockMembrane hands a stream every
83
- // response still queued.)
84
- membrane.pushResponse(createMockResponse([{ type: 'text', text: 'Hi alice!' }]));
85
- framework.pushEvent(incomingEvent({ channelId: 'slack:D1', text: 'hello there', channelType: 'im' }));
86
- await framework.runUntilIdle();
87
- membrane.pushResponse(createMockResponse([{ type: 'text', text: 'On it.' }]));
88
- framework.pushEvent(incomingEvent({ channelId: 'slack:C1', text: 'bot, help', mentioned: true }));
89
- await framework.runUntilIdle();
90
- assert.ok(framework.getAgent('conversation-slack-D1-g1'), 'DM fork spawned');
91
- assert.ok(framework.getAgent('conversation-slack-C1-g1'), 'channel-mention fork spawned');
92
- assert.equal(membrane.calls.length, 2, 'both forks ran inference');
93
- assert.equal(deprecationWarnings(warn).length, 1, 'spawning forks does not warn again');
94
- }
95
- finally {
96
- warn.mock.restore();
97
- await framework?.stop();
98
- }
99
- });
100
- it('not configured: no [deprecated] line', async () => {
101
- const warn = mock.method(console, 'warn', () => { });
102
- let framework;
103
- try {
104
- membrane.pushResponse(createMockResponse([{ type: 'text', text: 'Hi alice!' }]));
105
- framework = await AgentFramework.create({
106
- storePath: join(tempDir, 'test.chronicle'),
107
- membrane: membrane.asMembrane(),
108
- agents: [{ name: 'trunk', model: 'test-model', systemPrompt: 'You are the trunk.' }],
109
- modules: [],
110
- });
111
- framework.pushEvent(incomingEvent({ channelId: 'slack:D1', text: 'hello there', channelType: 'im' }));
112
- await framework.runUntilIdle();
113
- assert.equal(framework.getConversationRouter(), null);
114
- assert.deepEqual(deprecationWarnings(warn), []);
115
- }
116
- finally {
117
- warn.mock.restore();
118
- await framework?.stop();
119
- }
120
- });
121
- it('DM message spawns a fork, routes the message there, and triggers inference', async () => {
122
- membrane.pushResponse(createMockResponse([{ type: 'text', text: 'Hi alice!' }]));
123
- const framework = await makeFramework();
124
- framework.pushEvent(incomingEvent({
125
- channelId: 'slack:D1', text: 'hello there', channelType: 'im',
126
- }));
127
- await framework.runUntilIdle();
128
- const fork = framework.getAgent('conversation-slack-D1-g1');
129
- assert.ok(fork, 'fork agent should exist');
130
- // Message landed in the fork's context, not the trunk's.
131
- const { messages: forkMessages } = await fork.getContextManager().compile();
132
- assert.ok(forkMessages.some((m) => JSON.stringify(m.content).includes('hello there')), 'fork context should contain the incoming message');
133
- const trunk = framework.getAgent('trunk');
134
- const { messages: trunkMessages } = await trunk.getContextManager().compile();
135
- assert.ok(!trunkMessages.some((m) => JSON.stringify(m.content).includes('hello there')), 'trunk context must not receive routed messages');
136
- // Inference ran for the fork.
137
- assert.ok(membrane.calls.length >= 1, 'inference should have been triggered');
138
- // Binding is live.
139
- const router = framework.getConversationRouter();
140
- assert.equal(router.getBinding('slack:D1')?.agentName, 'conversation-slack-D1-g1');
141
- await framework.stop();
142
- });
143
- it('channel message without mention is dropped; mention spawns', async () => {
144
- membrane.pushResponse(createMockResponse([{ type: 'text', text: 'On it.' }]));
145
- const framework = await makeFramework();
146
- framework.pushEvent(incomingEvent({ channelId: 'slack:C1', text: 'just chatting' }));
147
- await framework.runUntilIdle();
148
- assert.equal(framework.getAgent('conversation-slack-C1-g1'), null, 'no fork without mention');
149
- assert.equal(membrane.calls.length, 0, 'no inference for unrouted messages');
150
- framework.pushEvent(incomingEvent({ channelId: 'slack:C1', text: 'bot, help', mentioned: true }));
151
- await framework.runUntilIdle();
152
- assert.ok(framework.getAgent('conversation-slack-C1-g1'), 'mention spawns fork');
153
- await framework.stop();
154
- });
155
- it('non-mention on a bound channel lands in context without triggering', async () => {
156
- membrane.pushResponse(createMockResponse([{ type: 'text', text: 'ack' }]));
157
- const framework = await makeFramework();
158
- framework.pushEvent(incomingEvent({ channelId: 'slack:C1', text: 'first', mentioned: true }));
159
- await framework.runUntilIdle();
160
- const callsAfterSpawn = membrane.calls.length;
161
- framework.pushEvent(incomingEvent({ channelId: 'slack:C1', text: 'ambient detail' }));
162
- await framework.runUntilIdle();
163
- const fork = framework.getAgent('conversation-slack-C1-g1');
164
- const { messages } = await fork.getContextManager().compile();
165
- assert.ok(messages.some((m) => JSON.stringify(m.content).includes('ambient detail')), 'ambient message should land in fork context');
166
- assert.equal(membrane.calls.length, callsAfterSpawn, 'ambient message must not trigger inference');
167
- await framework.stop();
168
- });
169
- /** Spawn the fork for `slack:D3`, and return what its namespace was seeded
170
- * with and the `[conversation]` lines the spawn logged. */
171
- async function seedOf(framework) {
172
- const log = mock.method(console, 'log', () => { });
173
- let lines;
174
- try {
175
- framework.pushEvent(incomingEvent({ channelId: 'slack:D3', text: 'hi', channelType: 'im' }));
176
- await framework.runUntilIdle();
177
- lines = log.mock.calls.map((c) => String(c.arguments[0])).filter((line) => line.startsWith('[conversation]'));
178
- }
179
- finally {
180
- log.mock.restore();
181
- }
182
- const seeded = framework.getAgent('conversation-slack-D3-g1').getContextManager().getAllMessages();
183
- return { seeded, lines };
184
- }
185
- /** The line a spawn logs for a seed that left something out. */
186
- function seedLine(thinking, calls, results) {
187
- return `[conversation] conversation-slack-D3-g1: seeded from trunk without ${thinking} thinking block(s), ` +
188
- `${calls} unanswered tool call(s) and ${results} orphaned tool result(s)`;
189
- }
190
- it('fork inherits the template context, and a seed that leaves nothing out logs nothing', async () => {
191
- membrane.pushResponse(createMockResponse([{ type: 'text', text: 'ok' }]));
192
- const framework = await makeFramework();
193
- // Seed the trunk (primary agent) with handbook-like content.
194
- framework.getAgent('trunk').getContextManager().addMessage('user', [
195
- { type: 'text', text: 'HANDBOOK: always check the logs first.' },
196
- ]);
197
- const { seeded, lines } = await seedOf(framework);
198
- assert.ok(seeded.some((m) => JSON.stringify(m.content).includes('HANDBOOK')), 'fork should inherit trunk context');
199
- assert.deepEqual(lines, [], 'a seed with nothing left out logs no line');
200
- await framework.stop();
201
- });
202
- it("a fork's seed is a dry run, and carries none of the template's thinking", async () => {
203
- membrane.pushResponse(createMockResponse([{ type: 'text', text: 'ok' }]));
204
- const framework = await makeFramework();
205
- const trunk = framework.getAgent('trunk').getContextManager();
206
- trunk.addMessage('user', [{ type: 'text', text: 'HANDBOOK: always check the logs first.' }]);
207
- trunk.addMessage('trunk', [
208
- { type: 'thinking', thinking: 'minted under the trunk\'s prefix', signature: 'sig-trunk' },
209
- { type: 'text', text: 'Checked the logs.' },
210
- ]);
211
- trunk.addMessage('trunk', [{ type: 'redacted_thinking', data: 'opaque' }]);
212
- // Every compile on any context manager during the spawn, by instance.
213
- const proto = trunk.constructor.prototype;
214
- const original = proto.compile;
215
- const compiles = [];
216
- proto.compile = function (...args) {
217
- compiles.push({ cm: this, dry: args[2]?.dryRun === true });
218
- return original.apply(this, args);
219
- };
220
- let seed;
221
- try {
222
- seed = await seedOf(framework);
223
- }
224
- finally {
225
- proto.compile = original;
226
- }
227
- const { seeded, lines } = seed;
228
- const fork = framework.getAgent('conversation-slack-D3-g1').getContextManager();
229
- const onTrunk = compiles.filter((c) => c.cm === trunk);
230
- assert.ok(onTrunk.length >= 1, 'the seed compiled the template');
231
- assert.ok(onTrunk.every((c) => c.dry), "the template's compiles during the spawn are dry runs");
232
- assert.equal(compiles.find((c) => c.cm === fork)?.dry, true, "the new namespace's emptiness check is a dry run");
233
- const types = seeded.flatMap((m) => m.content.map((b) => b.type));
234
- assert.ok(!types.includes('thinking') && !types.includes('redacted_thinking'), `no thinking in the seed: ${types}`);
235
- const texts = seeded.map((m) => JSON.stringify(m.content));
236
- assert.ok(texts.some((t) => t.includes('HANDBOOK')) && texts.some((t) => t.includes('Checked the logs.')));
237
- assert.ok(seeded.some((m) => m.participant === 'conversation-slack-D3-g1'
238
- && JSON.stringify(m.content).includes('Checked the logs.')), "the reply keeps its text, under the fork's name");
239
- assert.ok(seeded.every((m) => m.content.length > 0), 'the thinking-only message is left out, not stored empty');
240
- assert.deepEqual(lines, [seedLine(2, 0, 0)], 'one line counts what the seed left out');
241
- await framework.stop();
242
- });
243
- it("a seed that ends on a completed tool round keeps the round, without its thinking", async () => {
244
- membrane.pushResponse(createMockResponse([{ type: 'text', text: 'ok' }]));
245
- const framework = await makeFramework();
246
- const trunk = framework.getAgent('trunk').getContextManager();
247
- trunk.addMessage('user', [{ type: 'text', text: 'check the logs' }]);
248
- trunk.addMessage('trunk', [
249
- { type: 'thinking', thinking: 'the logs first', signature: 'sig-round' },
250
- { type: 'tool_use', id: 'toolu_logs', name: 'read_logs', input: {} },
251
- ]);
252
- trunk.addMessage('user', [{ type: 'tool_result', toolUseId: 'toolu_logs', content: 'all quiet' }]);
253
- const { seeded, lines } = await seedOf(framework);
254
- const contents = seeded.map((m) => m.content);
255
- const round = contents.findIndex((c) => c.some((b) => b.type === 'tool_use'));
256
- assert.ok(round >= 0, 'the round is in the seed');
257
- assert.deepEqual(contents[round].map((b) => b.type), ['tool_use'], 'its call stays, its thinking goes');
258
- assert.equal(seeded[round].participant, 'conversation-slack-D3-g1');
259
- assert.deepEqual(contents[round + 1].map((b) => b.type), ['tool_result'], 'its result follows it');
260
- assert.deepEqual(lines, [seedLine(1, 0, 0)]);
261
- await framework.stop();
262
- });
263
- it("a seed's unanswered call gives way to a placeholder, and the seed ends on neither it nor a thinking-only row", async () => {
264
- membrane.pushResponse(createMockResponse([{ type: 'text', text: 'ok' }]));
265
- const framework = await makeFramework();
266
- const trunk = framework.getAgent('trunk').getContextManager();
267
- trunk.addMessage('user', [{ type: 'text', text: 'check the logs' }]);
268
- trunk.addMessage('trunk', [{ type: 'text', text: 'Looking.' }]);
269
- // A tool round's assistant row, stored before its results (the spawn can
270
- // land between the two when the coalescer spawns outside the event loop),
271
- // and a thinking-only row after it.
272
- trunk.addMessage('trunk', [
273
- { type: 'thinking', thinking: 'mid-round', signature: 'sig-mid' },
274
- { type: 'tool_use', id: 'toolu_pending', name: 'read_logs', input: {} },
275
- ]);
276
- trunk.addMessage('trunk', [{ type: 'thinking', thinking: 'still thinking', signature: 'sig-after' }]);
277
- const { seeded, lines } = await seedOf(framework);
278
- const types = seeded.flatMap((m) => m.content.map((b) => b.type));
279
- assert.ok(!types.includes('tool_use') && !types.includes('thinking'), `no unanswered call or thinking in the seed: ${types}`);
280
- // The seed is everything before the fork's own first message ('hi').
281
- const firstOwn = seeded.findIndex((m) => JSON.stringify(m.content).includes('"hi"'));
282
- assert.ok(firstOwn > 1, 'the incoming message follows the seed');
283
- // The thinking goes first, so the round's row holds only its unanswered
284
- // call, which the pairing pass replaces with its placeholder.
285
- const last = seeded[firstOwn - 1];
286
- assert.deepEqual(last.content.map((b) => b.type), ['text']);
287
- assert.ok(JSON.stringify(last.content).includes('[tool call omitted]'), `the seed ends on the placeholder: ${JSON.stringify(last.content)}`);
288
- assert.equal(last.participant, 'conversation-slack-D3-g1');
289
- assert.ok(JSON.stringify(seeded[firstOwn - 2].content).includes('Looking.'), 'the exchange before the round stays');
290
- assert.deepEqual(lines, [seedLine(2, 1, 0)]);
291
- await framework.stop();
292
- });
293
- it("a seed keeps a partly answered round's answered call and drops the other, drops an orphaned result and a trailing unanswered call, and keeps the text beside each", async () => {
294
- membrane.pushResponse(createMockResponse([{ type: 'text', text: 'ok' }]));
295
- const framework = await makeFramework();
296
- const trunk = framework.getAgent('trunk').getContextManager();
297
- // A result whose call isn't in the history (as where a window starts
298
- // after the call), beside the user's text.
299
- trunk.addMessage('user', [
300
- { type: 'tool_result', toolUseId: 'toolu_gone', content: 'stale' },
301
- { type: 'text', text: 'check both' },
302
- ]);
303
- // A parallel round with one of its two calls answered.
304
- trunk.addMessage('trunk', [
305
- { type: 'text', text: 'Checking both.' },
306
- { type: 'tool_use', id: 'toolu_a', name: 'read_logs', input: {} },
307
- { type: 'tool_use', id: 'toolu_b', name: 'read_config', input: {} },
308
- ]);
309
- trunk.addMessage('user', [{ type: 'tool_result', toolUseId: 'toolu_a', content: 'all quiet' }]);
310
- // The next round's row, stored before its result: thinking, text and a call.
311
- trunk.addMessage('trunk', [
312
- { type: 'thinking', thinking: 'the config next', signature: 'sig-next' },
313
- { type: 'text', text: 'And the config.' },
314
- { type: 'tool_use', id: 'toolu_c', name: 'read_config', input: {} },
315
- ]);
316
- const { seeded, lines } = await seedOf(framework);
317
- const blocks = seeded.flatMap((m) => m.content);
318
- assert.deepEqual(blocks.filter((b) => b.type === 'tool_use').map((b) => b.id), ['toolu_a'], 'the answered call stays, the unanswered ones go');
319
- assert.deepEqual(blocks.filter((b) => b.type === 'tool_result').map((b) => b.toolUseId), ['toolu_a'], 'its result stays, the orphaned one goes');
320
- const round = seeded.find((m) => m.content.some((b) => b.type === 'tool_use'));
321
- assert.deepEqual(round.content.map((b) => b.type), ['text', 'tool_use'], "the round's text stays beside its answered call");
322
- assert.ok(seeded.some((m) => JSON.stringify(m.content).includes('check both')), "the user's text stays beside the orphaned result");
323
- const trailing = seeded.find((m) => JSON.stringify(m.content).includes('And the config.'));
324
- assert.deepEqual(trailing.content.map((b) => b.type), ['text'], "the trailing row keeps its text, without its thinking or its unanswered call");
325
- assert.deepEqual(lines, [seedLine(1, 2, 1)]);
326
- await framework.stop();
327
- });
328
- /** A Responses reply as membrane stores it: `output` through membrane's own
329
- * Responses adapter and its conversion to content blocks, with the HTTP
330
- * call stubbed. */
331
- async function storedResponsesReply(output) {
332
- const completed = {
333
- type: 'response.completed',
334
- response: { id: 'resp_seed', status: 'completed', output, usage: { input_tokens: 1, output_tokens: 1 } },
335
- };
336
- const realFetch = globalThis.fetch;
337
- globalThis.fetch = (async () => new Response(`data: ${JSON.stringify(completed)}\n\n`, {
338
- status: 200,
339
- headers: { 'content-type': 'text/event-stream' },
340
- }));
341
- try {
342
- const responses = new Membrane(new OpenAIResponsesAPIAdapter({ apiKey: 'test' }), {
343
- formatter: new OpenAIResponsesFormatter(),
344
- });
345
- const response = await responses.stream({
346
- messages: [{ participant: 'user', content: [{ type: 'text', text: 'what changed?' }] }],
347
- config: { model: 'gpt-test', maxTokens: 100 },
348
- tools: [{ name: 'read_config', description: 'Read the config.', inputSchema: { type: 'object', properties: {} } }],
349
- });
350
- return response.content;
351
- }
352
- finally {
353
- globalThis.fetch = realFetch;
354
- }
355
- }
356
- it("a Responses seed replays no item paired with the reasoning it left out; opaque carriers stay whole", async () => {
357
- membrane.pushResponse(createMockResponse([{ type: 'text', text: 'ok' }]));
358
- const framework = await makeFramework();
359
- const trunk = framework.getAgent('trunk').getContextManager();
360
- trunk.addMessage('user', [{ type: 'text', text: 'what changed?' }]);
361
- // A reply holding a compaction, a reasoning item, a hosted web search, a
362
- // message and a function call, as membrane stores it.
363
- trunk.addMessage('trunk', await storedResponsesReply([
364
- { type: 'compaction', id: 'cmp_1', encrypted_content: 'earlier history' },
365
- { type: 'reasoning', id: 'rs_1', encrypted_content: 'enc', summary: [] },
366
- { type: 'web_search_call', id: 'ws_1', status: 'completed', action: { type: 'search', query: 'config' } },
367
- { type: 'message', id: 'msg_1', role: 'assistant', status: 'completed', content: [{ type: 'output_text', text: 'The config.' }] },
368
- { type: 'function_call', id: 'fc_1', call_id: 'call_1', name: 'read_config', arguments: '{}', status: 'completed' },
369
- ]));
370
- trunk.addMessage('user', [{ type: 'tool_result', toolUseId: 'call_1', content: 'ok' }]);
371
- // A reply with no reasoning item: nothing it was paired with is left out,
372
- // so it replays as it was.
373
- trunk.addMessage('trunk', await storedResponsesReply([
374
- { type: 'message', id: 'msg_2', role: 'assistant', status: 'completed', content: [{ type: 'output_text', text: 'Read it.' }] },
375
- ]));
376
- // An Anthropic reply in the same history: its thinking carries no raw item.
377
- trunk.addMessage('trunk', [
378
- { type: 'thinking', thinking: 'plain', signature: 'sig-plain' },
379
- { type: 'text', text: 'Done.' },
380
- ]);
381
- const { seeded } = await seedOf(framework);
382
- const items = new OpenAIResponsesFormatter().buildMessages(seeded.map((m) => ({ participant: m.participant, content: m.content })), { participantMode: 'simple', assistantParticipant: 'conversation-slack-D3-g1', humanParticipant: 'user', systemPrompt: 'fork' }).messages;
383
- const ids = items.map((item) => item.id).filter((id) => id !== undefined);
384
- assert.deepEqual(ids, ['cmp_1', 'ws_1', 'msg_2'], `only the opaque carriers and the unpaired reply replay by id: ${JSON.stringify(items)}`);
385
- assert.ok(!items.some((item) => item.type === 'reasoning'), 'the reasoning item is left out');
386
- assert.ok(items.some((item) => item.type === 'function_call' && item.call_id === 'call_1'), 'the call renders from its fields');
387
- assert.ok(items.some((item) => item.type === 'message' && JSON.stringify(item.content).includes('The config.')), 'the text renders from its fields');
388
- const plain = seeded.find((m) => JSON.stringify(m.content).includes('Done.'));
389
- assert.deepEqual(plain.content.map((b) => b.type), ['text'], "an Anthropic reply loses only its thinking");
390
- await framework.stop();
391
- });
392
- it("a fork whose namespace already holds history isn't seeded again", async () => {
393
- membrane.pushResponse(createMockResponse([{ type: 'text', text: 'noted' }]));
394
- const fw1 = await makeFramework({}, 'reseed.chronicle');
395
- fw1.getAgent('trunk').getContextManager().addMessage('user', [
396
- { type: 'text', text: 'HANDBOOK-V1: always check the logs first.' },
397
- ]);
398
- fw1.pushEvent(incomingEvent({ channelId: 'slack:D8', text: 'case one', channelType: 'im' }));
399
- await fw1.runUntilIdle();
400
- assert.ok(fw1.getAgent('conversation-slack-D8-g1'), 'first engagement spawns g1');
401
- await fw1.stop();
402
- // Restart with the generation counters lost, so the next engagement
403
- // proposes g1 again, and its namespace already holds g1's history.
404
- membrane.pushResponse(createMockResponse([{ type: 'text', text: 'again' }]));
405
- const fw2 = await makeFramework({}, 'reseed.chronicle');
406
- fw2.getConversationRouter().generations.clear();
407
- fw2.pushEvent(incomingEvent({ channelId: 'slack:D8', text: 'case two', channelType: 'im' }));
408
- await fw2.runUntilIdle();
409
- const g1 = fw2.getAgent('conversation-slack-D8-g1');
410
- assert.ok(g1, 'the lost counters propose g1 again');
411
- const contents = g1.getContextManager().getAllMessages().map((m) => JSON.stringify(m.content));
412
- assert.equal(contents.filter((c) => c.includes('HANDBOOK-V1')).length, 1, 'no second template copy on its history');
413
- assert.ok(contents.some((c) => c.includes('case one')), 'its own history stays');
414
- await fw2.stop();
415
- });
416
- // Exercise the delivery boundary without scheduling inference. The same
417
- // handler receives ordinary channel traffic and coalesced fixed-audience notices.
418
- async function deliver(framework, channelId, text, deliverTo) {
419
- const internals = framework;
420
- return internals.handleMcplChannelIncoming({
421
- ...incomingEvent({ channelId, text, mentioned: true }),
422
- triggerInference: false,
423
- ...(deliverTo ? { deliverTo } : {}),
424
- });
425
- }
426
- it('successful ambient delivery refreshes the bound fork idle clock', async () => {
427
- const framework = await makeFramework();
428
- try {
429
- await deliver(framework, 'slack:C1', 'first');
430
- const router = framework.getConversationRouter();
431
- const binding = router.getBinding('slack:C1');
432
- binding.lastActivity = 1;
433
- const before = Date.now();
434
- framework.pushEvent({
435
- ...incomingEvent({ channelId: 'slack:C1', text: 'ambient detail' }),
436
- triggerInference: false,
437
- });
438
- await framework.runUntilIdle();
439
- assert.ok(binding.lastActivity >= before, 'successful delivery records activity');
440
- assert.equal(membrane.calls.length, 0, 'ambient delivery needs no inference');
441
- assert.deepEqual(router.expired(before), []);
442
- }
443
- finally {
444
- await framework.stop();
445
- }
446
- });
447
- it('failed delivery leaves the bound fork idle clock unchanged', async () => {
448
- const framework = await makeFramework();
449
- try {
450
- await deliver(framework, 'slack:C1', 'first');
451
- const router = framework.getConversationRouter();
452
- const binding = router.getBinding('slack:C1');
453
- binding.lastActivity = 1;
454
- const context = framework.getAgent(binding.agentName).getContextManager();
455
- const addMessage = context.addMessage;
456
- context.addMessage = () => { throw new Error('injected context write failure'); };
457
- try {
458
- await assert.rejects(deliver(framework, 'slack:C1', 'lost'), /injected context write failure/);
459
- assert.equal(binding.lastActivity, 1, 'a routing decision is not delivered activity');
460
- }
461
- finally {
462
- context.addMessage = addMessage;
463
- }
464
- }
465
- finally {
466
- await framework.stop();
467
- }
468
- });
469
- it('fixed-audience coalesced delivery refreshes the current fork idle clock', async () => {
470
- const framework = await makeFramework();
471
- try {
472
- await deliver(framework, 'slack:C1', 'first');
473
- const router = framework.getConversationRouter();
474
- const binding = router.getBinding('slack:C1');
475
- binding.lastActivity = 1;
476
- const before = Date.now();
477
- await deliver(framework, 'slack:C1', 'updated detail', binding.agentName);
478
- assert.ok(binding.lastActivity >= before, 'delivery bypassing fresh routing still records activity');
479
- const { messages } = await framework.getAgent(binding.agentName).getContextManager().compile();
480
- assert.ok(JSON.stringify(messages).includes('updated detail'));
481
- }
482
- finally {
483
- await framework.stop();
484
- }
485
- });
486
- it('delivery to an older fork does not refresh a newer binding on the same channel', async () => {
487
- const framework = await makeFramework();
488
- try {
489
- await deliver(framework, 'slack:C1', 'first');
490
- const router = framework.getConversationRouter();
491
- const oldName = router.getBinding('slack:C1').agentName;
492
- router.unbind('slack:C1');
493
- await deliver(framework, 'slack:C1', 'new engagement');
494
- const binding = router.getBinding('slack:C1');
495
- binding.lastActivity = 1;
496
- await deliver(framework, 'slack:C1', 'old engagement correction', oldName);
497
- assert.equal(binding.lastActivity, 1, 'the correction belongs to the old engagement');
498
- const { messages } = await framework.getAgent(oldName).getContextManager().compile();
499
- assert.ok(JSON.stringify(messages).includes('old engagement correction'));
500
- }
501
- finally {
502
- await framework.stop();
503
- }
504
- });
505
- it('idle TTL runs a closure turn, unbinds, disposes the fork, and the next message spawns g2', async () => {
506
- const IDLE_TTL_MS = 60_000;
507
- membrane.pushResponse(createMockResponse([{ type: 'text', text: 'hello!' }]));
508
- const framework = await makeFramework({ idleTtlMs: IDLE_TTL_MS });
509
- framework.pushEvent(incomingEvent({ channelId: 'slack:D3', text: 'hi', channelType: 'im' }));
510
- await framework.runUntilIdle();
511
- const router = framework.getConversationRouter();
512
- assert.ok(router.getBinding('slack:D3'), 'spawn should leave a live binding');
513
- const g1 = framework.getAgent('conversation-slack-D3-g1');
514
- assert.ok(g1, 'g1 fork should exist after spawn');
515
- // Force expiry deterministically and provide the closure-turn response.
516
- forceExpiry(framework, 'slack:D3', IDLE_TTL_MS);
517
- membrane.pushResponse(createMockResponse([{ type: 'text', text: 'Final report posted.' }]));
518
- // Nudge the loop so the sweep runs.
519
- framework.pushEvent({ type: 'external-message', source: 'test', content: 'tick', metadata: {} });
520
- await framework.runUntilIdle();
521
- assert.equal(router.getBinding('slack:D3'), undefined, 'binding should be gone after TTL');
522
- const { messages } = await g1.getContextManager().compile();
523
- assert.ok(messages.some((m) => JSON.stringify(m.content).includes('engagement is closing')), 'closure prompt should be in the fork context');
524
- assert.equal(framework.getAgent('conversation-slack-D3-g1'), null, 'closed fork should be disposed once its closure turn finished');
525
- const internals = framework;
526
- assert.equal(internals.turnRouting.has('conversation-slack-D3-g1'), false, 'the closed fork leaves no routing');
527
- assert.equal(internals.proseSpeechChains.has('conversation-slack-D3-g1'), false, 'the closed fork leaves no speech chain');
528
- // Next DM spawns a fresh generation.
529
- membrane.pushResponse(createMockResponse([{ type: 'text', text: 'hi again' }]));
530
- framework.pushEvent(incomingEvent({ channelId: 'slack:D3', text: 'back again', channelType: 'im' }));
531
- await framework.runUntilIdle();
532
- assert.ok(framework.getAgent('conversation-slack-D3-g2'), 'rebind spawns generation 2');
533
- await framework.stop();
534
- });
535
- it('restart does not reuse generation names or re-seed an existing namespace', async () => {
536
- membrane.pushResponse(createMockResponse([{ type: 'text', text: 'noted' }]));
537
- const fw1 = await makeFramework({}, 'restart.chronicle');
538
- fw1.getAgent('trunk').getContextManager().addMessage('user', [
539
- { type: 'text', text: 'HANDBOOK-V1: always check the logs first.' },
540
- ]);
541
- fw1.pushEvent(incomingEvent({ channelId: 'slack:D9', text: 'case one', channelType: 'im' }));
542
- await fw1.runUntilIdle();
543
- assert.ok(fw1.getAgent('conversation-slack-D9-g1'), 'first engagement spawns g1');
544
- await fw1.stop();
545
- // Restart: same store, fresh framework. The generation counter must come
546
- // back from Chronicle so the next engagement is g2 in a fresh namespace.
547
- membrane.pushResponse(createMockResponse([{ type: 'text', text: 'fresh' }]));
548
- const fw2 = await makeFramework({}, 'restart.chronicle');
549
- fw2.pushEvent(incomingEvent({ channelId: 'slack:D9', text: 'case two', channelType: 'im' }));
550
- await fw2.runUntilIdle();
551
- assert.equal(fw2.getAgent('conversation-slack-D9-g1'), null, 'g1 must not be resurrected');
552
- const g2 = fw2.getAgent('conversation-slack-D9-g2');
553
- assert.ok(g2, 'restart spawns the next generation, not generation 1 again');
554
- const { messages } = await g2.getContextManager().compile();
555
- const handbookCopies = messages.filter((m) => JSON.stringify(m.content).includes('HANDBOOK-V1')).length;
556
- assert.equal(handbookCopies, 1, 'fresh namespace is seeded with exactly one template copy');
557
- assert.ok(!messages.some((m) => JSON.stringify(m.content).includes('case one')), 'a new generation must not inherit the previous engagement history');
558
- await fw2.stop();
559
- });
560
- it('forks cannot open channels or close foreign ones', async () => {
561
- membrane.pushResponse(createMockResponse([{ type: 'text', text: 'hi' }]));
562
- const framework = await makeFramework();
563
- framework.pushEvent(incomingEvent({ channelId: 'slack:C7', text: 'bot, help', mentioned: true }));
564
- await framework.runUntilIdle();
565
- const forkName = 'conversation-slack-C7-g1';
566
- assert.ok(framework.getAgent(forkName), 'fork should exist');
567
- const failures = [];
568
- framework.onTrace((e) => {
569
- if (e.type === 'tool:failed') {
570
- failures.push({ tool: e.tool, error: e.error });
571
- }
572
- });
573
- const fw = framework;
574
- fw.dispatchChannelToolCall(forkName, { id: 't1', name: 'channel_open', input: { channelId: 'slack:C8' } });
575
- fw.dispatchChannelToolCall(forkName, { id: 't2', name: 'channel_close', input: { channelId: 'slack:C8' } });
576
- assert.equal(failures.length, 2, 'both foreign channel operations should be rejected');
577
- assert.ok(failures[0].error.includes('cannot open channels'), 'channel_open is rejected outright');
578
- assert.ok(failures[1].error.includes('closing slack:C8 is not allowed'), 'foreign channel_close is rejected');
579
- await framework.stop();
580
- });
581
- it('fork channel_publish: omitted channelId defaults to home; foreign publish is rejected', async () => {
582
- membrane.pushResponse(createMockResponse([{ type: 'text', text: 'hi' }]));
583
- const framework = await makeFramework();
584
- framework.pushEvent(incomingEvent({ channelId: 'slack:C7', text: 'bot, help', mentioned: true }));
585
- await framework.runUntilIdle();
586
- const forkName = 'conversation-slack-C7-g1';
587
- assert.ok(framework.getAgent(forkName), 'fork should exist');
588
- // tool:started is emitted AFTER the fence with the (possibly rewritten)
589
- // input, so home-defaulting is observable there; a fence rejection emits
590
- // tool:failed and never reaches tool:started.
591
- const started = [];
592
- const failures = [];
593
- framework.onTrace((e) => {
594
- if (e.type === 'tool:started')
595
- started.push(e);
596
- if (e.type === 'tool:failed')
597
- failures.push(e);
598
- });
599
- const fw = framework;
600
- // This harness runs no MCPL servers, so the framework never builds a real
601
- // ChannelRegistry (the public dispatch path guards on it before routing
602
- // channel_* tools). Stub the downstream boundary — the unit under test is
603
- // the fence ABOVE it, and a home-defaulted publish must get past the fence
604
- // to be observable at tool:started.
605
- fw.channelRegistry = { handleChannelToolCall: async () => ({ success: true }), stopAll: () => { } };
606
- // (a) omitted channelId → rewritten to the home channel, passes the fence
607
- fw.dispatchChannelToolCall(forkName, { id: 'p1', name: 'channel_publish', input: { content: 'hello home' } });
608
- const homePublish = started.find((t) => t.tool === 'channel_publish');
609
- assert.ok(homePublish, 'home-defaulted publish should pass the fence and reach tool:started');
610
- assert.equal(homePublish.input?.channelId, 'slack:C7', 'omitted channelId is rewritten to the home channel');
611
- assert.ok(!failures.some((f) => f.callId === 'p1'), 'home-defaulted publish must not be rejected by the fence');
612
- // (b) foreign channelId → rejected by the fence, never starts
613
- fw.dispatchChannelToolCall(forkName, { id: 'p2', name: 'channel_publish', input: { channelId: 'slack:C8', content: 'sneaky' } });
614
- const rejection = failures.find((f) => f.callId === 'p2');
615
- assert.ok(rejection, 'foreign publish should be rejected');
616
- assert.ok(rejection.error.includes('publishing to slack:C8 is not allowed'), 'rejection names the foreign channel');
617
- assert.equal(started.filter((t) => t.tool === 'channel_publish').length, 1, 'foreign publish never reaches tool:started');
618
- await framework.stop();
619
- });
620
- });
621
- //# sourceMappingURL=conversation-routing.test.js.map