@animalabs/agent-framework 0.22.2 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (997) hide show
  1. package/README.md +108 -4
  2. package/dist/src/agent.d.ts +108 -17
  3. package/dist/src/agent.d.ts.map +1 -1
  4. package/dist/src/agent.js +207 -67
  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/index.d.ts +1 -1
  22. package/dist/src/code-execution/index.d.ts.map +1 -1
  23. package/dist/src/code-execution/index.js.map +1 -1
  24. package/dist/src/code-execution/py-runner.d.ts +50 -7
  25. package/dist/src/code-execution/py-runner.d.ts.map +1 -1
  26. package/dist/src/code-execution/py-runner.js +258 -90
  27. package/dist/src/code-execution/py-runner.js.map +1 -1
  28. package/dist/src/code-execution/runtime-py.d.ts +3 -2
  29. package/dist/src/code-execution/runtime-py.d.ts.map +1 -1
  30. package/dist/src/code-execution/runtime-py.js +94 -8
  31. package/dist/src/code-execution/runtime-py.js.map +1 -1
  32. package/dist/src/code-execution/tool-definition.d.ts +17 -1
  33. package/dist/src/code-execution/tool-definition.d.ts.map +1 -1
  34. package/dist/src/code-execution/tool-definition.js +72 -6
  35. package/dist/src/code-execution/tool-definition.js.map +1 -1
  36. package/dist/src/config-checks.d.ts +28 -0
  37. package/dist/src/config-checks.d.ts.map +1 -0
  38. package/dist/src/config-checks.js +56 -0
  39. package/dist/src/config-checks.js.map +1 -0
  40. package/dist/src/deadline-timer.d.ts +21 -0
  41. package/dist/src/deadline-timer.d.ts.map +1 -0
  42. package/dist/src/deadline-timer.js +43 -0
  43. package/dist/src/deadline-timer.js.map +1 -0
  44. package/dist/src/error-message.d.ts +30 -0
  45. package/dist/src/error-message.d.ts.map +1 -0
  46. package/dist/src/error-message.js +50 -0
  47. package/dist/src/error-message.js.map +1 -0
  48. package/dist/src/framework.d.ts +1529 -165
  49. package/dist/src/framework.d.ts.map +1 -1
  50. package/dist/src/framework.js +8264 -1939
  51. package/dist/src/framework.js.map +1 -1
  52. package/dist/src/gate/event-gate.d.ts +8 -0
  53. package/dist/src/gate/event-gate.d.ts.map +1 -1
  54. package/dist/src/gate/event-gate.js +36 -5
  55. package/dist/src/gate/event-gate.js.map +1 -1
  56. package/dist/src/held-writes.d.ts +16 -0
  57. package/dist/src/held-writes.d.ts.map +1 -0
  58. package/dist/src/held-writes.js +56 -0
  59. package/dist/src/held-writes.js.map +1 -0
  60. package/dist/src/index.d.ts +10 -4
  61. package/dist/src/index.d.ts.map +1 -1
  62. package/dist/src/index.js +11 -5
  63. package/dist/src/index.js.map +1 -1
  64. package/dist/src/mcpl/capability-grant.d.ts +4 -0
  65. package/dist/src/mcpl/capability-grant.d.ts.map +1 -1
  66. package/dist/src/mcpl/capability-grant.js +1 -1
  67. package/dist/src/mcpl/capability-grant.js.map +1 -1
  68. package/dist/src/mcpl/channel-registry.d.ts +233 -18
  69. package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
  70. package/dist/src/mcpl/channel-registry.js +975 -386
  71. package/dist/src/mcpl/channel-registry.js.map +1 -1
  72. package/dist/src/mcpl/checkpoint-manager.d.ts +21 -1
  73. package/dist/src/mcpl/checkpoint-manager.d.ts.map +1 -1
  74. package/dist/src/mcpl/checkpoint-manager.js +91 -30
  75. package/dist/src/mcpl/checkpoint-manager.js.map +1 -1
  76. package/dist/src/mcpl/conversation-router.d.ts +19 -3
  77. package/dist/src/mcpl/conversation-router.d.ts.map +1 -1
  78. package/dist/src/mcpl/conversation-router.js +23 -8
  79. package/dist/src/mcpl/conversation-router.js.map +1 -1
  80. package/dist/src/mcpl/convert-block.d.ts +20 -0
  81. package/dist/src/mcpl/convert-block.d.ts.map +1 -0
  82. package/dist/src/mcpl/convert-block.js +88 -0
  83. package/dist/src/mcpl/convert-block.js.map +1 -0
  84. package/dist/src/mcpl/errors.d.ts +13 -0
  85. package/dist/src/mcpl/errors.d.ts.map +1 -1
  86. package/dist/src/mcpl/errors.js +28 -0
  87. package/dist/src/mcpl/errors.js.map +1 -1
  88. package/dist/src/mcpl/hook-orchestrator.d.ts +23 -0
  89. package/dist/src/mcpl/hook-orchestrator.d.ts.map +1 -1
  90. package/dist/src/mcpl/hook-orchestrator.js +83 -72
  91. package/dist/src/mcpl/hook-orchestrator.js.map +1 -1
  92. package/dist/src/mcpl/inbound-source.d.ts +114 -0
  93. package/dist/src/mcpl/inbound-source.d.ts.map +1 -0
  94. package/dist/src/mcpl/inbound-source.js +83 -0
  95. package/dist/src/mcpl/inbound-source.js.map +1 -0
  96. package/dist/src/mcpl/index.d.ts +7 -1
  97. package/dist/src/mcpl/index.d.ts.map +1 -1
  98. package/dist/src/mcpl/index.js +5 -1
  99. package/dist/src/mcpl/index.js.map +1 -1
  100. package/dist/src/mcpl/inference-router.d.ts +19 -13
  101. package/dist/src/mcpl/inference-router.d.ts.map +1 -1
  102. package/dist/src/mcpl/inference-router.js +155 -87
  103. package/dist/src/mcpl/inference-router.js.map +1 -1
  104. package/dist/src/mcpl/log-value.d.ts +7 -0
  105. package/dist/src/mcpl/log-value.d.ts.map +1 -1
  106. package/dist/src/mcpl/log-value.js +9 -0
  107. package/dist/src/mcpl/log-value.js.map +1 -1
  108. package/dist/src/mcpl/modern-connection.d.ts +227 -0
  109. package/dist/src/mcpl/modern-connection.d.ts.map +1 -0
  110. package/dist/src/mcpl/modern-connection.js +1088 -0
  111. package/dist/src/mcpl/modern-connection.js.map +1 -0
  112. package/dist/src/mcpl/prefix-rule.d.ts +18 -0
  113. package/dist/src/mcpl/prefix-rule.d.ts.map +1 -0
  114. package/dist/src/mcpl/prefix-rule.js +25 -0
  115. package/dist/src/mcpl/prefix-rule.js.map +1 -0
  116. package/dist/src/mcpl/protocol-family.d.ts +179 -0
  117. package/dist/src/mcpl/protocol-family.d.ts.map +1 -0
  118. package/dist/src/mcpl/protocol-family.js +697 -0
  119. package/dist/src/mcpl/protocol-family.js.map +1 -0
  120. package/dist/src/mcpl/push-coalescer.d.ts +58 -17
  121. package/dist/src/mcpl/push-coalescer.d.ts.map +1 -1
  122. package/dist/src/mcpl/push-coalescer.js +93 -32
  123. package/dist/src/mcpl/push-coalescer.js.map +1 -1
  124. package/dist/src/mcpl/push-handler.d.ts +16 -9
  125. package/dist/src/mcpl/push-handler.d.ts.map +1 -1
  126. package/dist/src/mcpl/push-handler.js +18 -83
  127. package/dist/src/mcpl/push-handler.js.map +1 -1
  128. package/dist/src/mcpl/reference-fetcher.d.ts +76 -13
  129. package/dist/src/mcpl/reference-fetcher.d.ts.map +1 -1
  130. package/dist/src/mcpl/reference-fetcher.js +275 -66
  131. package/dist/src/mcpl/reference-fetcher.js.map +1 -1
  132. package/dist/src/mcpl/references.d.ts +98 -18
  133. package/dist/src/mcpl/references.d.ts.map +1 -1
  134. package/dist/src/mcpl/references.js +170 -32
  135. package/dist/src/mcpl/references.js.map +1 -1
  136. package/dist/src/mcpl/server-connection.d.ts +406 -31
  137. package/dist/src/mcpl/server-connection.d.ts.map +1 -1
  138. package/dist/src/mcpl/server-connection.js +1331 -272
  139. package/dist/src/mcpl/server-connection.js.map +1 -1
  140. package/dist/src/mcpl/server-registry.d.ts +35 -6
  141. package/dist/src/mcpl/server-registry.d.ts.map +1 -1
  142. package/dist/src/mcpl/server-registry.js +63 -13
  143. package/dist/src/mcpl/server-registry.js.map +1 -1
  144. package/dist/src/mcpl/skip-reply-wake.d.ts +36 -0
  145. package/dist/src/mcpl/skip-reply-wake.d.ts.map +1 -0
  146. package/dist/src/mcpl/skip-reply-wake.js +55 -0
  147. package/dist/src/mcpl/skip-reply-wake.js.map +1 -0
  148. package/dist/src/mcpl/tool-result-normalize.d.ts +54 -0
  149. package/dist/src/mcpl/tool-result-normalize.d.ts.map +1 -0
  150. package/dist/src/mcpl/tool-result-normalize.js +232 -0
  151. package/dist/src/mcpl/tool-result-normalize.js.map +1 -0
  152. package/dist/src/mcpl/transport.d.ts +104 -12
  153. package/dist/src/mcpl/transport.d.ts.map +1 -1
  154. package/dist/src/mcpl/transport.js +315 -85
  155. package/dist/src/mcpl/transport.js.map +1 -1
  156. package/dist/src/mcpl/types.d.ts +76 -19
  157. package/dist/src/mcpl/types.d.ts.map +1 -1
  158. package/dist/src/mcpl/types.js.map +1 -1
  159. package/dist/src/mcpl/visible-content.d.ts +16 -0
  160. package/dist/src/mcpl/visible-content.d.ts.map +1 -1
  161. package/dist/src/mcpl/visible-content.js +26 -0
  162. package/dist/src/mcpl/visible-content.js.map +1 -1
  163. package/dist/src/module-registry.d.ts +34 -6
  164. package/dist/src/module-registry.d.ts.map +1 -1
  165. package/dist/src/module-registry.js +119 -31
  166. package/dist/src/module-registry.js.map +1 -1
  167. package/dist/src/modules/api/index.d.ts +1 -1
  168. package/dist/src/modules/api/index.d.ts.map +1 -1
  169. package/dist/src/modules/api/index.js +3 -2
  170. package/dist/src/modules/api/index.js.map +1 -1
  171. package/dist/src/modules/discord/discord-js-client.d.ts +43 -2
  172. package/dist/src/modules/discord/discord-js-client.d.ts.map +1 -1
  173. package/dist/src/modules/discord/discord-js-client.js +286 -67
  174. package/dist/src/modules/discord/discord-js-client.js.map +1 -1
  175. package/dist/src/modules/discord/index.d.ts +53 -5
  176. package/dist/src/modules/discord/index.d.ts.map +1 -1
  177. package/dist/src/modules/discord/index.js +712 -186
  178. package/dist/src/modules/discord/index.js.map +1 -1
  179. package/dist/src/modules/discord/refusal.d.ts +14 -0
  180. package/dist/src/modules/discord/refusal.d.ts.map +1 -0
  181. package/dist/src/modules/discord/refusal.js +14 -0
  182. package/dist/src/modules/discord/refusal.js.map +1 -0
  183. package/dist/src/modules/discord/types.d.ts +27 -4
  184. package/dist/src/modules/discord/types.d.ts.map +1 -1
  185. package/dist/src/modules/health/index.d.ts.map +1 -1
  186. package/dist/src/modules/health/index.js +8 -3
  187. package/dist/src/modules/health/index.js.map +1 -1
  188. package/dist/src/modules/history/index.d.ts +3 -1
  189. package/dist/src/modules/history/index.d.ts.map +1 -1
  190. package/dist/src/modules/history/index.js +359 -127
  191. package/dist/src/modules/history/index.js.map +1 -1
  192. package/dist/src/modules/history/semantic.d.ts +28 -1
  193. package/dist/src/modules/history/semantic.d.ts.map +1 -1
  194. package/dist/src/modules/history/semantic.js +177 -32
  195. package/dist/src/modules/history/semantic.js.map +1 -1
  196. package/dist/src/modules/index.d.ts +1 -1
  197. package/dist/src/modules/index.d.ts.map +1 -1
  198. package/dist/src/modules/index.js +1 -1
  199. package/dist/src/modules/index.js.map +1 -1
  200. package/dist/src/modules/unknown-tool.d.ts +10 -0
  201. package/dist/src/modules/unknown-tool.d.ts.map +1 -0
  202. package/dist/src/modules/unknown-tool.js +17 -0
  203. package/dist/src/modules/unknown-tool.js.map +1 -0
  204. package/dist/src/modules/workspace/disk-agreement.d.ts +57 -4
  205. package/dist/src/modules/workspace/disk-agreement.d.ts.map +1 -1
  206. package/dist/src/modules/workspace/disk-agreement.js +75 -7
  207. package/dist/src/modules/workspace/disk-agreement.js.map +1 -1
  208. package/dist/src/modules/workspace/effects.d.ts +66 -7
  209. package/dist/src/modules/workspace/effects.d.ts.map +1 -1
  210. package/dist/src/modules/workspace/effects.js +303 -46
  211. package/dist/src/modules/workspace/effects.js.map +1 -1
  212. package/dist/src/modules/workspace/index.d.ts +313 -45
  213. package/dist/src/modules/workspace/index.d.ts.map +1 -1
  214. package/dist/src/modules/workspace/index.js +1404 -304
  215. package/dist/src/modules/workspace/index.js.map +1 -1
  216. package/dist/src/modules/workspace/observe.d.ts +315 -16
  217. package/dist/src/modules/workspace/observe.d.ts.map +1 -1
  218. package/dist/src/modules/workspace/observe.js +727 -37
  219. package/dist/src/modules/workspace/observe.js.map +1 -1
  220. package/dist/src/modules/workspace/reconcile.d.ts +58 -7
  221. package/dist/src/modules/workspace/reconcile.d.ts.map +1 -1
  222. package/dist/src/modules/workspace/reconcile.js +521 -56
  223. package/dist/src/modules/workspace/reconcile.js.map +1 -1
  224. package/dist/src/modules/workspace/types.d.ts +28 -5
  225. package/dist/src/modules/workspace/types.d.ts.map +1 -1
  226. package/dist/src/modules/workspace/types.js.map +1 -1
  227. package/dist/src/modules/workspace/watcher.d.ts +49 -2
  228. package/dist/src/modules/workspace/watcher.d.ts.map +1 -1
  229. package/dist/src/modules/workspace/watcher.js +158 -29
  230. package/dist/src/modules/workspace/watcher.js.map +1 -1
  231. package/dist/src/prose-drafts.d.ts +240 -0
  232. package/dist/src/prose-drafts.d.ts.map +1 -0
  233. package/dist/src/prose-drafts.js +362 -0
  234. package/dist/src/prose-drafts.js.map +1 -0
  235. package/dist/src/prose-segments.d.ts +21 -2
  236. package/dist/src/prose-segments.d.ts.map +1 -1
  237. package/dist/src/prose-segments.js +46 -9
  238. package/dist/src/prose-segments.js.map +1 -1
  239. package/dist/src/recovery/offline-branch.d.ts +1 -0
  240. package/dist/src/recovery/offline-branch.d.ts.map +1 -1
  241. package/dist/src/recovery/offline-branch.js +3 -1
  242. package/dist/src/recovery/offline-branch.js.map +1 -1
  243. package/dist/src/safe-slice.d.ts +5 -1
  244. package/dist/src/safe-slice.d.ts.map +1 -1
  245. package/dist/src/safe-slice.js +9 -1
  246. package/dist/src/safe-slice.js.map +1 -1
  247. package/dist/src/silent-heartbeat.d.ts +112 -39
  248. package/dist/src/silent-heartbeat.d.ts.map +1 -1
  249. package/dist/src/silent-heartbeat.js +100 -29
  250. package/dist/src/silent-heartbeat.js.map +1 -1
  251. package/dist/src/tool-args.d.ts +40 -0
  252. package/dist/src/tool-args.d.ts.map +1 -0
  253. package/dist/src/tool-args.js +207 -0
  254. package/dist/src/tool-args.js.map +1 -0
  255. package/dist/src/tool-image-ledger.d.ts +87 -19
  256. package/dist/src/tool-image-ledger.d.ts.map +1 -1
  257. package/dist/src/tool-image-ledger.js +135 -32
  258. package/dist/src/tool-image-ledger.js.map +1 -1
  259. package/dist/src/tool-presentation.d.ts +9 -0
  260. package/dist/src/tool-presentation.d.ts.map +1 -1
  261. package/dist/src/tool-presentation.js +266 -62
  262. package/dist/src/tool-presentation.js.map +1 -1
  263. package/dist/src/tool-result-guard.d.ts.map +1 -1
  264. package/dist/src/tool-result-guard.js +7 -10
  265. package/dist/src/tool-result-guard.js.map +1 -1
  266. package/dist/src/tool-result-history.d.ts +32 -3
  267. package/dist/src/tool-result-history.d.ts.map +1 -1
  268. package/dist/src/tool-result-history.js +106 -19
  269. package/dist/src/tool-result-history.js.map +1 -1
  270. package/dist/src/tune-out/coordinator.d.ts +25 -1
  271. package/dist/src/tune-out/coordinator.d.ts.map +1 -1
  272. package/dist/src/tune-out/coordinator.js +260 -65
  273. package/dist/src/tune-out/coordinator.js.map +1 -1
  274. package/dist/src/types/agent.d.ts +44 -22
  275. package/dist/src/types/agent.d.ts.map +1 -1
  276. package/dist/src/types/events.d.ts +25 -0
  277. package/dist/src/types/events.d.ts.map +1 -1
  278. package/dist/src/types/framework.d.ts +38 -7
  279. package/dist/src/types/framework.d.ts.map +1 -1
  280. package/dist/src/types/inference-log.d.ts +1 -1
  281. package/dist/src/types/inference-log.d.ts.map +1 -1
  282. package/dist/src/types/module.d.ts +77 -14
  283. package/dist/src/types/module.d.ts.map +1 -1
  284. package/dist/src/types/trace.d.ts +97 -8
  285. package/dist/src/types/trace.d.ts.map +1 -1
  286. package/dist/src/usage/usage-tracker.d.ts +5 -0
  287. package/dist/src/usage/usage-tracker.d.ts.map +1 -1
  288. package/dist/src/usage/usage-tracker.js +35 -8
  289. package/dist/src/usage/usage-tracker.js.map +1 -1
  290. package/package.json +5 -4
  291. package/src/agent.ts +257 -72
  292. package/src/api/mcp-server-core.ts +1 -1
  293. package/src/api/server.ts +4 -1
  294. package/src/api/types.ts +1 -1
  295. package/src/branch-names.ts +19 -0
  296. package/src/closest-names.ts +94 -0
  297. package/src/code-execution/index.ts +1 -0
  298. package/src/code-execution/py-runner.ts +304 -93
  299. package/src/code-execution/runtime-py.ts +94 -8
  300. package/src/code-execution/tool-definition.ts +85 -7
  301. package/src/config-checks.ts +50 -0
  302. package/src/deadline-timer.ts +44 -0
  303. package/src/error-message.ts +48 -0
  304. package/src/framework.ts +8625 -1984
  305. package/src/gate/event-gate.ts +38 -5
  306. package/src/held-writes.ts +59 -0
  307. package/src/index.ts +29 -5
  308. package/src/mcpl/capability-grant.ts +1 -1
  309. package/src/mcpl/channel-registry.ts +1095 -411
  310. package/src/mcpl/checkpoint-manager.ts +104 -29
  311. package/src/mcpl/conversation-router.ts +28 -8
  312. package/src/mcpl/convert-block.ts +105 -0
  313. package/src/mcpl/errors.ts +28 -0
  314. package/src/mcpl/hook-orchestrator.ts +84 -77
  315. package/src/mcpl/inbound-source.ts +156 -0
  316. package/src/mcpl/index.ts +23 -1
  317. package/src/mcpl/inference-router.ts +179 -103
  318. package/src/mcpl/log-value.ts +10 -0
  319. package/src/mcpl/modern-connection.ts +1182 -0
  320. package/src/mcpl/prefix-rule.ts +32 -0
  321. package/src/mcpl/protocol-family.ts +691 -0
  322. package/src/mcpl/push-coalescer.ts +110 -36
  323. package/src/mcpl/push-handler.ts +20 -90
  324. package/src/mcpl/reference-fetcher.ts +318 -67
  325. package/src/mcpl/references.ts +183 -34
  326. package/src/mcpl/server-connection.ts +1404 -280
  327. package/src/mcpl/server-registry.ts +63 -14
  328. package/src/mcpl/skip-reply-wake.ts +73 -0
  329. package/src/mcpl/tool-result-normalize.ts +294 -0
  330. package/src/mcpl/transport.ts +320 -76
  331. package/src/mcpl/types.ts +77 -19
  332. package/src/mcpl/visible-content.ts +28 -0
  333. package/src/module-registry.ts +126 -36
  334. package/src/modules/api/index.ts +3 -2
  335. package/src/modules/discord/discord-js-client.ts +306 -74
  336. package/src/modules/discord/index.ts +737 -201
  337. package/src/modules/discord/refusal.ts +13 -0
  338. package/src/modules/discord/types.ts +27 -6
  339. package/src/modules/health/index.ts +8 -3
  340. package/src/modules/history/index.ts +410 -120
  341. package/src/modules/history/semantic.ts +189 -32
  342. package/src/modules/index.ts +1 -1
  343. package/src/modules/unknown-tool.ts +16 -0
  344. package/src/modules/workspace/disk-agreement.ts +97 -8
  345. package/src/modules/workspace/effects.ts +291 -36
  346. package/src/modules/workspace/index.ts +1469 -321
  347. package/src/modules/workspace/observe.ts +784 -41
  348. package/src/modules/workspace/reconcile.ts +619 -64
  349. package/src/modules/workspace/types.ts +28 -5
  350. package/src/modules/workspace/watcher.ts +154 -30
  351. package/src/prose-drafts.ts +481 -0
  352. package/src/prose-segments.ts +51 -8
  353. package/src/recovery/offline-branch.ts +4 -1
  354. package/src/safe-slice.ts +9 -1
  355. package/src/silent-heartbeat.ts +184 -59
  356. package/src/tool-args.ts +213 -0
  357. package/src/tool-image-ledger.ts +153 -34
  358. package/src/tool-presentation.ts +233 -42
  359. package/src/tool-result-guard.ts +7 -8
  360. package/src/tool-result-history.ts +124 -20
  361. package/src/tune-out/coordinator.ts +259 -65
  362. package/src/types/agent.ts +44 -24
  363. package/src/types/events.ts +25 -0
  364. package/src/types/framework.ts +38 -7
  365. package/src/types/inference-log.ts +1 -1
  366. package/src/types/module.ts +79 -14
  367. package/src/types/trace.ts +103 -8
  368. package/src/usage/usage-tracker.ts +32 -8
  369. package/dist/test/activation-request-sanitize.test.d.ts +0 -2
  370. package/dist/test/activation-request-sanitize.test.d.ts.map +0 -1
  371. package/dist/test/activation-request-sanitize.test.js +0 -89
  372. package/dist/test/activation-request-sanitize.test.js.map +0 -1
  373. package/dist/test/agent-cache-ttl.test.d.ts +0 -2
  374. package/dist/test/agent-cache-ttl.test.d.ts.map +0 -1
  375. package/dist/test/agent-cache-ttl.test.js +0 -41
  376. package/dist/test/agent-cache-ttl.test.js.map +0 -1
  377. package/dist/test/agent-runtime-settings.test.d.ts +0 -2
  378. package/dist/test/agent-runtime-settings.test.d.ts.map +0 -1
  379. package/dist/test/agent-runtime-settings.test.js +0 -1598
  380. package/dist/test/agent-runtime-settings.test.js.map +0 -1
  381. package/dist/test/api-admin-gate.test.d.ts +0 -2
  382. package/dist/test/api-admin-gate.test.d.ts.map +0 -1
  383. package/dist/test/api-admin-gate.test.js +0 -116
  384. package/dist/test/api-admin-gate.test.js.map +0 -1
  385. package/dist/test/assistant-persist-refusal.test.d.ts +0 -2
  386. package/dist/test/assistant-persist-refusal.test.d.ts.map +0 -1
  387. package/dist/test/assistant-persist-refusal.test.js +0 -63
  388. package/dist/test/assistant-persist-refusal.test.js.map +0 -1
  389. package/dist/test/batched-wake-locus.test.d.ts +0 -2
  390. package/dist/test/batched-wake-locus.test.d.ts.map +0 -1
  391. package/dist/test/batched-wake-locus.test.js +0 -166
  392. package/dist/test/batched-wake-locus.test.js.map +0 -1
  393. package/dist/test/busy-agent-scheduler.test.d.ts +0 -2
  394. package/dist/test/busy-agent-scheduler.test.d.ts.map +0 -1
  395. package/dist/test/busy-agent-scheduler.test.js +0 -92
  396. package/dist/test/busy-agent-scheduler.test.js.map +0 -1
  397. package/dist/test/channel-incoming-targeting.test.d.ts +0 -2
  398. package/dist/test/channel-incoming-targeting.test.d.ts.map +0 -1
  399. package/dist/test/channel-incoming-targeting.test.js +0 -81
  400. package/dist/test/channel-incoming-targeting.test.js.map +0 -1
  401. package/dist/test/channel-label-history.test.d.ts +0 -2
  402. package/dist/test/channel-label-history.test.d.ts.map +0 -1
  403. package/dist/test/channel-label-history.test.js +0 -424
  404. package/dist/test/channel-label-history.test.js.map +0 -1
  405. package/dist/test/channel-lifecycle-provenance.test.d.ts +0 -2
  406. package/dist/test/channel-lifecycle-provenance.test.d.ts.map +0 -1
  407. package/dist/test/channel-lifecycle-provenance.test.js +0 -47
  408. package/dist/test/channel-lifecycle-provenance.test.js.map +0 -1
  409. package/dist/test/channel-registry-routing.test.d.ts +0 -2
  410. package/dist/test/channel-registry-routing.test.d.ts.map +0 -1
  411. package/dist/test/channel-registry-routing.test.js +0 -446
  412. package/dist/test/channel-registry-routing.test.js.map +0 -1
  413. package/dist/test/channel-registry-typing.test.d.ts +0 -2
  414. package/dist/test/channel-registry-typing.test.d.ts.map +0 -1
  415. package/dist/test/channel-registry-typing.test.js +0 -91
  416. package/dist/test/channel-registry-typing.test.js.map +0 -1
  417. package/dist/test/channels-changed-respond-first.test.d.ts +0 -2
  418. package/dist/test/channels-changed-respond-first.test.d.ts.map +0 -1
  419. package/dist/test/channels-changed-respond-first.test.js +0 -74
  420. package/dist/test/channels-changed-respond-first.test.js.map +0 -1
  421. package/dist/test/checkpoint-attribution.test.d.ts +0 -2
  422. package/dist/test/checkpoint-attribution.test.d.ts.map +0 -1
  423. package/dist/test/checkpoint-attribution.test.js +0 -200
  424. package/dist/test/checkpoint-attribution.test.js.map +0 -1
  425. package/dist/test/code-execution.test.d.ts +0 -11
  426. package/dist/test/code-execution.test.d.ts.map +0 -1
  427. package/dist/test/code-execution.test.js +0 -1272
  428. package/dist/test/code-execution.test.js.map +0 -1
  429. package/dist/test/component-defaults.test.d.ts +0 -2
  430. package/dist/test/component-defaults.test.d.ts.map +0 -1
  431. package/dist/test/component-defaults.test.js +0 -54
  432. package/dist/test/component-defaults.test.js.map +0 -1
  433. package/dist/test/conversation-fork-injection-scoping.test.d.ts +0 -2
  434. package/dist/test/conversation-fork-injection-scoping.test.d.ts.map +0 -1
  435. package/dist/test/conversation-fork-injection-scoping.test.js +0 -200
  436. package/dist/test/conversation-fork-injection-scoping.test.js.map +0 -1
  437. package/dist/test/conversation-router.test.d.ts +0 -2
  438. package/dist/test/conversation-router.test.d.ts.map +0 -1
  439. package/dist/test/conversation-router.test.js +0 -174
  440. package/dist/test/conversation-router.test.js.map +0 -1
  441. package/dist/test/conversation-routing.test.d.ts +0 -7
  442. package/dist/test/conversation-routing.test.d.ts.map +0 -1
  443. package/dist/test/conversation-routing.test.js +0 -621
  444. package/dist/test/conversation-routing.test.js.map +0 -1
  445. package/dist/test/deferred-wake-integrity.test.d.ts +0 -29
  446. package/dist/test/deferred-wake-integrity.test.d.ts.map +0 -1
  447. package/dist/test/deferred-wake-integrity.test.js +0 -320
  448. package/dist/test/deferred-wake-integrity.test.js.map +0 -1
  449. package/dist/test/discord-awareness-outbox.test.d.ts +0 -2
  450. package/dist/test/discord-awareness-outbox.test.d.ts.map +0 -1
  451. package/dist/test/discord-awareness-outbox.test.js +0 -371
  452. package/dist/test/discord-awareness-outbox.test.js.map +0 -1
  453. package/dist/test/discord-history-delete-window.test.d.ts +0 -2
  454. package/dist/test/discord-history-delete-window.test.d.ts.map +0 -1
  455. package/dist/test/discord-history-delete-window.test.js +0 -81
  456. package/dist/test/discord-history-delete-window.test.js.map +0 -1
  457. package/dist/test/discord-history-sync.test.d.ts +0 -2
  458. package/dist/test/discord-history-sync.test.d.ts.map +0 -1
  459. package/dist/test/discord-history-sync.test.js +0 -56
  460. package/dist/test/discord-history-sync.test.js.map +0 -1
  461. package/dist/test/discord-typing-keepalive.test.d.ts +0 -2
  462. package/dist/test/discord-typing-keepalive.test.d.ts.map +0 -1
  463. package/dist/test/discord-typing-keepalive.test.js +0 -77
  464. package/dist/test/discord-typing-keepalive.test.js.map +0 -1
  465. package/dist/test/ephemeral-settle.test.d.ts +0 -2
  466. package/dist/test/ephemeral-settle.test.d.ts.map +0 -1
  467. package/dist/test/ephemeral-settle.test.js +0 -354
  468. package/dist/test/ephemeral-settle.test.js.map +0 -1
  469. package/dist/test/event-gate-passthrough.test.d.ts +0 -15
  470. package/dist/test/event-gate-passthrough.test.d.ts.map +0 -1
  471. package/dist/test/event-gate-passthrough.test.js +0 -289
  472. package/dist/test/event-gate-passthrough.test.js.map +0 -1
  473. package/dist/test/event-gate-policy-mutation.test.d.ts +0 -2
  474. package/dist/test/event-gate-policy-mutation.test.d.ts.map +0 -1
  475. package/dist/test/event-gate-policy-mutation.test.js +0 -137
  476. package/dist/test/event-gate-policy-mutation.test.js.map +0 -1
  477. package/dist/test/event-gate-rate-limit.test.d.ts +0 -2
  478. package/dist/test/event-gate-rate-limit.test.d.ts.map +0 -1
  479. package/dist/test/event-gate-rate-limit.test.js +0 -627
  480. package/dist/test/event-gate-rate-limit.test.js.map +0 -1
  481. package/dist/test/event-gate-script.test.d.ts +0 -2
  482. package/dist/test/event-gate-script.test.d.ts.map +0 -1
  483. package/dist/test/event-gate-script.test.js +0 -95
  484. package/dist/test/event-gate-script.test.js.map +0 -1
  485. package/dist/test/event-gate-selfwake.test.d.ts +0 -15
  486. package/dist/test/event-gate-selfwake.test.d.ts.map +0 -1
  487. package/dist/test/event-gate-selfwake.test.js +0 -125
  488. package/dist/test/event-gate-selfwake.test.js.map +0 -1
  489. package/dist/test/event-gate-tags.test.d.ts +0 -2
  490. package/dist/test/event-gate-tags.test.d.ts.map +0 -1
  491. package/dist/test/event-gate-tags.test.js +0 -76
  492. package/dist/test/event-gate-tags.test.js.map +0 -1
  493. package/dist/test/event-gate.test.d.ts +0 -2
  494. package/dist/test/event-gate.test.d.ts.map +0 -1
  495. package/dist/test/event-gate.test.js +0 -919
  496. package/dist/test/event-gate.test.js.map +0 -1
  497. package/dist/test/explicit-prose-routing.test.d.ts +0 -11
  498. package/dist/test/explicit-prose-routing.test.d.ts.map +0 -1
  499. package/dist/test/explicit-prose-routing.test.js +0 -1715
  500. package/dist/test/explicit-prose-routing.test.js.map +0 -1
  501. package/dist/test/framework.test.d.ts +0 -5
  502. package/dist/test/framework.test.d.ts.map +0 -1
  503. package/dist/test/framework.test.js +0 -1048
  504. package/dist/test/framework.test.js.map +0 -1
  505. package/dist/test/gather-context-timeout.test.d.ts +0 -2
  506. package/dist/test/gather-context-timeout.test.d.ts.map +0 -1
  507. package/dist/test/gather-context-timeout.test.js +0 -120
  508. package/dist/test/gather-context-timeout.test.js.map +0 -1
  509. package/dist/test/health-snapshot.test.d.ts +0 -2
  510. package/dist/test/health-snapshot.test.d.ts.map +0 -1
  511. package/dist/test/health-snapshot.test.js +0 -74
  512. package/dist/test/health-snapshot.test.js.map +0 -1
  513. package/dist/test/helpers/coalescing-fixture.d.ts +0 -74
  514. package/dist/test/helpers/coalescing-fixture.d.ts.map +0 -1
  515. package/dist/test/helpers/coalescing-fixture.js +0 -152
  516. package/dist/test/helpers/coalescing-fixture.js.map +0 -1
  517. package/dist/test/helpers/coalescing-kill-child.d.ts +0 -2
  518. package/dist/test/helpers/coalescing-kill-child.d.ts.map +0 -1
  519. package/dist/test/helpers/coalescing-kill-child.js +0 -24
  520. package/dist/test/helpers/coalescing-kill-child.js.map +0 -1
  521. package/dist/test/helpers/mock-membrane.d.ts +0 -53
  522. package/dist/test/helpers/mock-membrane.d.ts.map +0 -1
  523. package/dist/test/helpers/mock-membrane.js +0 -168
  524. package/dist/test/helpers/mock-membrane.js.map +0 -1
  525. package/dist/test/helpers/pytc-stop-rows.d.ts +0 -11
  526. package/dist/test/helpers/pytc-stop-rows.d.ts.map +0 -1
  527. package/dist/test/helpers/pytc-stop-rows.js +0 -143
  528. package/dist/test/helpers/pytc-stop-rows.js.map +0 -1
  529. package/dist/test/helpers/quiesce-crash-child.d.ts +0 -2
  530. package/dist/test/helpers/quiesce-crash-child.d.ts.map +0 -1
  531. package/dist/test/helpers/quiesce-crash-child.js +0 -156
  532. package/dist/test/helpers/quiesce-crash-child.js.map +0 -1
  533. package/dist/test/hide-then-turn.test.d.ts +0 -2
  534. package/dist/test/hide-then-turn.test.d.ts.map +0 -1
  535. package/dist/test/hide-then-turn.test.js +0 -101
  536. package/dist/test/hide-then-turn.test.js.map +0 -1
  537. package/dist/test/history-module-overview.test.d.ts +0 -2
  538. package/dist/test/history-module-overview.test.d.ts.map +0 -1
  539. package/dist/test/history-module-overview.test.js +0 -711
  540. package/dist/test/history-module-overview.test.js.map +0 -1
  541. package/dist/test/history-module-realstore.test.d.ts +0 -2
  542. package/dist/test/history-module-realstore.test.d.ts.map +0 -1
  543. package/dist/test/history-module-realstore.test.js +0 -363
  544. package/dist/test/history-module-realstore.test.js.map +0 -1
  545. package/dist/test/history-module-semantic.test.d.ts +0 -2
  546. package/dist/test/history-module-semantic.test.d.ts.map +0 -1
  547. package/dist/test/history-module-semantic.test.js +0 -213
  548. package/dist/test/history-module-semantic.test.js.map +0 -1
  549. package/dist/test/history-module-ux.test.d.ts +0 -2
  550. package/dist/test/history-module-ux.test.d.ts.map +0 -1
  551. package/dist/test/history-module-ux.test.js +0 -304
  552. package/dist/test/history-module-ux.test.js.map +0 -1
  553. package/dist/test/history-module.test.d.ts +0 -2
  554. package/dist/test/history-module.test.d.ts.map +0 -1
  555. package/dist/test/history-module.test.js +0 -619
  556. package/dist/test/history-module.test.js.map +0 -1
  557. package/dist/test/history-semantic-review-findings.test.d.ts +0 -2
  558. package/dist/test/history-semantic-review-findings.test.d.ts.map +0 -1
  559. package/dist/test/history-semantic-review-findings.test.js +0 -338
  560. package/dist/test/history-semantic-review-findings.test.js.map +0 -1
  561. package/dist/test/history-semantic-sync-converges.test.d.ts +0 -2
  562. package/dist/test/history-semantic-sync-converges.test.d.ts.map +0 -1
  563. package/dist/test/history-semantic-sync-converges.test.js +0 -109
  564. package/dist/test/history-semantic-sync-converges.test.js.map +0 -1
  565. package/dist/test/host-quiesce.test.d.ts +0 -2
  566. package/dist/test/host-quiesce.test.d.ts.map +0 -1
  567. package/dist/test/host-quiesce.test.js +0 -988
  568. package/dist/test/host-quiesce.test.js.map +0 -1
  569. package/dist/test/inference-exhaustion-rewind.test.d.ts +0 -2
  570. package/dist/test/inference-exhaustion-rewind.test.d.ts.map +0 -1
  571. package/dist/test/inference-exhaustion-rewind.test.js +0 -387
  572. package/dist/test/inference-exhaustion-rewind.test.js.map +0 -1
  573. package/dist/test/inference-failure-bounds.test.d.ts +0 -2
  574. package/dist/test/inference-failure-bounds.test.d.ts.map +0 -1
  575. package/dist/test/inference-failure-bounds.test.js +0 -1202
  576. package/dist/test/inference-failure-bounds.test.js.map +0 -1
  577. package/dist/test/inference-failure-observability.test.d.ts +0 -2
  578. package/dist/test/inference-failure-observability.test.d.ts.map +0 -1
  579. package/dist/test/inference-failure-observability.test.js +0 -84
  580. package/dist/test/inference-failure-observability.test.js.map +0 -1
  581. package/dist/test/journal-tool.test.d.ts +0 -2
  582. package/dist/test/journal-tool.test.d.ts.map +0 -1
  583. package/dist/test/journal-tool.test.js +0 -33
  584. package/dist/test/journal-tool.test.js.map +0 -1
  585. package/dist/test/kv-unified-open-flight-retry.test.d.ts +0 -2
  586. package/dist/test/kv-unified-open-flight-retry.test.d.ts.map +0 -1
  587. package/dist/test/kv-unified-open-flight-retry.test.js +0 -189
  588. package/dist/test/kv-unified-open-flight-retry.test.js.map +0 -1
  589. package/dist/test/kv-unified-wiring.test.d.ts +0 -2
  590. package/dist/test/kv-unified-wiring.test.d.ts.map +0 -1
  591. package/dist/test/kv-unified-wiring.test.js +0 -95
  592. package/dist/test/kv-unified-wiring.test.js.map +0 -1
  593. package/dist/test/late-events-after-stop.test.d.ts +0 -2
  594. package/dist/test/late-events-after-stop.test.d.ts.map +0 -1
  595. package/dist/test/late-events-after-stop.test.js +0 -122
  596. package/dist/test/late-events-after-stop.test.js.map +0 -1
  597. package/dist/test/liveness-watchdog.test.d.ts +0 -2
  598. package/dist/test/liveness-watchdog.test.d.ts.map +0 -1
  599. package/dist/test/liveness-watchdog.test.js +0 -94
  600. package/dist/test/liveness-watchdog.test.js.map +0 -1
  601. package/dist/test/machine-close-provenance.test.d.ts +0 -2
  602. package/dist/test/machine-close-provenance.test.d.ts.map +0 -1
  603. package/dist/test/machine-close-provenance.test.js +0 -116
  604. package/dist/test/machine-close-provenance.test.js.map +0 -1
  605. package/dist/test/maintenance-timer.test.d.ts +0 -2
  606. package/dist/test/maintenance-timer.test.d.ts.map +0 -1
  607. package/dist/test/maintenance-timer.test.js +0 -1827
  608. package/dist/test/maintenance-timer.test.js.map +0 -1
  609. package/dist/test/mcp-server-bin.test.d.ts +0 -2
  610. package/dist/test/mcp-server-bin.test.d.ts.map +0 -1
  611. package/dist/test/mcp-server-bin.test.js +0 -142
  612. package/dist/test/mcp-server-bin.test.js.map +0 -1
  613. package/dist/test/mcpl-access-provider.test.d.ts +0 -2
  614. package/dist/test/mcpl-access-provider.test.d.ts.map +0 -1
  615. package/dist/test/mcpl-access-provider.test.js +0 -20
  616. package/dist/test/mcpl-access-provider.test.js.map +0 -1
  617. package/dist/test/mcpl-awareness-barrier.test.d.ts +0 -2
  618. package/dist/test/mcpl-awareness-barrier.test.d.ts.map +0 -1
  619. package/dist/test/mcpl-awareness-barrier.test.js +0 -769
  620. package/dist/test/mcpl-awareness-barrier.test.js.map +0 -1
  621. package/dist/test/mcpl-capability-grant.test.d.ts +0 -10
  622. package/dist/test/mcpl-capability-grant.test.d.ts.map +0 -1
  623. package/dist/test/mcpl-capability-grant.test.js +0 -111
  624. package/dist/test/mcpl-capability-grant.test.js.map +0 -1
  625. package/dist/test/mcpl-capability-scoping.test.d.ts +0 -2
  626. package/dist/test/mcpl-capability-scoping.test.d.ts.map +0 -1
  627. package/dist/test/mcpl-capability-scoping.test.js +0 -266
  628. package/dist/test/mcpl-capability-scoping.test.js.map +0 -1
  629. package/dist/test/mcpl-child-env.test.d.ts +0 -2
  630. package/dist/test/mcpl-child-env.test.d.ts.map +0 -1
  631. package/dist/test/mcpl-child-env.test.js +0 -158
  632. package/dist/test/mcpl-child-env.test.js.map +0 -1
  633. package/dist/test/mcpl-coalesced-content-parity.test.d.ts +0 -2
  634. package/dist/test/mcpl-coalesced-content-parity.test.d.ts.map +0 -1
  635. package/dist/test/mcpl-coalesced-content-parity.test.js +0 -532
  636. package/dist/test/mcpl-coalesced-content-parity.test.js.map +0 -1
  637. package/dist/test/mcpl-coalescing.test.d.ts +0 -2
  638. package/dist/test/mcpl-coalescing.test.d.ts.map +0 -1
  639. package/dist/test/mcpl-coalescing.test.js +0 -1125
  640. package/dist/test/mcpl-coalescing.test.js.map +0 -1
  641. package/dist/test/mcpl-config-diagnostics.test.d.ts +0 -2
  642. package/dist/test/mcpl-config-diagnostics.test.d.ts.map +0 -1
  643. package/dist/test/mcpl-config-diagnostics.test.js +0 -452
  644. package/dist/test/mcpl-config-diagnostics.test.js.map +0 -1
  645. package/dist/test/mcpl-empty-content.test.d.ts +0 -2
  646. package/dist/test/mcpl-empty-content.test.d.ts.map +0 -1
  647. package/dist/test/mcpl-empty-content.test.js +0 -368
  648. package/dist/test/mcpl-empty-content.test.js.map +0 -1
  649. package/dist/test/mcpl-gate-roundtrip.test.d.ts +0 -2
  650. package/dist/test/mcpl-gate-roundtrip.test.d.ts.map +0 -1
  651. package/dist/test/mcpl-gate-roundtrip.test.js +0 -285
  652. package/dist/test/mcpl-gate-roundtrip.test.js.map +0 -1
  653. package/dist/test/mcpl-list-status.test.d.ts +0 -2
  654. package/dist/test/mcpl-list-status.test.d.ts.map +0 -1
  655. package/dist/test/mcpl-list-status.test.js +0 -82
  656. package/dist/test/mcpl-list-status.test.js.map +0 -1
  657. package/dist/test/mcpl-manifest-changed.test.d.ts +0 -2
  658. package/dist/test/mcpl-manifest-changed.test.d.ts.map +0 -1
  659. package/dist/test/mcpl-manifest-changed.test.js +0 -178
  660. package/dist/test/mcpl-manifest-changed.test.js.map +0 -1
  661. package/dist/test/mcpl-push-convert.test.d.ts +0 -2
  662. package/dist/test/mcpl-push-convert.test.d.ts.map +0 -1
  663. package/dist/test/mcpl-push-convert.test.js +0 -42
  664. package/dist/test/mcpl-push-convert.test.js.map +0 -1
  665. package/dist/test/mcpl-reconnect-events.test.d.ts +0 -2
  666. package/dist/test/mcpl-reconnect-events.test.d.ts.map +0 -1
  667. package/dist/test/mcpl-reconnect-events.test.js +0 -144
  668. package/dist/test/mcpl-reconnect-events.test.js.map +0 -1
  669. package/dist/test/mcpl-reconnect-reregistration.test.d.ts +0 -2
  670. package/dist/test/mcpl-reconnect-reregistration.test.d.ts.map +0 -1
  671. package/dist/test/mcpl-reconnect-reregistration.test.js +0 -238
  672. package/dist/test/mcpl-reconnect-reregistration.test.js.map +0 -1
  673. package/dist/test/mcpl-reference-fetcher.test.d.ts +0 -2
  674. package/dist/test/mcpl-reference-fetcher.test.d.ts.map +0 -1
  675. package/dist/test/mcpl-reference-fetcher.test.js +0 -427
  676. package/dist/test/mcpl-reference-fetcher.test.js.map +0 -1
  677. package/dist/test/mcpl-reference-fields.test.d.ts +0 -2
  678. package/dist/test/mcpl-reference-fields.test.d.ts.map +0 -1
  679. package/dist/test/mcpl-reference-fields.test.js +0 -149
  680. package/dist/test/mcpl-reference-fields.test.js.map +0 -1
  681. package/dist/test/mcpl-rejection-log-lines.test.d.ts +0 -2
  682. package/dist/test/mcpl-rejection-log-lines.test.d.ts.map +0 -1
  683. package/dist/test/mcpl-rejection-log-lines.test.js +0 -349
  684. package/dist/test/mcpl-rejection-log-lines.test.js.map +0 -1
  685. package/dist/test/mcpl-request-timeout.test.d.ts +0 -2
  686. package/dist/test/mcpl-request-timeout.test.d.ts.map +0 -1
  687. package/dist/test/mcpl-request-timeout.test.js +0 -138
  688. package/dist/test/mcpl-request-timeout.test.js.map +0 -1
  689. package/dist/test/mcpl-runtime-lifecycle.test.d.ts +0 -7
  690. package/dist/test/mcpl-runtime-lifecycle.test.d.ts.map +0 -1
  691. package/dist/test/mcpl-runtime-lifecycle.test.js +0 -142
  692. package/dist/test/mcpl-runtime-lifecycle.test.js.map +0 -1
  693. package/dist/test/mcpl-stderr-tail.test.d.ts +0 -2
  694. package/dist/test/mcpl-stderr-tail.test.d.ts.map +0 -1
  695. package/dist/test/mcpl-stderr-tail.test.js +0 -210
  696. package/dist/test/mcpl-stderr-tail.test.js.map +0 -1
  697. package/dist/test/mcpl-tool-class-listing.test.d.ts +0 -2
  698. package/dist/test/mcpl-tool-class-listing.test.d.ts.map +0 -1
  699. package/dist/test/mcpl-tool-class-listing.test.js +0 -147
  700. package/dist/test/mcpl-tool-class-listing.test.js.map +0 -1
  701. package/dist/test/mcpl-tool-classes.test.d.ts +0 -7
  702. package/dist/test/mcpl-tool-classes.test.d.ts.map +0 -1
  703. package/dist/test/mcpl-tool-classes.test.js +0 -80
  704. package/dist/test/mcpl-tool-classes.test.js.map +0 -1
  705. package/dist/test/mcpl-tool-lifecycle-e2e.test.d.ts +0 -2
  706. package/dist/test/mcpl-tool-lifecycle-e2e.test.d.ts.map +0 -1
  707. package/dist/test/mcpl-tool-lifecycle-e2e.test.js +0 -237
  708. package/dist/test/mcpl-tool-lifecycle-e2e.test.js.map +0 -1
  709. package/dist/test/mcpl-tool-lifecycle-emitter.test.d.ts +0 -11
  710. package/dist/test/mcpl-tool-lifecycle-emitter.test.d.ts.map +0 -1
  711. package/dist/test/mcpl-tool-lifecycle-emitter.test.js +0 -412
  712. package/dist/test/mcpl-tool-lifecycle-emitter.test.js.map +0 -1
  713. package/dist/test/mcpl-tool-lifecycle-script.test.d.ts +0 -2
  714. package/dist/test/mcpl-tool-lifecycle-script.test.d.ts.map +0 -1
  715. package/dist/test/mcpl-tool-lifecycle-script.test.js +0 -288
  716. package/dist/test/mcpl-tool-lifecycle-script.test.js.map +0 -1
  717. package/dist/test/mcpl-tool-lifecycle.test.d.ts +0 -11
  718. package/dist/test/mcpl-tool-lifecycle.test.d.ts.map +0 -1
  719. package/dist/test/mcpl-tool-lifecycle.test.js +0 -270
  720. package/dist/test/mcpl-tool-lifecycle.test.js.map +0 -1
  721. package/dist/test/mcpl-transport-close.test.d.ts +0 -2
  722. package/dist/test/mcpl-transport-close.test.d.ts.map +0 -1
  723. package/dist/test/mcpl-transport-close.test.js +0 -373
  724. package/dist/test/mcpl-transport-close.test.js.map +0 -1
  725. package/dist/test/mcpl-transport-spawn.test.d.ts +0 -2
  726. package/dist/test/mcpl-transport-spawn.test.d.ts.map +0 -1
  727. package/dist/test/mcpl-transport-spawn.test.js +0 -58
  728. package/dist/test/mcpl-transport-spawn.test.js.map +0 -1
  729. package/dist/test/mcpl-ws-transport.test.d.ts +0 -2
  730. package/dist/test/mcpl-ws-transport.test.d.ts.map +0 -1
  731. package/dist/test/mcpl-ws-transport.test.js +0 -259
  732. package/dist/test/mcpl-ws-transport.test.js.map +0 -1
  733. package/dist/test/module-context-integration.test.d.ts +0 -18
  734. package/dist/test/module-context-integration.test.d.ts.map +0 -1
  735. package/dist/test/module-context-integration.test.js +0 -181
  736. package/dist/test/module-context-integration.test.js.map +0 -1
  737. package/dist/test/offline-recovery-branch.test.d.ts +0 -2
  738. package/dist/test/offline-recovery-branch.test.d.ts.map +0 -1
  739. package/dist/test/offline-recovery-branch.test.js +0 -570
  740. package/dist/test/offline-recovery-branch.test.js.map +0 -1
  741. package/dist/test/operator-surgery.test.d.ts +0 -2
  742. package/dist/test/operator-surgery.test.d.ts.map +0 -1
  743. package/dist/test/operator-surgery.test.js +0 -595
  744. package/dist/test/operator-surgery.test.js.map +0 -1
  745. package/dist/test/ops-alert.test.d.ts +0 -2
  746. package/dist/test/ops-alert.test.d.ts.map +0 -1
  747. package/dist/test/ops-alert.test.js +0 -153
  748. package/dist/test/ops-alert.test.js.map +0 -1
  749. package/dist/test/overbudget-drain-breaker.test.d.ts +0 -2
  750. package/dist/test/overbudget-drain-breaker.test.d.ts.map +0 -1
  751. package/dist/test/overbudget-drain-breaker.test.js +0 -198
  752. package/dist/test/overbudget-drain-breaker.test.js.map +0 -1
  753. package/dist/test/pack-installs-alone.test.d.ts +0 -2
  754. package/dist/test/pack-installs-alone.test.d.ts.map +0 -1
  755. package/dist/test/pack-installs-alone.test.js +0 -284
  756. package/dist/test/pack-installs-alone.test.js.map +0 -1
  757. package/dist/test/per-agent-delivery.test.d.ts +0 -2
  758. package/dist/test/per-agent-delivery.test.d.ts.map +0 -1
  759. package/dist/test/per-agent-delivery.test.js +0 -108
  760. package/dist/test/per-agent-delivery.test.js.map +0 -1
  761. package/dist/test/physical-window-restart.test.d.ts +0 -16
  762. package/dist/test/physical-window-restart.test.d.ts.map +0 -1
  763. package/dist/test/physical-window-restart.test.js +0 -487
  764. package/dist/test/physical-window-restart.test.js.map +0 -1
  765. package/dist/test/placed-reaction-baseline.test.d.ts +0 -2
  766. package/dist/test/placed-reaction-baseline.test.d.ts.map +0 -1
  767. package/dist/test/placed-reaction-baseline.test.js +0 -312
  768. package/dist/test/placed-reaction-baseline.test.js.map +0 -1
  769. package/dist/test/present-while-acting.test.d.ts +0 -19
  770. package/dist/test/present-while-acting.test.d.ts.map +0 -1
  771. package/dist/test/present-while-acting.test.js +0 -1649
  772. package/dist/test/present-while-acting.test.js.map +0 -1
  773. package/dist/test/prose-segments.test.d.ts +0 -2
  774. package/dist/test/prose-segments.test.d.ts.map +0 -1
  775. package/dist/test/prose-segments.test.js +0 -52
  776. package/dist/test/prose-segments.test.js.map +0 -1
  777. package/dist/test/prose-stream-router.test.d.ts +0 -2
  778. package/dist/test/prose-stream-router.test.d.ts.map +0 -1
  779. package/dist/test/prose-stream-router.test.js +0 -171
  780. package/dist/test/prose-stream-router.test.js.map +0 -1
  781. package/dist/test/provider-acceleration-cooldown.test.d.ts +0 -2
  782. package/dist/test/provider-acceleration-cooldown.test.d.ts.map +0 -1
  783. package/dist/test/provider-acceleration-cooldown.test.js +0 -435
  784. package/dist/test/provider-acceleration-cooldown.test.js.map +0 -1
  785. package/dist/test/provider-waits.test.d.ts +0 -2
  786. package/dist/test/provider-waits.test.d.ts.map +0 -1
  787. package/dist/test/provider-waits.test.js +0 -2259
  788. package/dist/test/provider-waits.test.js.map +0 -1
  789. package/dist/test/puppet-tool-call.test.d.ts +0 -2
  790. package/dist/test/puppet-tool-call.test.d.ts.map +0 -1
  791. package/dist/test/puppet-tool-call.test.js +0 -226
  792. package/dist/test/puppet-tool-call.test.js.map +0 -1
  793. package/dist/test/puppet-turn-reservation.test.d.ts +0 -2
  794. package/dist/test/puppet-turn-reservation.test.d.ts.map +0 -1
  795. package/dist/test/puppet-turn-reservation.test.js +0 -139
  796. package/dist/test/puppet-turn-reservation.test.js.map +0 -1
  797. package/dist/test/reaction-baseline-platform.test.d.ts +0 -2
  798. package/dist/test/reaction-baseline-platform.test.d.ts.map +0 -1
  799. package/dist/test/reaction-baseline-platform.test.js +0 -124
  800. package/dist/test/reaction-baseline-platform.test.js.map +0 -1
  801. package/dist/test/record-journal.test.d.ts +0 -6
  802. package/dist/test/record-journal.test.d.ts.map +0 -1
  803. package/dist/test/record-journal.test.js +0 -269
  804. package/dist/test/record-journal.test.js.map +0 -1
  805. package/dist/test/refusal-reaction-baseline.test.d.ts +0 -2
  806. package/dist/test/refusal-reaction-baseline.test.d.ts.map +0 -1
  807. package/dist/test/refusal-reaction-baseline.test.js +0 -81
  808. package/dist/test/refusal-reaction-baseline.test.js.map +0 -1
  809. package/dist/test/refusal-rewind.test.d.ts +0 -2
  810. package/dist/test/refusal-rewind.test.d.ts.map +0 -1
  811. package/dist/test/refusal-rewind.test.js +0 -117
  812. package/dist/test/refusal-rewind.test.js.map +0 -1
  813. package/dist/test/refusal-single-call.test.d.ts +0 -2
  814. package/dist/test/refusal-single-call.test.d.ts.map +0 -1
  815. package/dist/test/refusal-single-call.test.js +0 -177
  816. package/dist/test/refusal-single-call.test.js.map +0 -1
  817. package/dist/test/release-bump.test.d.ts +0 -2
  818. package/dist/test/release-bump.test.d.ts.map +0 -1
  819. package/dist/test/release-bump.test.js +0 -248
  820. package/dist/test/release-bump.test.js.map +0 -1
  821. package/dist/test/release-changelog.test.d.ts +0 -2
  822. package/dist/test/release-changelog.test.d.ts.map +0 -1
  823. package/dist/test/release-changelog.test.js +0 -159
  824. package/dist/test/release-changelog.test.js.map +0 -1
  825. package/dist/test/release-holds.test.d.ts +0 -2
  826. package/dist/test/release-holds.test.d.ts.map +0 -1
  827. package/dist/test/release-holds.test.js +0 -456
  828. package/dist/test/release-holds.test.js.map +0 -1
  829. package/dist/test/same-round-think-policy.test.d.ts +0 -2
  830. package/dist/test/same-round-think-policy.test.d.ts.map +0 -1
  831. package/dist/test/same-round-think-policy.test.js +0 -853
  832. package/dist/test/same-round-think-policy.test.js.map +0 -1
  833. package/dist/test/save-recent-image.test.d.ts +0 -26
  834. package/dist/test/save-recent-image.test.d.ts.map +0 -1
  835. package/dist/test/save-recent-image.test.js +0 -974
  836. package/dist/test/save-recent-image.test.js.map +0 -1
  837. package/dist/test/shutdown-errors.test.d.ts +0 -2
  838. package/dist/test/shutdown-errors.test.d.ts.map +0 -1
  839. package/dist/test/shutdown-errors.test.js +0 -662
  840. package/dist/test/shutdown-errors.test.js.map +0 -1
  841. package/dist/test/silent-heartbeat-rows.test.d.ts +0 -2
  842. package/dist/test/silent-heartbeat-rows.test.d.ts.map +0 -1
  843. package/dist/test/silent-heartbeat-rows.test.js +0 -451
  844. package/dist/test/silent-heartbeat-rows.test.js.map +0 -1
  845. package/dist/test/silent-heartbeat.test.d.ts +0 -2
  846. package/dist/test/silent-heartbeat.test.d.ts.map +0 -1
  847. package/dist/test/silent-heartbeat.test.js +0 -165
  848. package/dist/test/silent-heartbeat.test.js.map +0 -1
  849. package/dist/test/state-scaling-e2e.test.d.ts +0 -22
  850. package/dist/test/state-scaling-e2e.test.d.ts.map +0 -1
  851. package/dist/test/state-scaling-e2e.test.js +0 -206
  852. package/dist/test/state-scaling-e2e.test.js.map +0 -1
  853. package/dist/test/state-scaling.test.d.ts +0 -12
  854. package/dist/test/state-scaling.test.d.ts.map +0 -1
  855. package/dist/test/state-scaling.test.js +0 -251
  856. package/dist/test/state-scaling.test.js.map +0 -1
  857. package/dist/test/stop-with-host-operations.test.d.ts +0 -20
  858. package/dist/test/stop-with-host-operations.test.d.ts.map +0 -1
  859. package/dist/test/stop-with-host-operations.test.js +0 -1174
  860. package/dist/test/stop-with-host-operations.test.js.map +0 -1
  861. package/dist/test/stop-with-work-in-flight.test.d.ts +0 -23
  862. package/dist/test/stop-with-work-in-flight.test.d.ts.map +0 -1
  863. package/dist/test/stop-with-work-in-flight.test.js +0 -784
  864. package/dist/test/stop-with-work-in-flight.test.js.map +0 -1
  865. package/dist/test/surgery-marks-receipt.test.d.ts +0 -2
  866. package/dist/test/surgery-marks-receipt.test.d.ts.map +0 -1
  867. package/dist/test/surgery-marks-receipt.test.js +0 -540
  868. package/dist/test/surgery-marks-receipt.test.js.map +0 -1
  869. package/dist/test/thinking-token-stamp.test.d.ts +0 -12
  870. package/dist/test/thinking-token-stamp.test.d.ts.map +0 -1
  871. package/dist/test/thinking-token-stamp.test.js +0 -129
  872. package/dist/test/thinking-token-stamp.test.js.map +0 -1
  873. package/dist/test/timezone.test.d.ts +0 -2
  874. package/dist/test/timezone.test.d.ts.map +0 -1
  875. package/dist/test/timezone.test.js +0 -18
  876. package/dist/test/timezone.test.js.map +0 -1
  877. package/dist/test/tool-batch-hook.test.d.ts +0 -8
  878. package/dist/test/tool-batch-hook.test.d.ts.map +0 -1
  879. package/dist/test/tool-batch-hook.test.js +0 -275
  880. package/dist/test/tool-batch-hook.test.js.map +0 -1
  881. package/dist/test/tool-policy.test.d.ts +0 -2
  882. package/dist/test/tool-policy.test.d.ts.map +0 -1
  883. package/dist/test/tool-policy.test.js +0 -51
  884. package/dist/test/tool-policy.test.js.map +0 -1
  885. package/dist/test/tool-presentation.test.d.ts +0 -2
  886. package/dist/test/tool-presentation.test.d.ts.map +0 -1
  887. package/dist/test/tool-presentation.test.js +0 -268
  888. package/dist/test/tool-presentation.test.js.map +0 -1
  889. package/dist/test/tool-result-content.test.d.ts +0 -2
  890. package/dist/test/tool-result-content.test.d.ts.map +0 -1
  891. package/dist/test/tool-result-content.test.js +0 -37
  892. package/dist/test/tool-result-content.test.js.map +0 -1
  893. package/dist/test/tool-result-guard.test.d.ts +0 -2
  894. package/dist/test/tool-result-guard.test.d.ts.map +0 -1
  895. package/dist/test/tool-result-guard.test.js +0 -3729
  896. package/dist/test/tool-result-guard.test.js.map +0 -1
  897. package/dist/test/tool-result-history.test.d.ts +0 -7
  898. package/dist/test/tool-result-history.test.d.ts.map +0 -1
  899. package/dist/test/tool-result-history.test.js +0 -156
  900. package/dist/test/tool-result-history.test.js.map +0 -1
  901. package/dist/test/tool-result-spill.test.d.ts +0 -13
  902. package/dist/test/tool-result-spill.test.d.ts.map +0 -1
  903. package/dist/test/tool-result-spill.test.js +0 -586
  904. package/dist/test/tool-result-spill.test.js.map +0 -1
  905. package/dist/test/tool-wrapper-prose-guard-integration.test.d.ts +0 -2
  906. package/dist/test/tool-wrapper-prose-guard-integration.test.d.ts.map +0 -1
  907. package/dist/test/tool-wrapper-prose-guard-integration.test.js +0 -485
  908. package/dist/test/tool-wrapper-prose-guard-integration.test.js.map +0 -1
  909. package/dist/test/tool-wrapper-prose-guard.test.d.ts +0 -2
  910. package/dist/test/tool-wrapper-prose-guard.test.d.ts.map +0 -1
  911. package/dist/test/tool-wrapper-prose-guard.test.js +0 -34
  912. package/dist/test/tool-wrapper-prose-guard.test.js.map +0 -1
  913. package/dist/test/tools-observe-parser-conformance.test.d.ts +0 -2
  914. package/dist/test/tools-observe-parser-conformance.test.d.ts.map +0 -1
  915. package/dist/test/tools-observe-parser-conformance.test.js +0 -129
  916. package/dist/test/tools-observe-parser-conformance.test.js.map +0 -1
  917. package/dist/test/trunk-channel-routing.test.d.ts +0 -19
  918. package/dist/test/trunk-channel-routing.test.d.ts.map +0 -1
  919. package/dist/test/trunk-channel-routing.test.js +0 -652
  920. package/dist/test/trunk-channel-routing.test.js.map +0 -1
  921. package/dist/test/tune-out-e2e.test.d.ts +0 -2
  922. package/dist/test/tune-out-e2e.test.d.ts.map +0 -1
  923. package/dist/test/tune-out-e2e.test.js +0 -142
  924. package/dist/test/tune-out-e2e.test.js.map +0 -1
  925. package/dist/test/tune-out-gate-composition.test.d.ts +0 -2
  926. package/dist/test/tune-out-gate-composition.test.d.ts.map +0 -1
  927. package/dist/test/tune-out-gate-composition.test.js +0 -221
  928. package/dist/test/tune-out-gate-composition.test.js.map +0 -1
  929. package/dist/test/tune-out-lifecycle.test.d.ts +0 -2
  930. package/dist/test/tune-out-lifecycle.test.d.ts.map +0 -1
  931. package/dist/test/tune-out-lifecycle.test.js +0 -121
  932. package/dist/test/tune-out-lifecycle.test.js.map +0 -1
  933. package/dist/test/turn-trigger-provenance.test.d.ts +0 -2
  934. package/dist/test/turn-trigger-provenance.test.d.ts.map +0 -1
  935. package/dist/test/turn-trigger-provenance.test.js +0 -137
  936. package/dist/test/turn-trigger-provenance.test.js.map +0 -1
  937. package/dist/test/unconvertible-tool-result.test.d.ts +0 -2
  938. package/dist/test/unconvertible-tool-result.test.d.ts.map +0 -1
  939. package/dist/test/unconvertible-tool-result.test.js +0 -358
  940. package/dist/test/unconvertible-tool-result.test.js.map +0 -1
  941. package/dist/test/unsent-compiles.test.d.ts +0 -2
  942. package/dist/test/unsent-compiles.test.d.ts.map +0 -1
  943. package/dist/test/unsent-compiles.test.js +0 -139
  944. package/dist/test/unsent-compiles.test.js.map +0 -1
  945. package/dist/test/usage-accounting.test.d.ts +0 -2
  946. package/dist/test/usage-accounting.test.d.ts.map +0 -1
  947. package/dist/test/usage-accounting.test.js +0 -13
  948. package/dist/test/usage-accounting.test.js.map +0 -1
  949. package/dist/test/usage-tracker.test.d.ts +0 -2
  950. package/dist/test/usage-tracker.test.d.ts.map +0 -1
  951. package/dist/test/usage-tracker.test.js +0 -129
  952. package/dist/test/usage-tracker.test.js.map +0 -1
  953. package/dist/test/utils-surface.test.d.ts +0 -2
  954. package/dist/test/utils-surface.test.d.ts.map +0 -1
  955. package/dist/test/utils-surface.test.js +0 -145
  956. package/dist/test/utils-surface.test.js.map +0 -1
  957. package/dist/test/workspace-branch-continuation.test.d.ts +0 -15
  958. package/dist/test/workspace-branch-continuation.test.d.ts.map +0 -1
  959. package/dist/test/workspace-branch-continuation.test.js +0 -183
  960. package/dist/test/workspace-branch-continuation.test.js.map +0 -1
  961. package/dist/test/workspace-materialize-freshness.test.d.ts +0 -16
  962. package/dist/test/workspace-materialize-freshness.test.d.ts.map +0 -1
  963. package/dist/test/workspace-materialize-freshness.test.js +0 -252
  964. package/dist/test/workspace-materialize-freshness.test.js.map +0 -1
  965. package/dist/test/workspace-path-containment.test.d.ts +0 -19
  966. package/dist/test/workspace-path-containment.test.d.ts.map +0 -1
  967. package/dist/test/workspace-path-containment.test.js +0 -91
  968. package/dist/test/workspace-path-containment.test.js.map +0 -1
  969. package/dist/test/workspace-read-file-from-disk.test.d.ts +0 -17
  970. package/dist/test/workspace-read-file-from-disk.test.d.ts.map +0 -1
  971. package/dist/test/workspace-read-file-from-disk.test.js +0 -174
  972. package/dist/test/workspace-read-file-from-disk.test.js.map +0 -1
  973. package/dist/test/workspace-read-image.test.d.ts +0 -2
  974. package/dist/test/workspace-read-image.test.d.ts.map +0 -1
  975. package/dist/test/workspace-read-image.test.js +0 -597
  976. package/dist/test/workspace-read-image.test.js.map +0 -1
  977. package/dist/test/workspace-read-text.test.d.ts +0 -2
  978. package/dist/test/workspace-read-text.test.d.ts.map +0 -1
  979. package/dist/test/workspace-read-text.test.js +0 -101
  980. package/dist/test/workspace-read-text.test.js.map +0 -1
  981. package/dist/test/workspace-restore-order.test.d.ts +0 -16
  982. package/dist/test/workspace-restore-order.test.d.ts.map +0 -1
  983. package/dist/test/workspace-restore-order.test.js +0 -140
  984. package/dist/test/workspace-restore-order.test.js.map +0 -1
  985. package/dist/test/workspace-three-way.test.d.ts +0 -12
  986. package/dist/test/workspace-three-way.test.d.ts.map +0 -1
  987. package/dist/test/workspace-three-way.test.js +0 -4094
  988. package/dist/test/workspace-three-way.test.js.map +0 -1
  989. package/dist/test/workspace-watcher.test.d.ts +0 -2
  990. package/dist/test/workspace-watcher.test.d.ts.map +0 -1
  991. package/dist/test/workspace-watcher.test.js +0 -281
  992. package/dist/test/workspace-watcher.test.js.map +0 -1
  993. package/dist/test/xml-round-persist.test.d.ts +0 -19
  994. package/dist/test/xml-round-persist.test.d.ts.map +0 -1
  995. package/dist/test/xml-round-persist.test.js +0 -235
  996. package/dist/test/xml-round-persist.test.js.map +0 -1
  997. 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