@animalabs/agent-framework 0.22.1 → 0.22.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (946) hide show
  1. package/README.md +4 -2
  2. package/dist/src/agent.d.ts +266 -28
  3. package/dist/src/agent.d.ts.map +1 -1
  4. package/dist/src/agent.js +539 -104
  5. package/dist/src/agent.js.map +1 -1
  6. package/dist/src/api/mcp-server-core.d.ts +41 -0
  7. package/dist/src/api/mcp-server-core.d.ts.map +1 -0
  8. package/dist/src/api/mcp-server-core.js +593 -0
  9. package/dist/src/api/mcp-server-core.js.map +1 -0
  10. package/dist/src/api/mcp-server.d.ts +2 -36
  11. package/dist/src/api/mcp-server.d.ts.map +1 -1
  12. package/dist/src/api/mcp-server.js +15 -595
  13. package/dist/src/api/mcp-server.js.map +1 -1
  14. package/dist/src/api/server.d.ts +9 -1
  15. package/dist/src/api/server.d.ts.map +1 -1
  16. package/dist/src/api/server.js +55 -27
  17. package/dist/src/api/server.js.map +1 -1
  18. package/dist/src/api/types.d.ts +10 -2
  19. package/dist/src/api/types.d.ts.map +1 -1
  20. package/dist/src/branch-names.d.ts +14 -0
  21. package/dist/src/branch-names.d.ts.map +1 -0
  22. package/dist/src/branch-names.js +22 -0
  23. package/dist/src/branch-names.js.map +1 -0
  24. package/dist/src/closest-names.d.ts +28 -0
  25. package/dist/src/closest-names.d.ts.map +1 -0
  26. package/dist/src/closest-names.js +98 -0
  27. package/dist/src/closest-names.js.map +1 -0
  28. package/dist/src/code-execution/py-runner.d.ts +16 -5
  29. package/dist/src/code-execution/py-runner.d.ts.map +1 -1
  30. package/dist/src/code-execution/py-runner.js +186 -74
  31. package/dist/src/code-execution/py-runner.js.map +1 -1
  32. package/dist/src/code-execution/runtime-py.d.ts.map +1 -1
  33. package/dist/src/code-execution/runtime-py.js +49 -3
  34. package/dist/src/code-execution/runtime-py.js.map +1 -1
  35. package/dist/src/code-execution/tool-definition.d.ts +12 -1
  36. package/dist/src/code-execution/tool-definition.d.ts.map +1 -1
  37. package/dist/src/code-execution/tool-definition.js +21 -3
  38. package/dist/src/code-execution/tool-definition.js.map +1 -1
  39. package/dist/src/config-checks.d.ts +28 -0
  40. package/dist/src/config-checks.d.ts.map +1 -0
  41. package/dist/src/config-checks.js +52 -0
  42. package/dist/src/config-checks.js.map +1 -0
  43. package/dist/src/deadline-timer.d.ts +21 -0
  44. package/dist/src/deadline-timer.d.ts.map +1 -0
  45. package/dist/src/deadline-timer.js +43 -0
  46. package/dist/src/deadline-timer.js.map +1 -0
  47. package/dist/src/error-message.d.ts +30 -0
  48. package/dist/src/error-message.d.ts.map +1 -0
  49. package/dist/src/error-message.js +50 -0
  50. package/dist/src/error-message.js.map +1 -0
  51. package/dist/src/framework.d.ts +1212 -192
  52. package/dist/src/framework.d.ts.map +1 -1
  53. package/dist/src/framework.js +6686 -1835
  54. package/dist/src/framework.js.map +1 -1
  55. package/dist/src/gate/event-gate.d.ts +8 -0
  56. package/dist/src/gate/event-gate.d.ts.map +1 -1
  57. package/dist/src/gate/event-gate.js +27 -3
  58. package/dist/src/gate/event-gate.js.map +1 -1
  59. package/dist/src/gate/gate-script.d.ts.map +1 -1
  60. package/dist/src/gate/gate-script.js.map +1 -1
  61. package/dist/src/index.d.ts +5 -3
  62. package/dist/src/index.d.ts.map +1 -1
  63. package/dist/src/index.js +5 -3
  64. package/dist/src/index.js.map +1 -1
  65. package/dist/src/mcpl/capability-grant.d.ts.map +1 -1
  66. package/dist/src/mcpl/channel-registry.d.ts +170 -13
  67. package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
  68. package/dist/src/mcpl/channel-registry.js +499 -258
  69. package/dist/src/mcpl/channel-registry.js.map +1 -1
  70. package/dist/src/mcpl/checkpoint-manager.d.ts +21 -1
  71. package/dist/src/mcpl/checkpoint-manager.d.ts.map +1 -1
  72. package/dist/src/mcpl/checkpoint-manager.js +91 -30
  73. package/dist/src/mcpl/checkpoint-manager.js.map +1 -1
  74. package/dist/src/mcpl/conversation-router.d.ts +19 -3
  75. package/dist/src/mcpl/conversation-router.d.ts.map +1 -1
  76. package/dist/src/mcpl/conversation-router.js +23 -8
  77. package/dist/src/mcpl/conversation-router.js.map +1 -1
  78. package/dist/src/mcpl/convert-block.d.ts +20 -0
  79. package/dist/src/mcpl/convert-block.d.ts.map +1 -0
  80. package/dist/src/mcpl/convert-block.js +89 -0
  81. package/dist/src/mcpl/convert-block.js.map +1 -0
  82. package/dist/src/mcpl/errors.d.ts +13 -0
  83. package/dist/src/mcpl/errors.d.ts.map +1 -1
  84. package/dist/src/mcpl/errors.js +28 -0
  85. package/dist/src/mcpl/errors.js.map +1 -1
  86. package/dist/src/mcpl/feature-set-manager.d.ts.map +1 -1
  87. package/dist/src/mcpl/feature-set-manager.js +4 -3
  88. package/dist/src/mcpl/feature-set-manager.js.map +1 -1
  89. package/dist/src/mcpl/hook-orchestrator.d.ts +23 -0
  90. package/dist/src/mcpl/hook-orchestrator.d.ts.map +1 -1
  91. package/dist/src/mcpl/hook-orchestrator.js +83 -72
  92. package/dist/src/mcpl/hook-orchestrator.js.map +1 -1
  93. package/dist/src/mcpl/inbound-source.d.ts +114 -0
  94. package/dist/src/mcpl/inbound-source.d.ts.map +1 -0
  95. package/dist/src/mcpl/inbound-source.js +83 -0
  96. package/dist/src/mcpl/inbound-source.js.map +1 -0
  97. package/dist/src/mcpl/index.d.ts +3 -1
  98. package/dist/src/mcpl/index.d.ts.map +1 -1
  99. package/dist/src/mcpl/index.js +3 -1
  100. package/dist/src/mcpl/index.js.map +1 -1
  101. package/dist/src/mcpl/inference-router.d.ts +15 -11
  102. package/dist/src/mcpl/inference-router.d.ts.map +1 -1
  103. package/dist/src/mcpl/inference-router.js +153 -84
  104. package/dist/src/mcpl/inference-router.js.map +1 -1
  105. package/dist/src/mcpl/log-value.d.ts +54 -0
  106. package/dist/src/mcpl/log-value.d.ts.map +1 -0
  107. package/dist/src/mcpl/log-value.js +109 -0
  108. package/dist/src/mcpl/log-value.js.map +1 -0
  109. package/dist/src/mcpl/prose-stream-router.d.ts +6 -6
  110. package/dist/src/mcpl/prose-stream-router.d.ts.map +1 -1
  111. package/dist/src/mcpl/prose-stream-router.js +4 -4
  112. package/dist/src/mcpl/prose-stream-router.js.map +1 -1
  113. package/dist/src/mcpl/push-coalescer.d.ts +64 -7
  114. package/dist/src/mcpl/push-coalescer.d.ts.map +1 -1
  115. package/dist/src/mcpl/push-coalescer.js +121 -24
  116. package/dist/src/mcpl/push-coalescer.js.map +1 -1
  117. package/dist/src/mcpl/push-handler.d.ts +38 -8
  118. package/dist/src/mcpl/push-handler.d.ts.map +1 -1
  119. package/dist/src/mcpl/push-handler.js +77 -78
  120. package/dist/src/mcpl/push-handler.js.map +1 -1
  121. package/dist/src/mcpl/reference-fetcher.d.ts +14 -2
  122. package/dist/src/mcpl/reference-fetcher.d.ts.map +1 -1
  123. package/dist/src/mcpl/reference-fetcher.js +72 -30
  124. package/dist/src/mcpl/reference-fetcher.js.map +1 -1
  125. package/dist/src/mcpl/references.d.ts +49 -14
  126. package/dist/src/mcpl/references.d.ts.map +1 -1
  127. package/dist/src/mcpl/references.js +74 -21
  128. package/dist/src/mcpl/references.js.map +1 -1
  129. package/dist/src/mcpl/refusal-lines.d.ts +37 -0
  130. package/dist/src/mcpl/refusal-lines.d.ts.map +1 -0
  131. package/dist/src/mcpl/refusal-lines.js +61 -0
  132. package/dist/src/mcpl/refusal-lines.js.map +1 -0
  133. package/dist/src/mcpl/scope-manager.d.ts.map +1 -1
  134. package/dist/src/mcpl/server-connection.d.ts +107 -12
  135. package/dist/src/mcpl/server-connection.d.ts.map +1 -1
  136. package/dist/src/mcpl/server-connection.js +470 -139
  137. package/dist/src/mcpl/server-connection.js.map +1 -1
  138. package/dist/src/mcpl/server-registry.d.ts +10 -1
  139. package/dist/src/mcpl/server-registry.d.ts.map +1 -1
  140. package/dist/src/mcpl/server-registry.js +14 -3
  141. package/dist/src/mcpl/server-registry.js.map +1 -1
  142. package/dist/src/mcpl/skip-reply-wake.d.ts +36 -0
  143. package/dist/src/mcpl/skip-reply-wake.d.ts.map +1 -0
  144. package/dist/src/mcpl/skip-reply-wake.js +55 -0
  145. package/dist/src/mcpl/skip-reply-wake.js.map +1 -0
  146. package/dist/src/mcpl/tool-classes.d.ts +1 -1
  147. package/dist/src/mcpl/tool-classes.d.ts.map +1 -1
  148. package/dist/src/mcpl/tool-classes.js +3 -2
  149. package/dist/src/mcpl/tool-classes.js.map +1 -1
  150. package/dist/src/mcpl/tool-lifecycle.d.ts.map +1 -1
  151. package/dist/src/mcpl/tool-lifecycle.js.map +1 -1
  152. package/dist/src/mcpl/transport.d.ts +74 -7
  153. package/dist/src/mcpl/transport.d.ts.map +1 -1
  154. package/dist/src/mcpl/transport.js +209 -22
  155. package/dist/src/mcpl/transport.js.map +1 -1
  156. package/dist/src/mcpl/types.d.ts +43 -28
  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 +15 -0
  160. package/dist/src/mcpl/visible-content.d.ts.map +1 -1
  161. package/dist/src/mcpl/visible-content.js +25 -0
  162. package/dist/src/mcpl/visible-content.js.map +1 -1
  163. package/dist/src/module-registry.d.ts +19 -1
  164. package/dist/src/module-registry.d.ts.map +1 -1
  165. package/dist/src/module-registry.js +54 -25
  166. package/dist/src/module-registry.js.map +1 -1
  167. package/dist/src/modules/api/index.d.ts.map +1 -1
  168. package/dist/src/modules/api/index.js +1 -1
  169. package/dist/src/modules/api/index.js.map +1 -1
  170. package/dist/src/modules/discord/discord-js-client.d.ts +1 -0
  171. package/dist/src/modules/discord/discord-js-client.d.ts.map +1 -1
  172. package/dist/src/modules/discord/discord-js-client.js +25 -9
  173. package/dist/src/modules/discord/discord-js-client.js.map +1 -1
  174. package/dist/src/modules/discord/index.d.ts +29 -3
  175. package/dist/src/modules/discord/index.d.ts.map +1 -1
  176. package/dist/src/modules/discord/index.js +383 -145
  177. package/dist/src/modules/discord/index.js.map +1 -1
  178. package/dist/src/modules/discord/types.d.ts +14 -1
  179. package/dist/src/modules/discord/types.d.ts.map +1 -1
  180. package/dist/src/modules/health/index.d.ts.map +1 -1
  181. package/dist/src/modules/health/index.js +2 -1
  182. package/dist/src/modules/health/index.js.map +1 -1
  183. package/dist/src/modules/history/index.d.ts +3 -1
  184. package/dist/src/modules/history/index.d.ts.map +1 -1
  185. package/dist/src/modules/history/index.js +359 -127
  186. package/dist/src/modules/history/index.js.map +1 -1
  187. package/dist/src/modules/history/semantic.d.ts +28 -1
  188. package/dist/src/modules/history/semantic.d.ts.map +1 -1
  189. package/dist/src/modules/history/semantic.js +177 -32
  190. package/dist/src/modules/history/semantic.js.map +1 -1
  191. package/dist/src/modules/unknown-tool.d.ts +10 -0
  192. package/dist/src/modules/unknown-tool.d.ts.map +1 -0
  193. package/dist/src/modules/unknown-tool.js +17 -0
  194. package/dist/src/modules/unknown-tool.js.map +1 -0
  195. package/dist/src/modules/workspace/branch-intent.d.ts.map +1 -1
  196. package/dist/src/modules/workspace/branch-intent.js.map +1 -1
  197. package/dist/src/modules/workspace/disk-agreement.d.ts +54 -6
  198. package/dist/src/modules/workspace/disk-agreement.d.ts.map +1 -1
  199. package/dist/src/modules/workspace/disk-agreement.js +93 -27
  200. package/dist/src/modules/workspace/disk-agreement.js.map +1 -1
  201. package/dist/src/modules/workspace/effects.d.ts +64 -6
  202. package/dist/src/modules/workspace/effects.d.ts.map +1 -1
  203. package/dist/src/modules/workspace/effects.js +291 -44
  204. package/dist/src/modules/workspace/effects.js.map +1 -1
  205. package/dist/src/modules/workspace/index.d.ts +127 -27
  206. package/dist/src/modules/workspace/index.d.ts.map +1 -1
  207. package/dist/src/modules/workspace/index.js +821 -248
  208. package/dist/src/modules/workspace/index.js.map +1 -1
  209. package/dist/src/modules/workspace/observe.d.ts +117 -15
  210. package/dist/src/modules/workspace/observe.d.ts.map +1 -1
  211. package/dist/src/modules/workspace/observe.js +436 -51
  212. package/dist/src/modules/workspace/observe.js.map +1 -1
  213. package/dist/src/modules/workspace/reconcile.d.ts +75 -8
  214. package/dist/src/modules/workspace/reconcile.d.ts.map +1 -1
  215. package/dist/src/modules/workspace/reconcile.js +576 -68
  216. package/dist/src/modules/workspace/reconcile.js.map +1 -1
  217. package/dist/src/modules/workspace/types.d.ts +42 -3
  218. package/dist/src/modules/workspace/types.d.ts.map +1 -1
  219. package/dist/src/modules/workspace/types.js.map +1 -1
  220. package/dist/src/modules/workspace/watcher.d.ts +7 -2
  221. package/dist/src/modules/workspace/watcher.d.ts.map +1 -1
  222. package/dist/src/modules/workspace/watcher.js +28 -4
  223. package/dist/src/modules/workspace/watcher.js.map +1 -1
  224. package/dist/src/operator-log.d.ts.map +1 -1
  225. package/dist/src/operator-log.js.map +1 -1
  226. package/dist/src/prose-drafts.d.ts +240 -0
  227. package/dist/src/prose-drafts.d.ts.map +1 -0
  228. package/dist/src/prose-drafts.js +362 -0
  229. package/dist/src/prose-drafts.js.map +1 -0
  230. package/dist/src/prose-segments.d.ts +21 -2
  231. package/dist/src/prose-segments.d.ts.map +1 -1
  232. package/dist/src/prose-segments.js +46 -9
  233. package/dist/src/prose-segments.js.map +1 -1
  234. package/dist/src/provider-waits.d.ts.map +1 -1
  235. package/dist/src/provider-waits.js.map +1 -1
  236. package/dist/src/queue.d.ts.map +1 -1
  237. package/dist/src/record-journal.d.ts.map +1 -1
  238. package/dist/src/record-journal.js.map +1 -1
  239. package/dist/src/recovery/discord-awareness-outbox.d.ts.map +1 -1
  240. package/dist/src/recovery/discord-awareness-outbox.js.map +1 -1
  241. package/dist/src/recovery/offline-branch.d.ts +1 -0
  242. package/dist/src/recovery/offline-branch.d.ts.map +1 -1
  243. package/dist/src/recovery/offline-branch.js +32 -25
  244. package/dist/src/recovery/offline-branch.js.map +1 -1
  245. package/dist/src/recovery/recover-cli.js.map +1 -1
  246. package/dist/src/runtime/liveness-watchdog.d.ts.map +1 -1
  247. package/dist/src/runtime/liveness-watchdog.js.map +1 -1
  248. package/dist/src/safe-slice.d.ts +5 -1
  249. package/dist/src/safe-slice.d.ts.map +1 -1
  250. package/dist/src/safe-slice.js +9 -1
  251. package/dist/src/safe-slice.js.map +1 -1
  252. package/dist/src/shutdown.d.ts.map +1 -1
  253. package/dist/src/shutdown.js.map +1 -1
  254. package/dist/src/stored-removal.d.ts +73 -0
  255. package/dist/src/stored-removal.d.ts.map +1 -0
  256. package/dist/src/stored-removal.js +100 -0
  257. package/dist/src/stored-removal.js.map +1 -0
  258. package/dist/src/thinking-token-stamp.js.map +1 -1
  259. package/dist/src/tool-image-ledger.d.ts +87 -19
  260. package/dist/src/tool-image-ledger.d.ts.map +1 -1
  261. package/dist/src/tool-image-ledger.js +135 -32
  262. package/dist/src/tool-image-ledger.js.map +1 -1
  263. package/dist/src/tool-presentation.d.ts +9 -0
  264. package/dist/src/tool-presentation.d.ts.map +1 -1
  265. package/dist/src/tool-presentation.js +257 -60
  266. package/dist/src/tool-presentation.js.map +1 -1
  267. package/dist/src/tool-result-guard.d.ts.map +1 -1
  268. package/dist/src/tool-result-guard.js +7 -10
  269. package/dist/src/tool-result-guard.js.map +1 -1
  270. package/dist/src/tool-result-history.d.ts +32 -3
  271. package/dist/src/tool-result-history.d.ts.map +1 -1
  272. package/dist/src/tool-result-history.js +106 -19
  273. package/dist/src/tool-result-history.js.map +1 -1
  274. package/dist/src/tune-out/coordinator.d.ts +25 -1
  275. package/dist/src/tune-out/coordinator.d.ts.map +1 -1
  276. package/dist/src/tune-out/coordinator.js +260 -65
  277. package/dist/src/tune-out/coordinator.js.map +1 -1
  278. package/dist/src/tune-out/tools.d.ts +1 -1
  279. package/dist/src/tune-out/tools.d.ts.map +1 -1
  280. package/dist/src/types/agent.d.ts +59 -11
  281. package/dist/src/types/agent.d.ts.map +1 -1
  282. package/dist/src/types/events.d.ts +17 -0
  283. package/dist/src/types/events.d.ts.map +1 -1
  284. package/dist/src/types/framework.d.ts +31 -5
  285. package/dist/src/types/framework.d.ts.map +1 -1
  286. package/dist/src/types/inference-log.d.ts +1 -1
  287. package/dist/src/types/inference-log.d.ts.map +1 -1
  288. package/dist/src/types/module.d.ts +30 -7
  289. package/dist/src/types/module.d.ts.map +1 -1
  290. package/dist/src/types/trace.d.ts +151 -11
  291. package/dist/src/types/trace.d.ts.map +1 -1
  292. package/dist/src/usage/usage-tracker.d.ts +5 -0
  293. package/dist/src/usage/usage-tracker.d.ts.map +1 -1
  294. package/dist/src/usage/usage-tracker.js +35 -8
  295. package/dist/src/usage/usage-tracker.js.map +1 -1
  296. package/package.json +10 -9
  297. package/src/agent.ts +572 -105
  298. package/src/api/mcp-server-core.ts +681 -0
  299. package/src/api/mcp-server.ts +16 -685
  300. package/src/api/server.ts +55 -30
  301. package/src/api/types.ts +10 -2
  302. package/src/branch-names.ts +19 -0
  303. package/src/closest-names.ts +94 -0
  304. package/src/code-execution/py-runner.ts +200 -76
  305. package/src/code-execution/runtime-py.ts +49 -3
  306. package/src/code-execution/tool-definition.ts +28 -4
  307. package/src/config-checks.ts +48 -0
  308. package/src/deadline-timer.ts +44 -0
  309. package/src/error-message.ts +48 -0
  310. package/src/framework.ts +7158 -1936
  311. package/src/gate/event-gate.ts +28 -3
  312. package/src/index.ts +12 -3
  313. package/src/mcpl/channel-registry.ts +615 -289
  314. package/src/mcpl/checkpoint-manager.ts +104 -29
  315. package/src/mcpl/conversation-router.ts +28 -8
  316. package/src/mcpl/convert-block.ts +97 -0
  317. package/src/mcpl/errors.ts +28 -0
  318. package/src/mcpl/feature-set-manager.ts +4 -3
  319. package/src/mcpl/hook-orchestrator.ts +84 -77
  320. package/src/mcpl/inbound-source.ts +156 -0
  321. package/src/mcpl/index.ts +10 -1
  322. package/src/mcpl/inference-router.ts +174 -99
  323. package/src/mcpl/log-value.ts +116 -0
  324. package/src/mcpl/prose-stream-router.ts +6 -6
  325. package/src/mcpl/push-coalescer.ts +124 -24
  326. package/src/mcpl/push-handler.ts +86 -84
  327. package/src/mcpl/reference-fetcher.ts +71 -26
  328. package/src/mcpl/references.ts +81 -22
  329. package/src/mcpl/refusal-lines.ts +59 -0
  330. package/src/mcpl/server-connection.ts +496 -142
  331. package/src/mcpl/server-registry.ts +15 -4
  332. package/src/mcpl/skip-reply-wake.ts +73 -0
  333. package/src/mcpl/tool-classes.ts +3 -2
  334. package/src/mcpl/transport.ts +219 -26
  335. package/src/mcpl/types.ts +18 -3
  336. package/src/mcpl/visible-content.ts +27 -0
  337. package/src/module-registry.ts +58 -23
  338. package/src/modules/api/index.ts +1 -1
  339. package/src/modules/discord/discord-js-client.ts +26 -10
  340. package/src/modules/discord/index.ts +395 -160
  341. package/src/modules/discord/types.ts +15 -2
  342. package/src/modules/health/index.ts +2 -1
  343. package/src/modules/history/index.ts +410 -120
  344. package/src/modules/history/semantic.ts +189 -32
  345. package/src/modules/unknown-tool.ts +16 -0
  346. package/src/modules/workspace/disk-agreement.ts +125 -21
  347. package/src/modules/workspace/effects.ts +279 -35
  348. package/src/modules/workspace/index.ts +841 -261
  349. package/src/modules/workspace/observe.ts +456 -56
  350. package/src/modules/workspace/reconcile.ts +688 -76
  351. package/src/modules/workspace/types.ts +41 -2
  352. package/src/modules/workspace/watcher.ts +27 -4
  353. package/src/prose-drafts.ts +481 -0
  354. package/src/prose-segments.ts +51 -8
  355. package/src/recovery/offline-branch.ts +36 -29
  356. package/src/safe-slice.ts +9 -1
  357. package/src/stored-removal.ts +126 -0
  358. package/src/tool-image-ledger.ts +153 -34
  359. package/src/tool-presentation.ts +224 -40
  360. package/src/tool-result-guard.ts +7 -8
  361. package/src/tool-result-history.ts +124 -20
  362. package/src/tune-out/coordinator.ts +259 -65
  363. package/src/types/agent.ts +59 -13
  364. package/src/types/events.ts +17 -0
  365. package/src/types/framework.ts +31 -5
  366. package/src/types/inference-log.ts +1 -1
  367. package/src/types/module.ts +31 -7
  368. package/src/types/trace.ts +158 -12
  369. package/src/usage/usage-tracker.ts +32 -8
  370. package/dist/test/activation-request-sanitize.test.d.ts +0 -2
  371. package/dist/test/activation-request-sanitize.test.d.ts.map +0 -1
  372. package/dist/test/activation-request-sanitize.test.js +0 -89
  373. package/dist/test/activation-request-sanitize.test.js.map +0 -1
  374. package/dist/test/agent-cache-ttl.test.d.ts +0 -2
  375. package/dist/test/agent-cache-ttl.test.d.ts.map +0 -1
  376. package/dist/test/agent-cache-ttl.test.js +0 -41
  377. package/dist/test/agent-cache-ttl.test.js.map +0 -1
  378. package/dist/test/agent-runtime-settings.test.d.ts +0 -2
  379. package/dist/test/agent-runtime-settings.test.d.ts.map +0 -1
  380. package/dist/test/agent-runtime-settings.test.js +0 -462
  381. package/dist/test/agent-runtime-settings.test.js.map +0 -1
  382. package/dist/test/api-admin-gate.test.d.ts +0 -2
  383. package/dist/test/api-admin-gate.test.d.ts.map +0 -1
  384. package/dist/test/api-admin-gate.test.js +0 -116
  385. package/dist/test/api-admin-gate.test.js.map +0 -1
  386. package/dist/test/assistant-persist-refusal.test.d.ts +0 -2
  387. package/dist/test/assistant-persist-refusal.test.d.ts.map +0 -1
  388. package/dist/test/assistant-persist-refusal.test.js +0 -63
  389. package/dist/test/assistant-persist-refusal.test.js.map +0 -1
  390. package/dist/test/batched-wake-locus.test.d.ts +0 -2
  391. package/dist/test/batched-wake-locus.test.d.ts.map +0 -1
  392. package/dist/test/batched-wake-locus.test.js +0 -166
  393. package/dist/test/batched-wake-locus.test.js.map +0 -1
  394. package/dist/test/busy-agent-scheduler.test.d.ts +0 -2
  395. package/dist/test/busy-agent-scheduler.test.d.ts.map +0 -1
  396. package/dist/test/busy-agent-scheduler.test.js +0 -92
  397. package/dist/test/busy-agent-scheduler.test.js.map +0 -1
  398. package/dist/test/channel-incoming-targeting.test.d.ts +0 -2
  399. package/dist/test/channel-incoming-targeting.test.d.ts.map +0 -1
  400. package/dist/test/channel-incoming-targeting.test.js +0 -81
  401. package/dist/test/channel-incoming-targeting.test.js.map +0 -1
  402. package/dist/test/channel-label-history.test.d.ts +0 -2
  403. package/dist/test/channel-label-history.test.d.ts.map +0 -1
  404. package/dist/test/channel-label-history.test.js +0 -424
  405. package/dist/test/channel-label-history.test.js.map +0 -1
  406. package/dist/test/channel-lifecycle-provenance.test.d.ts +0 -2
  407. package/dist/test/channel-lifecycle-provenance.test.d.ts.map +0 -1
  408. package/dist/test/channel-lifecycle-provenance.test.js +0 -47
  409. package/dist/test/channel-lifecycle-provenance.test.js.map +0 -1
  410. package/dist/test/channel-registry-routing.test.d.ts +0 -2
  411. package/dist/test/channel-registry-routing.test.d.ts.map +0 -1
  412. package/dist/test/channel-registry-routing.test.js +0 -446
  413. package/dist/test/channel-registry-routing.test.js.map +0 -1
  414. package/dist/test/channel-registry-typing.test.d.ts +0 -2
  415. package/dist/test/channel-registry-typing.test.d.ts.map +0 -1
  416. package/dist/test/channel-registry-typing.test.js +0 -91
  417. package/dist/test/channel-registry-typing.test.js.map +0 -1
  418. package/dist/test/channels-changed-respond-first.test.d.ts +0 -2
  419. package/dist/test/channels-changed-respond-first.test.d.ts.map +0 -1
  420. package/dist/test/channels-changed-respond-first.test.js +0 -74
  421. package/dist/test/channels-changed-respond-first.test.js.map +0 -1
  422. package/dist/test/checkpoint-attribution.test.d.ts +0 -2
  423. package/dist/test/checkpoint-attribution.test.d.ts.map +0 -1
  424. package/dist/test/checkpoint-attribution.test.js +0 -200
  425. package/dist/test/checkpoint-attribution.test.js.map +0 -1
  426. package/dist/test/code-execution.test.d.ts +0 -11
  427. package/dist/test/code-execution.test.d.ts.map +0 -1
  428. package/dist/test/code-execution.test.js +0 -1272
  429. package/dist/test/code-execution.test.js.map +0 -1
  430. package/dist/test/component-defaults.test.d.ts +0 -2
  431. package/dist/test/component-defaults.test.d.ts.map +0 -1
  432. package/dist/test/component-defaults.test.js +0 -54
  433. package/dist/test/component-defaults.test.js.map +0 -1
  434. package/dist/test/conversation-fork-injection-scoping.test.d.ts +0 -2
  435. package/dist/test/conversation-fork-injection-scoping.test.d.ts.map +0 -1
  436. package/dist/test/conversation-fork-injection-scoping.test.js +0 -200
  437. package/dist/test/conversation-fork-injection-scoping.test.js.map +0 -1
  438. package/dist/test/conversation-router.test.d.ts +0 -2
  439. package/dist/test/conversation-router.test.d.ts.map +0 -1
  440. package/dist/test/conversation-router.test.js +0 -174
  441. package/dist/test/conversation-router.test.js.map +0 -1
  442. package/dist/test/conversation-routing.test.d.ts +0 -7
  443. package/dist/test/conversation-routing.test.d.ts.map +0 -1
  444. package/dist/test/conversation-routing.test.js +0 -387
  445. package/dist/test/conversation-routing.test.js.map +0 -1
  446. package/dist/test/deferred-wake-integrity.test.d.ts +0 -29
  447. package/dist/test/deferred-wake-integrity.test.d.ts.map +0 -1
  448. package/dist/test/deferred-wake-integrity.test.js +0 -320
  449. package/dist/test/deferred-wake-integrity.test.js.map +0 -1
  450. package/dist/test/discord-awareness-outbox.test.d.ts +0 -2
  451. package/dist/test/discord-awareness-outbox.test.d.ts.map +0 -1
  452. package/dist/test/discord-awareness-outbox.test.js +0 -267
  453. package/dist/test/discord-awareness-outbox.test.js.map +0 -1
  454. package/dist/test/discord-history-delete-window.test.d.ts +0 -2
  455. package/dist/test/discord-history-delete-window.test.d.ts.map +0 -1
  456. package/dist/test/discord-history-delete-window.test.js +0 -81
  457. package/dist/test/discord-history-delete-window.test.js.map +0 -1
  458. package/dist/test/discord-history-sync.test.d.ts +0 -2
  459. package/dist/test/discord-history-sync.test.d.ts.map +0 -1
  460. package/dist/test/discord-history-sync.test.js +0 -56
  461. package/dist/test/discord-history-sync.test.js.map +0 -1
  462. package/dist/test/ephemeral-settle.test.d.ts +0 -2
  463. package/dist/test/ephemeral-settle.test.d.ts.map +0 -1
  464. package/dist/test/ephemeral-settle.test.js +0 -354
  465. package/dist/test/ephemeral-settle.test.js.map +0 -1
  466. package/dist/test/event-gate-passthrough.test.d.ts +0 -15
  467. package/dist/test/event-gate-passthrough.test.d.ts.map +0 -1
  468. package/dist/test/event-gate-passthrough.test.js +0 -289
  469. package/dist/test/event-gate-passthrough.test.js.map +0 -1
  470. package/dist/test/event-gate-policy-mutation.test.d.ts +0 -2
  471. package/dist/test/event-gate-policy-mutation.test.d.ts.map +0 -1
  472. package/dist/test/event-gate-policy-mutation.test.js +0 -137
  473. package/dist/test/event-gate-policy-mutation.test.js.map +0 -1
  474. package/dist/test/event-gate-rate-limit.test.d.ts +0 -2
  475. package/dist/test/event-gate-rate-limit.test.d.ts.map +0 -1
  476. package/dist/test/event-gate-rate-limit.test.js +0 -627
  477. package/dist/test/event-gate-rate-limit.test.js.map +0 -1
  478. package/dist/test/event-gate-script.test.d.ts +0 -2
  479. package/dist/test/event-gate-script.test.d.ts.map +0 -1
  480. package/dist/test/event-gate-script.test.js +0 -95
  481. package/dist/test/event-gate-script.test.js.map +0 -1
  482. package/dist/test/event-gate-selfwake.test.d.ts +0 -15
  483. package/dist/test/event-gate-selfwake.test.d.ts.map +0 -1
  484. package/dist/test/event-gate-selfwake.test.js +0 -125
  485. package/dist/test/event-gate-selfwake.test.js.map +0 -1
  486. package/dist/test/event-gate-tags.test.d.ts +0 -2
  487. package/dist/test/event-gate-tags.test.d.ts.map +0 -1
  488. package/dist/test/event-gate-tags.test.js +0 -76
  489. package/dist/test/event-gate-tags.test.js.map +0 -1
  490. package/dist/test/event-gate.test.d.ts +0 -2
  491. package/dist/test/event-gate.test.d.ts.map +0 -1
  492. package/dist/test/event-gate.test.js +0 -919
  493. package/dist/test/event-gate.test.js.map +0 -1
  494. package/dist/test/explicit-prose-routing.test.d.ts +0 -11
  495. package/dist/test/explicit-prose-routing.test.d.ts.map +0 -1
  496. package/dist/test/explicit-prose-routing.test.js +0 -1394
  497. package/dist/test/explicit-prose-routing.test.js.map +0 -1
  498. package/dist/test/framework.test.d.ts +0 -5
  499. package/dist/test/framework.test.d.ts.map +0 -1
  500. package/dist/test/framework.test.js +0 -1048
  501. package/dist/test/framework.test.js.map +0 -1
  502. package/dist/test/gather-context-timeout.test.d.ts +0 -2
  503. package/dist/test/gather-context-timeout.test.d.ts.map +0 -1
  504. package/dist/test/gather-context-timeout.test.js +0 -120
  505. package/dist/test/gather-context-timeout.test.js.map +0 -1
  506. package/dist/test/health-snapshot.test.d.ts +0 -2
  507. package/dist/test/health-snapshot.test.d.ts.map +0 -1
  508. package/dist/test/health-snapshot.test.js +0 -74
  509. package/dist/test/health-snapshot.test.js.map +0 -1
  510. package/dist/test/helpers/coalescing-fixture.d.ts +0 -72
  511. package/dist/test/helpers/coalescing-fixture.d.ts.map +0 -1
  512. package/dist/test/helpers/coalescing-fixture.js +0 -146
  513. package/dist/test/helpers/coalescing-fixture.js.map +0 -1
  514. package/dist/test/helpers/coalescing-kill-child.d.ts +0 -2
  515. package/dist/test/helpers/coalescing-kill-child.d.ts.map +0 -1
  516. package/dist/test/helpers/coalescing-kill-child.js +0 -24
  517. package/dist/test/helpers/coalescing-kill-child.js.map +0 -1
  518. package/dist/test/helpers/mock-membrane.d.ts +0 -53
  519. package/dist/test/helpers/mock-membrane.d.ts.map +0 -1
  520. package/dist/test/helpers/mock-membrane.js +0 -168
  521. package/dist/test/helpers/mock-membrane.js.map +0 -1
  522. package/dist/test/helpers/pytc-stop-rows.d.ts +0 -11
  523. package/dist/test/helpers/pytc-stop-rows.d.ts.map +0 -1
  524. package/dist/test/helpers/pytc-stop-rows.js +0 -143
  525. package/dist/test/helpers/pytc-stop-rows.js.map +0 -1
  526. package/dist/test/helpers/quiesce-crash-child.d.ts +0 -2
  527. package/dist/test/helpers/quiesce-crash-child.d.ts.map +0 -1
  528. package/dist/test/helpers/quiesce-crash-child.js +0 -156
  529. package/dist/test/helpers/quiesce-crash-child.js.map +0 -1
  530. package/dist/test/history-module-overview.test.d.ts +0 -2
  531. package/dist/test/history-module-overview.test.d.ts.map +0 -1
  532. package/dist/test/history-module-overview.test.js +0 -711
  533. package/dist/test/history-module-overview.test.js.map +0 -1
  534. package/dist/test/history-module-realstore.test.d.ts +0 -2
  535. package/dist/test/history-module-realstore.test.d.ts.map +0 -1
  536. package/dist/test/history-module-realstore.test.js +0 -363
  537. package/dist/test/history-module-realstore.test.js.map +0 -1
  538. package/dist/test/history-module-semantic.test.d.ts +0 -2
  539. package/dist/test/history-module-semantic.test.d.ts.map +0 -1
  540. package/dist/test/history-module-semantic.test.js +0 -213
  541. package/dist/test/history-module-semantic.test.js.map +0 -1
  542. package/dist/test/history-module-ux.test.d.ts +0 -2
  543. package/dist/test/history-module-ux.test.d.ts.map +0 -1
  544. package/dist/test/history-module-ux.test.js +0 -304
  545. package/dist/test/history-module-ux.test.js.map +0 -1
  546. package/dist/test/history-module.test.d.ts +0 -2
  547. package/dist/test/history-module.test.d.ts.map +0 -1
  548. package/dist/test/history-module.test.js +0 -619
  549. package/dist/test/history-module.test.js.map +0 -1
  550. package/dist/test/history-semantic-review-findings.test.d.ts +0 -2
  551. package/dist/test/history-semantic-review-findings.test.d.ts.map +0 -1
  552. package/dist/test/history-semantic-review-findings.test.js +0 -338
  553. package/dist/test/history-semantic-review-findings.test.js.map +0 -1
  554. package/dist/test/history-semantic-sync-converges.test.d.ts +0 -2
  555. package/dist/test/history-semantic-sync-converges.test.d.ts.map +0 -1
  556. package/dist/test/history-semantic-sync-converges.test.js +0 -109
  557. package/dist/test/history-semantic-sync-converges.test.js.map +0 -1
  558. package/dist/test/host-quiesce.test.d.ts +0 -2
  559. package/dist/test/host-quiesce.test.d.ts.map +0 -1
  560. package/dist/test/host-quiesce.test.js +0 -863
  561. package/dist/test/host-quiesce.test.js.map +0 -1
  562. package/dist/test/inference-exhaustion-rewind.test.d.ts +0 -2
  563. package/dist/test/inference-exhaustion-rewind.test.d.ts.map +0 -1
  564. package/dist/test/inference-exhaustion-rewind.test.js +0 -309
  565. package/dist/test/inference-exhaustion-rewind.test.js.map +0 -1
  566. package/dist/test/inference-failure-bounds.test.d.ts +0 -2
  567. package/dist/test/inference-failure-bounds.test.d.ts.map +0 -1
  568. package/dist/test/inference-failure-bounds.test.js +0 -1201
  569. package/dist/test/inference-failure-bounds.test.js.map +0 -1
  570. package/dist/test/inference-failure-observability.test.d.ts +0 -2
  571. package/dist/test/inference-failure-observability.test.d.ts.map +0 -1
  572. package/dist/test/inference-failure-observability.test.js +0 -84
  573. package/dist/test/inference-failure-observability.test.js.map +0 -1
  574. package/dist/test/journal-tool.test.d.ts +0 -2
  575. package/dist/test/journal-tool.test.d.ts.map +0 -1
  576. package/dist/test/journal-tool.test.js +0 -33
  577. package/dist/test/journal-tool.test.js.map +0 -1
  578. package/dist/test/kv-unified-open-flight-retry.test.d.ts +0 -2
  579. package/dist/test/kv-unified-open-flight-retry.test.d.ts.map +0 -1
  580. package/dist/test/kv-unified-open-flight-retry.test.js +0 -189
  581. package/dist/test/kv-unified-open-flight-retry.test.js.map +0 -1
  582. package/dist/test/kv-unified-wiring.test.d.ts +0 -2
  583. package/dist/test/kv-unified-wiring.test.d.ts.map +0 -1
  584. package/dist/test/kv-unified-wiring.test.js +0 -95
  585. package/dist/test/kv-unified-wiring.test.js.map +0 -1
  586. package/dist/test/late-events-after-stop.test.d.ts +0 -2
  587. package/dist/test/late-events-after-stop.test.d.ts.map +0 -1
  588. package/dist/test/late-events-after-stop.test.js +0 -122
  589. package/dist/test/late-events-after-stop.test.js.map +0 -1
  590. package/dist/test/liveness-watchdog.test.d.ts +0 -2
  591. package/dist/test/liveness-watchdog.test.d.ts.map +0 -1
  592. package/dist/test/liveness-watchdog.test.js +0 -94
  593. package/dist/test/liveness-watchdog.test.js.map +0 -1
  594. package/dist/test/machine-close-provenance.test.d.ts +0 -2
  595. package/dist/test/machine-close-provenance.test.d.ts.map +0 -1
  596. package/dist/test/machine-close-provenance.test.js +0 -116
  597. package/dist/test/machine-close-provenance.test.js.map +0 -1
  598. package/dist/test/maintenance-timer.test.d.ts +0 -2
  599. package/dist/test/maintenance-timer.test.d.ts.map +0 -1
  600. package/dist/test/maintenance-timer.test.js +0 -265
  601. package/dist/test/maintenance-timer.test.js.map +0 -1
  602. package/dist/test/mcpl-access-provider.test.d.ts +0 -2
  603. package/dist/test/mcpl-access-provider.test.d.ts.map +0 -1
  604. package/dist/test/mcpl-access-provider.test.js +0 -20
  605. package/dist/test/mcpl-access-provider.test.js.map +0 -1
  606. package/dist/test/mcpl-awareness-barrier.test.d.ts +0 -2
  607. package/dist/test/mcpl-awareness-barrier.test.d.ts.map +0 -1
  608. package/dist/test/mcpl-awareness-barrier.test.js +0 -769
  609. package/dist/test/mcpl-awareness-barrier.test.js.map +0 -1
  610. package/dist/test/mcpl-capability-grant.test.d.ts +0 -10
  611. package/dist/test/mcpl-capability-grant.test.d.ts.map +0 -1
  612. package/dist/test/mcpl-capability-grant.test.js +0 -111
  613. package/dist/test/mcpl-capability-grant.test.js.map +0 -1
  614. package/dist/test/mcpl-capability-scoping.test.d.ts +0 -2
  615. package/dist/test/mcpl-capability-scoping.test.d.ts.map +0 -1
  616. package/dist/test/mcpl-capability-scoping.test.js +0 -266
  617. package/dist/test/mcpl-capability-scoping.test.js.map +0 -1
  618. package/dist/test/mcpl-child-env.test.d.ts +0 -2
  619. package/dist/test/mcpl-child-env.test.d.ts.map +0 -1
  620. package/dist/test/mcpl-child-env.test.js +0 -158
  621. package/dist/test/mcpl-child-env.test.js.map +0 -1
  622. package/dist/test/mcpl-coalescing.test.d.ts +0 -2
  623. package/dist/test/mcpl-coalescing.test.d.ts.map +0 -1
  624. package/dist/test/mcpl-coalescing.test.js +0 -1125
  625. package/dist/test/mcpl-coalescing.test.js.map +0 -1
  626. package/dist/test/mcpl-config-diagnostics.test.d.ts +0 -2
  627. package/dist/test/mcpl-config-diagnostics.test.d.ts.map +0 -1
  628. package/dist/test/mcpl-config-diagnostics.test.js +0 -452
  629. package/dist/test/mcpl-config-diagnostics.test.js.map +0 -1
  630. package/dist/test/mcpl-empty-content.test.d.ts +0 -2
  631. package/dist/test/mcpl-empty-content.test.d.ts.map +0 -1
  632. package/dist/test/mcpl-empty-content.test.js +0 -368
  633. package/dist/test/mcpl-empty-content.test.js.map +0 -1
  634. package/dist/test/mcpl-gate-roundtrip.test.d.ts +0 -2
  635. package/dist/test/mcpl-gate-roundtrip.test.d.ts.map +0 -1
  636. package/dist/test/mcpl-gate-roundtrip.test.js +0 -285
  637. package/dist/test/mcpl-gate-roundtrip.test.js.map +0 -1
  638. package/dist/test/mcpl-list-status.test.d.ts +0 -2
  639. package/dist/test/mcpl-list-status.test.d.ts.map +0 -1
  640. package/dist/test/mcpl-list-status.test.js +0 -82
  641. package/dist/test/mcpl-list-status.test.js.map +0 -1
  642. package/dist/test/mcpl-manifest-changed.test.d.ts +0 -2
  643. package/dist/test/mcpl-manifest-changed.test.d.ts.map +0 -1
  644. package/dist/test/mcpl-manifest-changed.test.js +0 -178
  645. package/dist/test/mcpl-manifest-changed.test.js.map +0 -1
  646. package/dist/test/mcpl-push-convert.test.d.ts +0 -2
  647. package/dist/test/mcpl-push-convert.test.d.ts.map +0 -1
  648. package/dist/test/mcpl-push-convert.test.js +0 -42
  649. package/dist/test/mcpl-push-convert.test.js.map +0 -1
  650. package/dist/test/mcpl-reconnect-events.test.d.ts +0 -2
  651. package/dist/test/mcpl-reconnect-events.test.d.ts.map +0 -1
  652. package/dist/test/mcpl-reconnect-events.test.js +0 -144
  653. package/dist/test/mcpl-reconnect-events.test.js.map +0 -1
  654. package/dist/test/mcpl-reconnect-reregistration.test.d.ts +0 -2
  655. package/dist/test/mcpl-reconnect-reregistration.test.d.ts.map +0 -1
  656. package/dist/test/mcpl-reconnect-reregistration.test.js +0 -236
  657. package/dist/test/mcpl-reconnect-reregistration.test.js.map +0 -1
  658. package/dist/test/mcpl-reference-fetcher.test.d.ts +0 -2
  659. package/dist/test/mcpl-reference-fetcher.test.d.ts.map +0 -1
  660. package/dist/test/mcpl-reference-fetcher.test.js +0 -427
  661. package/dist/test/mcpl-reference-fetcher.test.js.map +0 -1
  662. package/dist/test/mcpl-reference-fields.test.d.ts +0 -2
  663. package/dist/test/mcpl-reference-fields.test.d.ts.map +0 -1
  664. package/dist/test/mcpl-reference-fields.test.js +0 -149
  665. package/dist/test/mcpl-reference-fields.test.js.map +0 -1
  666. package/dist/test/mcpl-request-timeout.test.d.ts +0 -2
  667. package/dist/test/mcpl-request-timeout.test.d.ts.map +0 -1
  668. package/dist/test/mcpl-request-timeout.test.js +0 -138
  669. package/dist/test/mcpl-request-timeout.test.js.map +0 -1
  670. package/dist/test/mcpl-runtime-lifecycle.test.d.ts +0 -7
  671. package/dist/test/mcpl-runtime-lifecycle.test.d.ts.map +0 -1
  672. package/dist/test/mcpl-runtime-lifecycle.test.js +0 -142
  673. package/dist/test/mcpl-runtime-lifecycle.test.js.map +0 -1
  674. package/dist/test/mcpl-tool-class-listing.test.d.ts +0 -2
  675. package/dist/test/mcpl-tool-class-listing.test.d.ts.map +0 -1
  676. package/dist/test/mcpl-tool-class-listing.test.js +0 -147
  677. package/dist/test/mcpl-tool-class-listing.test.js.map +0 -1
  678. package/dist/test/mcpl-tool-classes.test.d.ts +0 -7
  679. package/dist/test/mcpl-tool-classes.test.d.ts.map +0 -1
  680. package/dist/test/mcpl-tool-classes.test.js +0 -80
  681. package/dist/test/mcpl-tool-classes.test.js.map +0 -1
  682. package/dist/test/mcpl-tool-lifecycle-e2e.test.d.ts +0 -2
  683. package/dist/test/mcpl-tool-lifecycle-e2e.test.d.ts.map +0 -1
  684. package/dist/test/mcpl-tool-lifecycle-e2e.test.js +0 -237
  685. package/dist/test/mcpl-tool-lifecycle-e2e.test.js.map +0 -1
  686. package/dist/test/mcpl-tool-lifecycle-emitter.test.d.ts +0 -11
  687. package/dist/test/mcpl-tool-lifecycle-emitter.test.d.ts.map +0 -1
  688. package/dist/test/mcpl-tool-lifecycle-emitter.test.js +0 -412
  689. package/dist/test/mcpl-tool-lifecycle-emitter.test.js.map +0 -1
  690. package/dist/test/mcpl-tool-lifecycle-script.test.d.ts +0 -2
  691. package/dist/test/mcpl-tool-lifecycle-script.test.d.ts.map +0 -1
  692. package/dist/test/mcpl-tool-lifecycle-script.test.js +0 -288
  693. package/dist/test/mcpl-tool-lifecycle-script.test.js.map +0 -1
  694. package/dist/test/mcpl-tool-lifecycle.test.d.ts +0 -11
  695. package/dist/test/mcpl-tool-lifecycle.test.d.ts.map +0 -1
  696. package/dist/test/mcpl-tool-lifecycle.test.js +0 -270
  697. package/dist/test/mcpl-tool-lifecycle.test.js.map +0 -1
  698. package/dist/test/mcpl-ws-transport.test.d.ts +0 -2
  699. package/dist/test/mcpl-ws-transport.test.d.ts.map +0 -1
  700. package/dist/test/mcpl-ws-transport.test.js +0 -258
  701. package/dist/test/mcpl-ws-transport.test.js.map +0 -1
  702. package/dist/test/module-context-integration.test.d.ts +0 -18
  703. package/dist/test/module-context-integration.test.d.ts.map +0 -1
  704. package/dist/test/module-context-integration.test.js +0 -181
  705. package/dist/test/module-context-integration.test.js.map +0 -1
  706. package/dist/test/offline-recovery-branch.test.d.ts +0 -2
  707. package/dist/test/offline-recovery-branch.test.d.ts.map +0 -1
  708. package/dist/test/offline-recovery-branch.test.js +0 -226
  709. package/dist/test/offline-recovery-branch.test.js.map +0 -1
  710. package/dist/test/operator-surgery.test.d.ts +0 -2
  711. package/dist/test/operator-surgery.test.d.ts.map +0 -1
  712. package/dist/test/operator-surgery.test.js +0 -398
  713. package/dist/test/operator-surgery.test.js.map +0 -1
  714. package/dist/test/ops-alert.test.d.ts +0 -2
  715. package/dist/test/ops-alert.test.d.ts.map +0 -1
  716. package/dist/test/ops-alert.test.js +0 -153
  717. package/dist/test/ops-alert.test.js.map +0 -1
  718. package/dist/test/overbudget-drain-breaker.test.d.ts +0 -2
  719. package/dist/test/overbudget-drain-breaker.test.d.ts.map +0 -1
  720. package/dist/test/overbudget-drain-breaker.test.js +0 -197
  721. package/dist/test/overbudget-drain-breaker.test.js.map +0 -1
  722. package/dist/test/per-agent-delivery.test.d.ts +0 -2
  723. package/dist/test/per-agent-delivery.test.d.ts.map +0 -1
  724. package/dist/test/per-agent-delivery.test.js +0 -108
  725. package/dist/test/per-agent-delivery.test.js.map +0 -1
  726. package/dist/test/physical-window-restart.test.d.ts +0 -14
  727. package/dist/test/physical-window-restart.test.d.ts.map +0 -1
  728. package/dist/test/physical-window-restart.test.js +0 -222
  729. package/dist/test/physical-window-restart.test.js.map +0 -1
  730. package/dist/test/placed-reaction-baseline.test.d.ts +0 -2
  731. package/dist/test/placed-reaction-baseline.test.d.ts.map +0 -1
  732. package/dist/test/placed-reaction-baseline.test.js +0 -312
  733. package/dist/test/placed-reaction-baseline.test.js.map +0 -1
  734. package/dist/test/present-while-acting.test.d.ts +0 -19
  735. package/dist/test/present-while-acting.test.d.ts.map +0 -1
  736. package/dist/test/present-while-acting.test.js +0 -706
  737. package/dist/test/present-while-acting.test.js.map +0 -1
  738. package/dist/test/prose-segments.test.d.ts +0 -2
  739. package/dist/test/prose-segments.test.d.ts.map +0 -1
  740. package/dist/test/prose-segments.test.js +0 -52
  741. package/dist/test/prose-segments.test.js.map +0 -1
  742. package/dist/test/prose-stream-router.test.d.ts +0 -2
  743. package/dist/test/prose-stream-router.test.d.ts.map +0 -1
  744. package/dist/test/prose-stream-router.test.js +0 -171
  745. package/dist/test/prose-stream-router.test.js.map +0 -1
  746. package/dist/test/provider-acceleration-cooldown.test.d.ts +0 -2
  747. package/dist/test/provider-acceleration-cooldown.test.d.ts.map +0 -1
  748. package/dist/test/provider-acceleration-cooldown.test.js +0 -435
  749. package/dist/test/provider-acceleration-cooldown.test.js.map +0 -1
  750. package/dist/test/provider-waits.test.d.ts +0 -2
  751. package/dist/test/provider-waits.test.d.ts.map +0 -1
  752. package/dist/test/provider-waits.test.js +0 -2196
  753. package/dist/test/provider-waits.test.js.map +0 -1
  754. package/dist/test/puppet-tool-call.test.d.ts +0 -2
  755. package/dist/test/puppet-tool-call.test.d.ts.map +0 -1
  756. package/dist/test/puppet-tool-call.test.js +0 -224
  757. package/dist/test/puppet-tool-call.test.js.map +0 -1
  758. package/dist/test/puppet-turn-reservation.test.d.ts +0 -2
  759. package/dist/test/puppet-turn-reservation.test.d.ts.map +0 -1
  760. package/dist/test/puppet-turn-reservation.test.js +0 -139
  761. package/dist/test/puppet-turn-reservation.test.js.map +0 -1
  762. package/dist/test/reaction-baseline-platform.test.d.ts +0 -2
  763. package/dist/test/reaction-baseline-platform.test.d.ts.map +0 -1
  764. package/dist/test/reaction-baseline-platform.test.js +0 -124
  765. package/dist/test/reaction-baseline-platform.test.js.map +0 -1
  766. package/dist/test/record-journal.test.d.ts +0 -6
  767. package/dist/test/record-journal.test.d.ts.map +0 -1
  768. package/dist/test/record-journal.test.js +0 -269
  769. package/dist/test/record-journal.test.js.map +0 -1
  770. package/dist/test/refusal-reaction-baseline.test.d.ts +0 -2
  771. package/dist/test/refusal-reaction-baseline.test.d.ts.map +0 -1
  772. package/dist/test/refusal-reaction-baseline.test.js +0 -81
  773. package/dist/test/refusal-reaction-baseline.test.js.map +0 -1
  774. package/dist/test/refusal-rewind.test.d.ts +0 -2
  775. package/dist/test/refusal-rewind.test.d.ts.map +0 -1
  776. package/dist/test/refusal-rewind.test.js +0 -108
  777. package/dist/test/refusal-rewind.test.js.map +0 -1
  778. package/dist/test/refusal-single-call.test.d.ts +0 -2
  779. package/dist/test/refusal-single-call.test.d.ts.map +0 -1
  780. package/dist/test/refusal-single-call.test.js +0 -177
  781. package/dist/test/refusal-single-call.test.js.map +0 -1
  782. package/dist/test/release-changelog.test.d.ts +0 -2
  783. package/dist/test/release-changelog.test.d.ts.map +0 -1
  784. package/dist/test/release-changelog.test.js +0 -159
  785. package/dist/test/release-changelog.test.js.map +0 -1
  786. package/dist/test/same-round-think-policy.test.d.ts +0 -2
  787. package/dist/test/same-round-think-policy.test.d.ts.map +0 -1
  788. package/dist/test/same-round-think-policy.test.js +0 -853
  789. package/dist/test/same-round-think-policy.test.js.map +0 -1
  790. package/dist/test/save-recent-image.test.d.ts +0 -26
  791. package/dist/test/save-recent-image.test.d.ts.map +0 -1
  792. package/dist/test/save-recent-image.test.js +0 -974
  793. package/dist/test/save-recent-image.test.js.map +0 -1
  794. package/dist/test/shutdown-errors.test.d.ts +0 -2
  795. package/dist/test/shutdown-errors.test.d.ts.map +0 -1
  796. package/dist/test/shutdown-errors.test.js +0 -662
  797. package/dist/test/shutdown-errors.test.js.map +0 -1
  798. package/dist/test/silent-heartbeat-rows.test.d.ts +0 -2
  799. package/dist/test/silent-heartbeat-rows.test.d.ts.map +0 -1
  800. package/dist/test/silent-heartbeat-rows.test.js +0 -451
  801. package/dist/test/silent-heartbeat-rows.test.js.map +0 -1
  802. package/dist/test/silent-heartbeat.test.d.ts +0 -2
  803. package/dist/test/silent-heartbeat.test.d.ts.map +0 -1
  804. package/dist/test/silent-heartbeat.test.js +0 -165
  805. package/dist/test/silent-heartbeat.test.js.map +0 -1
  806. package/dist/test/state-scaling-e2e.test.d.ts +0 -22
  807. package/dist/test/state-scaling-e2e.test.d.ts.map +0 -1
  808. package/dist/test/state-scaling-e2e.test.js +0 -206
  809. package/dist/test/state-scaling-e2e.test.js.map +0 -1
  810. package/dist/test/state-scaling.test.d.ts +0 -12
  811. package/dist/test/state-scaling.test.d.ts.map +0 -1
  812. package/dist/test/state-scaling.test.js +0 -251
  813. package/dist/test/state-scaling.test.js.map +0 -1
  814. package/dist/test/stop-with-work-in-flight.test.d.ts +0 -23
  815. package/dist/test/stop-with-work-in-flight.test.d.ts.map +0 -1
  816. package/dist/test/stop-with-work-in-flight.test.js +0 -672
  817. package/dist/test/stop-with-work-in-flight.test.js.map +0 -1
  818. package/dist/test/surgery-marks-receipt.test.d.ts +0 -2
  819. package/dist/test/surgery-marks-receipt.test.d.ts.map +0 -1
  820. package/dist/test/surgery-marks-receipt.test.js +0 -540
  821. package/dist/test/surgery-marks-receipt.test.js.map +0 -1
  822. package/dist/test/thinking-token-stamp.test.d.ts +0 -12
  823. package/dist/test/thinking-token-stamp.test.d.ts.map +0 -1
  824. package/dist/test/thinking-token-stamp.test.js +0 -129
  825. package/dist/test/thinking-token-stamp.test.js.map +0 -1
  826. package/dist/test/timezone.test.d.ts +0 -2
  827. package/dist/test/timezone.test.d.ts.map +0 -1
  828. package/dist/test/timezone.test.js +0 -18
  829. package/dist/test/timezone.test.js.map +0 -1
  830. package/dist/test/tool-batch-hook.test.d.ts +0 -8
  831. package/dist/test/tool-batch-hook.test.d.ts.map +0 -1
  832. package/dist/test/tool-batch-hook.test.js +0 -275
  833. package/dist/test/tool-batch-hook.test.js.map +0 -1
  834. package/dist/test/tool-policy.test.d.ts +0 -2
  835. package/dist/test/tool-policy.test.d.ts.map +0 -1
  836. package/dist/test/tool-policy.test.js +0 -51
  837. package/dist/test/tool-policy.test.js.map +0 -1
  838. package/dist/test/tool-presentation.test.d.ts +0 -2
  839. package/dist/test/tool-presentation.test.d.ts.map +0 -1
  840. package/dist/test/tool-presentation.test.js +0 -268
  841. package/dist/test/tool-presentation.test.js.map +0 -1
  842. package/dist/test/tool-result-content.test.d.ts +0 -2
  843. package/dist/test/tool-result-content.test.d.ts.map +0 -1
  844. package/dist/test/tool-result-content.test.js +0 -37
  845. package/dist/test/tool-result-content.test.js.map +0 -1
  846. package/dist/test/tool-result-guard.test.d.ts +0 -2
  847. package/dist/test/tool-result-guard.test.d.ts.map +0 -1
  848. package/dist/test/tool-result-guard.test.js +0 -3607
  849. package/dist/test/tool-result-guard.test.js.map +0 -1
  850. package/dist/test/tool-result-history.test.d.ts +0 -7
  851. package/dist/test/tool-result-history.test.d.ts.map +0 -1
  852. package/dist/test/tool-result-history.test.js +0 -156
  853. package/dist/test/tool-result-history.test.js.map +0 -1
  854. package/dist/test/tool-result-spill.test.d.ts +0 -13
  855. package/dist/test/tool-result-spill.test.d.ts.map +0 -1
  856. package/dist/test/tool-result-spill.test.js +0 -586
  857. package/dist/test/tool-result-spill.test.js.map +0 -1
  858. package/dist/test/tool-wrapper-prose-guard-integration.test.d.ts +0 -2
  859. package/dist/test/tool-wrapper-prose-guard-integration.test.d.ts.map +0 -1
  860. package/dist/test/tool-wrapper-prose-guard-integration.test.js +0 -485
  861. package/dist/test/tool-wrapper-prose-guard-integration.test.js.map +0 -1
  862. package/dist/test/tool-wrapper-prose-guard.test.d.ts +0 -2
  863. package/dist/test/tool-wrapper-prose-guard.test.d.ts.map +0 -1
  864. package/dist/test/tool-wrapper-prose-guard.test.js +0 -34
  865. package/dist/test/tool-wrapper-prose-guard.test.js.map +0 -1
  866. package/dist/test/tools-observe-parser-conformance.test.d.ts +0 -2
  867. package/dist/test/tools-observe-parser-conformance.test.d.ts.map +0 -1
  868. package/dist/test/tools-observe-parser-conformance.test.js +0 -129
  869. package/dist/test/tools-observe-parser-conformance.test.js.map +0 -1
  870. package/dist/test/trunk-channel-routing.test.d.ts +0 -19
  871. package/dist/test/trunk-channel-routing.test.d.ts.map +0 -1
  872. package/dist/test/trunk-channel-routing.test.js +0 -329
  873. package/dist/test/trunk-channel-routing.test.js.map +0 -1
  874. package/dist/test/tune-out-e2e.test.d.ts +0 -2
  875. package/dist/test/tune-out-e2e.test.d.ts.map +0 -1
  876. package/dist/test/tune-out-e2e.test.js +0 -142
  877. package/dist/test/tune-out-e2e.test.js.map +0 -1
  878. package/dist/test/tune-out-gate-composition.test.d.ts +0 -2
  879. package/dist/test/tune-out-gate-composition.test.d.ts.map +0 -1
  880. package/dist/test/tune-out-gate-composition.test.js +0 -221
  881. package/dist/test/tune-out-gate-composition.test.js.map +0 -1
  882. package/dist/test/tune-out-lifecycle.test.d.ts +0 -2
  883. package/dist/test/tune-out-lifecycle.test.d.ts.map +0 -1
  884. package/dist/test/tune-out-lifecycle.test.js +0 -121
  885. package/dist/test/tune-out-lifecycle.test.js.map +0 -1
  886. package/dist/test/turn-trigger-provenance.test.d.ts +0 -2
  887. package/dist/test/turn-trigger-provenance.test.d.ts.map +0 -1
  888. package/dist/test/turn-trigger-provenance.test.js +0 -137
  889. package/dist/test/turn-trigger-provenance.test.js.map +0 -1
  890. package/dist/test/unconvertible-tool-result.test.d.ts +0 -2
  891. package/dist/test/unconvertible-tool-result.test.d.ts.map +0 -1
  892. package/dist/test/unconvertible-tool-result.test.js +0 -358
  893. package/dist/test/unconvertible-tool-result.test.js.map +0 -1
  894. package/dist/test/usage-accounting.test.d.ts +0 -2
  895. package/dist/test/usage-accounting.test.d.ts.map +0 -1
  896. package/dist/test/usage-accounting.test.js +0 -13
  897. package/dist/test/usage-accounting.test.js.map +0 -1
  898. package/dist/test/usage-tracker.test.d.ts +0 -2
  899. package/dist/test/usage-tracker.test.d.ts.map +0 -1
  900. package/dist/test/usage-tracker.test.js +0 -129
  901. package/dist/test/usage-tracker.test.js.map +0 -1
  902. package/dist/test/utils-surface.test.d.ts +0 -2
  903. package/dist/test/utils-surface.test.d.ts.map +0 -1
  904. package/dist/test/utils-surface.test.js +0 -145
  905. package/dist/test/utils-surface.test.js.map +0 -1
  906. package/dist/test/workspace-branch-continuation.test.d.ts +0 -15
  907. package/dist/test/workspace-branch-continuation.test.d.ts.map +0 -1
  908. package/dist/test/workspace-branch-continuation.test.js +0 -183
  909. package/dist/test/workspace-branch-continuation.test.js.map +0 -1
  910. package/dist/test/workspace-materialize-freshness.test.d.ts +0 -16
  911. package/dist/test/workspace-materialize-freshness.test.d.ts.map +0 -1
  912. package/dist/test/workspace-materialize-freshness.test.js +0 -252
  913. package/dist/test/workspace-materialize-freshness.test.js.map +0 -1
  914. package/dist/test/workspace-path-containment.test.d.ts +0 -19
  915. package/dist/test/workspace-path-containment.test.d.ts.map +0 -1
  916. package/dist/test/workspace-path-containment.test.js +0 -91
  917. package/dist/test/workspace-path-containment.test.js.map +0 -1
  918. package/dist/test/workspace-read-file-from-disk.test.d.ts +0 -17
  919. package/dist/test/workspace-read-file-from-disk.test.d.ts.map +0 -1
  920. package/dist/test/workspace-read-file-from-disk.test.js +0 -174
  921. package/dist/test/workspace-read-file-from-disk.test.js.map +0 -1
  922. package/dist/test/workspace-read-image.test.d.ts +0 -2
  923. package/dist/test/workspace-read-image.test.d.ts.map +0 -1
  924. package/dist/test/workspace-read-image.test.js +0 -597
  925. package/dist/test/workspace-read-image.test.js.map +0 -1
  926. package/dist/test/workspace-read-text.test.d.ts +0 -2
  927. package/dist/test/workspace-read-text.test.d.ts.map +0 -1
  928. package/dist/test/workspace-read-text.test.js +0 -101
  929. package/dist/test/workspace-read-text.test.js.map +0 -1
  930. package/dist/test/workspace-restore-order.test.d.ts +0 -16
  931. package/dist/test/workspace-restore-order.test.d.ts.map +0 -1
  932. package/dist/test/workspace-restore-order.test.js +0 -140
  933. package/dist/test/workspace-restore-order.test.js.map +0 -1
  934. package/dist/test/workspace-three-way.test.d.ts +0 -12
  935. package/dist/test/workspace-three-way.test.d.ts.map +0 -1
  936. package/dist/test/workspace-three-way.test.js +0 -3194
  937. package/dist/test/workspace-three-way.test.js.map +0 -1
  938. package/dist/test/workspace-watcher.test.d.ts +0 -2
  939. package/dist/test/workspace-watcher.test.d.ts.map +0 -1
  940. package/dist/test/workspace-watcher.test.js +0 -281
  941. package/dist/test/workspace-watcher.test.js.map +0 -1
  942. package/dist/test/xml-round-persist.test.d.ts +0 -19
  943. package/dist/test/xml-round-persist.test.d.ts.map +0 -1
  944. package/dist/test/xml-round-persist.test.js +0 -235
  945. package/dist/test/xml-round-persist.test.js.map +0 -1
  946. package/dist/tsconfig.tsbuildinfo +0 -1
@@ -1,863 +0,0 @@
1
- /**
2
- * Host quiesce/maintenance mode (issue #122) — deterministic state-machine
3
- * coverage. No child processes; the MCPL plane/barrier interplay is covered
4
- * by the awareness-barrier suite.
5
- */
6
- import { test } from 'node:test';
7
- import assert from 'node:assert/strict';
8
- import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
9
- import { spawnSync } from 'node:child_process';
10
- import { fileURLToPath } from 'node:url';
11
- import { tmpdir } from 'node:os';
12
- import { join } from 'node:path';
13
- import { AutobiographicalStrategy } from '@animalabs/context-manager';
14
- import { AgentFramework, ResumeBlockedError } from '../src/index.js';
15
- import { MockMembrane, createMockResponse } from './helpers/mock-membrane.js';
16
- async function waitFor(description, predicate, timeoutMs = 3_000) {
17
- const deadline = Date.now() + timeoutMs;
18
- while (!predicate()) {
19
- if (Date.now() > deadline)
20
- throw new Error(`Timed out waiting for ${description}`);
21
- await new Promise((resolve) => setTimeout(resolve, 25));
22
- }
23
- }
24
- function autobiographical() {
25
- return new AutobiographicalStrategy({
26
- adaptiveResolution: true,
27
- foldingStrategy: 'kv-stable',
28
- recentWindowTokens: 30_000,
29
- kvStableReachTokens: 8_000,
30
- });
31
- }
32
- function stubPreview(framework, agentName, impl) {
33
- const cm = framework.getAgent(agentName).getContextManager();
34
- cm.previewContext = (budget) => impl(budget);
35
- }
36
- async function withFramework(membrane, fn, agentExtras = {}) {
37
- const dir = mkdtempSync(join(tmpdir(), 'host-quiesce-'));
38
- const framework = await AgentFramework.create({
39
- storePath: join(dir, 'store'),
40
- membrane: membrane.asMembrane(),
41
- agents: [{
42
- name: 'agent',
43
- model: 'test-model',
44
- systemPrompt: 'test',
45
- ...agentExtras,
46
- }],
47
- modules: [],
48
- });
49
- try {
50
- await fn(framework, dir);
51
- }
52
- finally {
53
- await framework.stop();
54
- rmSync(dir, { recursive: true, force: true });
55
- }
56
- }
57
- test('quiesce parks wakes; resume releases them', async () => {
58
- const membrane = new MockMembrane();
59
- await withFramework(membrane, async (framework) => {
60
- framework.start();
61
- const before = await framework.quiesce({ reason: 'test window' });
62
- assert.equal(before.quiesced, true);
63
- assert.equal(before.drained, true);
64
- const nudge = framework.nudgeAgent('agent', 'operator');
65
- assert.equal(nudge.ok, true);
66
- // Give the running loop time to (not) start a turn.
67
- await new Promise((resolve) => setTimeout(resolve, 300));
68
- assert.equal(membrane.calls.length, 0, 'no inference while quiesced');
69
- assert.equal(framework.getAgent('agent').state.status, 'idle');
70
- assert.equal(framework.getHostModeStatus().gatedRequests, 1);
71
- const after = await framework.resume();
72
- assert.equal(after.quiesced, false);
73
- await waitFor('parked wake to fire', () => membrane.calls.length > 0);
74
- });
75
- });
76
- test('parked wakes coalesce per (agent, reason), keeping the set bounded', async () => {
77
- const membrane = new MockMembrane();
78
- await withFramework(membrane, async (framework) => {
79
- framework.start();
80
- await framework.quiesce();
81
- for (let i = 0; i < 5; i++)
82
- framework.nudgeAgent('agent', 'operator');
83
- // The loop's next pass compresses same-reason parked requests to one.
84
- await waitFor('coalescing to a single parked request', () => framework.getHostModeStatus().gatedRequests === 1);
85
- await new Promise((resolve) => setTimeout(resolve, 200));
86
- assert.equal(framework.getHostModeStatus().gatedRequests, 1, 'stays bounded');
87
- assert.equal(membrane.calls.length, 0);
88
- });
89
- });
90
- test('coalescing keeps an ADDRESSED wake alive when an ambient one of the same reason parks later', async () => {
91
- // Every channel wake shares one reason; keying the coalescer on reason
92
- // alone let an ambient message parked later evict a DM/mention parked
93
- // earlier — and the resumed turn then answered into the ambient channel.
94
- const membrane = new MockMembrane();
95
- await withFramework(membrane, async (framework) => {
96
- framework.start();
97
- await framework.quiesce();
98
- // Re-read on every access: the scheduler REASSIGNS pendingRequests
99
- // when it takes a batch, so a captured reference goes stale.
100
- const pending = () => framework.pendingRequests;
101
- const t = Date.now();
102
- pending().push({ agentName: 'agent', reason: 'mcpl:channel-incoming', source: 'framework', timestamp: t, addressed: true, channelId: 'dm' }, { agentName: 'agent', reason: 'mcpl:channel-incoming', source: 'framework', timestamp: t + 1, addressed: false, channelId: 'lounge' }, { agentName: 'agent', reason: 'mcpl:channel-incoming', source: 'framework', timestamp: t + 2, addressed: false, channelId: 'lounge' });
103
- await waitFor('scheduler pass to coalesce', () => framework.getHostModeStatus().gatedRequests === 2);
104
- await new Promise((resolve) => setTimeout(resolve, 200));
105
- const survivors = pending().filter((r) => r.reason === 'mcpl:channel-incoming');
106
- assert.equal(survivors.length, 2, 'one addressed + one ambient survive');
107
- assert.ok(survivors.some((r) => r.addressed === true && r.channelId === 'dm'), 'the addressed wake survived');
108
- assert.ok(survivors.some((r) => r.addressed === false), 'the newest ambient wake survived');
109
- assert.equal(membrane.calls.length, 0);
110
- });
111
- });
112
- test('runUntilIdle returns with gated requests parked', async () => {
113
- const membrane = new MockMembrane();
114
- await withFramework(membrane, async (framework) => {
115
- await framework.quiesce();
116
- framework.nudgeAgent('agent', 'operator');
117
- // Must not hang: parked requests are not progress while quiesced.
118
- await framework.runUntilIdle();
119
- assert.equal(membrane.calls.length, 0);
120
- });
121
- });
122
- test('ephemeral admission is refused while quiesced', async () => {
123
- const membrane = new MockMembrane();
124
- await withFramework(membrane, async (framework) => {
125
- await framework.quiesce({ reason: 'surgery' });
126
- await assert.rejects(
127
- // Refused before the agent/CM are touched — a minimal stand-in suffices.
128
- framework.runEphemeralToCompletion({ name: 'ephemeral' }, {}), /quiesced \(surgery\).*resume\(\) first/);
129
- });
130
- });
131
- /** A stream that never completes until cancelled — models a hung provider. */
132
- class HangingStream {
133
- pendingResolve = null;
134
- aborted = false;
135
- cancel() {
136
- this.aborted = true;
137
- this.pendingResolve?.();
138
- }
139
- waitForCancel() {
140
- if (this.aborted)
141
- return Promise.resolve();
142
- return new Promise((resolve) => { this.pendingResolve = resolve; });
143
- }
144
- provideToolResults() { }
145
- get isWaitingForTools() { return false; }
146
- get pendingToolCallIds() { return []; }
147
- get toolDepth() { return 0; }
148
- async *[Symbol.asyncIterator]() {
149
- await this.waitForCancel();
150
- yield { type: 'aborted', reason: 'user' };
151
- }
152
- }
153
- class HangingMembrane extends MockMembrane {
154
- streamYielding(request) {
155
- this.calls.push(request);
156
- return new HangingStream();
157
- }
158
- }
159
- test('drain waits for an in-flight turn; abandon cancels without failure accounting', async () => {
160
- const membrane = new HangingMembrane();
161
- await withFramework(membrane, async (framework) => {
162
- const traces = [];
163
- framework.onTrace((event) => traces.push(event));
164
- framework.start();
165
- framework.nudgeAgent('agent', 'operator');
166
- await waitFor('turn to start', () => membrane.calls.length === 1);
167
- const status = await framework.quiesce({ timeoutMs: 1_000, abandon: true });
168
- assert.equal(status.quiesced, true);
169
- assert.equal(status.drained, true, 'abandon settles the hung turn');
170
- await waitFor('agent back to idle', () => framework.getAgent('agent').state.status === 'idle');
171
- assert.ok(traces.some((t) => t.type === 'inference:aborted'
172
- && t.reason === 'quiesce_abandoned'), 'abandon is traced as an operator abort');
173
- assert.ok(!traces.some((t) => t.type === 'inference:exhausted'), 'an operator cancel must not feed the failure streak / hard-down accounting');
174
- const quiesceTrace = traces.find((t) => t.type === 'host:quiesce');
175
- assert.equal(quiesceTrace?.abandoned, true);
176
- });
177
- });
178
- test('quiesce persists across restart; resume clears it durably', async () => {
179
- const dir = mkdtempSync(join(tmpdir(), 'host-quiesce-persist-'));
180
- const storePath = join(dir, 'store');
181
- const config = () => ({
182
- storePath,
183
- membrane: new MockMembrane().asMembrane(),
184
- agents: [{ name: 'agent', model: 'test-model', systemPrompt: 'test' }],
185
- modules: [],
186
- });
187
- let framework = await AgentFramework.create(config());
188
- try {
189
- await framework.quiesce({ reason: 'refold in progress' });
190
- await framework.stop();
191
- framework = await AgentFramework.create(config());
192
- const restored = framework.getHostModeStatus();
193
- assert.equal(restored.quiesced, true, 'a restart mid-surgery boots quiesced');
194
- assert.equal(restored.reason, 'refold in progress');
195
- await framework.resume();
196
- await framework.stop();
197
- framework = await AgentFramework.create(config());
198
- assert.equal(framework.getHostModeStatus().quiesced, false);
199
- }
200
- finally {
201
- await framework.stop();
202
- rmSync(dir, { recursive: true, force: true });
203
- }
204
- });
205
- test('resume gates on a fresh feasibility verdict; force overrides', async () => {
206
- const membrane = new MockMembrane();
207
- await withFramework(membrane, async (framework) => {
208
- await framework.quiesce();
209
- stubPreview(framework, 'agent', (budget) => ({
210
- finalTokens: 450_000,
211
- budgetTokens: budget.maxTokens,
212
- fits: false,
213
- exhausted: true,
214
- headTokens: 1,
215
- tailTokens: 2,
216
- middleTokens: 3,
217
- middleChunkCount: 1,
218
- deepestLevel: 3,
219
- resolutions: {},
220
- moves: 0,
221
- producedCount: 0,
222
- }));
223
- await assert.rejects(framework.resume(), (error) => {
224
- assert.ok(error instanceof ResumeBlockedError);
225
- assert.equal(error.verdicts.length, 1);
226
- assert.equal(error.verdicts[0].agentName, 'agent');
227
- assert.match(error.message, /folded floor 450000/);
228
- return true;
229
- });
230
- assert.equal(framework.getHostModeStatus().quiesced, true, 'still quiesced after refusal');
231
- const forced = await framework.resume({ force: true });
232
- assert.equal(forced.quiesced, false);
233
- }, {
234
- strategy: autobiographical(),
235
- contextBudgetTokens: 300_000,
236
- maxTokens: 10_000,
237
- });
238
- });
239
- test('resume proceeds with a warn when the strategy cannot preview', async () => {
240
- const membrane = new MockMembrane();
241
- await withFramework(membrane, async (framework) => {
242
- // Default PassthroughStrategy: no previewContext at all.
243
- await framework.quiesce();
244
- const status = await framework.resume();
245
- assert.equal(status.quiesced, false);
246
- });
247
- });
248
- test('maintenanceTick runs the real maintenance pass while quiesced', async () => {
249
- class QueuedStrategy {
250
- name = 'queued-test';
251
- ticks = 0;
252
- checkReadiness() {
253
- return { ready: this.ticks >= 2, description: 'test maintenance queued' };
254
- }
255
- async tick(_ctx) {
256
- this.ticks++;
257
- }
258
- select(_store, _log, _budget) {
259
- return [];
260
- }
261
- }
262
- const strategy = new QueuedStrategy();
263
- const membrane = new MockMembrane();
264
- await withFramework(membrane, async (framework) => {
265
- framework.start();
266
- await framework.quiesce({ reason: 'compression window' });
267
- const snapshot = await framework.maintenanceTick();
268
- assert.ok(strategy.ticks >= 2, `maintenance ticked while quiesced (${strategy.ticks})`);
269
- assert.ok(snapshot.agents.some((a) => a.agentName === 'agent'));
270
- }, { strategy });
271
- });
272
- // ---------------------------------------------------------------------------
273
- // End-to-end MCPL leg: data plane held while quiesced, resume deliverable
274
- // over host/command (control plane), funnel reopens and flushes the backlog.
275
- // ---------------------------------------------------------------------------
276
- const QUIESCE_STDIO_SERVER = `
277
- const fs = require('node:fs');
278
- const statusPath = process.env.STATUS_PATH;
279
- const pushPath = process.env.PUSH_PATH;
280
- const resumePath = process.env.RESUME_PATH;
281
- const log = (event, extra) =>
282
- fs.appendFileSync(statusPath, JSON.stringify({ event, ...extra }) + '\\n');
283
- let buf = '';
284
- let pushSent = false;
285
- let resumeSent = false;
286
- process.stdin.on('data', (c) => {
287
- buf += c.toString('utf8');
288
- let i;
289
- while ((i = buf.indexOf('\\n')) >= 0) {
290
- const line = buf.slice(0, i); buf = buf.slice(i + 1);
291
- if (!line.trim()) continue;
292
- let m; try { m = JSON.parse(line); } catch { continue; }
293
- const reply = (result) => process.stdout.write(JSON.stringify({ jsonrpc: '2.0', id: m.id, result }) + '\\n');
294
- if (m.method === 'initialize') reply({ capabilities: { experimental: { mcpl: { version: '0.4', pushEvents: true } } } });
295
- else if (m.method === 'tools/list') reply({ tools: [] });
296
- else if (m.id === 900) log('push-response', { error: m.error ?? null });
297
- else if (m.id === 901) log('resume-response', { result: m.result ?? null, error: m.error ?? null });
298
- }
299
- });
300
- setInterval(() => {
301
- if (!pushSent && fs.existsSync(pushPath)) {
302
- pushSent = true;
303
- process.stdout.write(JSON.stringify({ jsonrpc: '2.0', id: 900, method: 'push/event', params: {
304
- featureSet: 'chat', eventId: 'quiesce-push', timestamp: new Date().toISOString(),
305
- payload: { content: [{ type: 'text', text: 'held while quiesced' }] },
306
- } }) + '\\n');
307
- log('push-sent');
308
- }
309
- if (!resumeSent && fs.existsSync(resumePath)) {
310
- resumeSent = true;
311
- process.stdout.write(JSON.stringify({ jsonrpc: '2.0', id: 901, method: 'host/command', params: {
312
- command: 'resume', requesterName: 'test-operator',
313
- } }) + '\\n');
314
- log('resume-sent');
315
- }
316
- }, 25);
317
- `;
318
- test('MCPL: pushes buffer while quiesced; host/command resume reopens and flushes', async () => {
319
- const { writeFileSync, readFileSync, existsSync } = await import('node:fs');
320
- const dir = mkdtempSync(join(tmpdir(), 'host-quiesce-mcpl-'));
321
- const statusPath = join(dir, 'status.jsonl');
322
- const pushPath = join(dir, 'push');
323
- const resumePath = join(dir, 'resume');
324
- const records = () => existsSync(statusPath)
325
- ? readFileSync(statusPath, 'utf8').trim().split('\n').filter(Boolean).map((l) => JSON.parse(l))
326
- : [];
327
- const membrane = new MockMembrane();
328
- const framework = await AgentFramework.create({
329
- storePath: join(dir, 'store'),
330
- membrane: membrane.asMembrane(),
331
- agents: [{ name: 'assistant', model: 'test-model', systemPrompt: 'test' }],
332
- modules: [],
333
- mcplServers: [{
334
- id: 'pusher',
335
- command: process.execPath,
336
- args: ['-e', QUIESCE_STDIO_SERVER],
337
- allowHostCommands: true,
338
- env: { STATUS_PATH: statusPath, PUSH_PATH: pushPath, RESUME_PATH: resumePath },
339
- }],
340
- });
341
- try {
342
- framework.start();
343
- await framework.quiesce({ reason: 'mcpl leg' });
344
- writeFileSync(pushPath, 'go');
345
- await waitFor('push sent by server', () => records().some((r) => r.event === 'push-sent'));
346
- await new Promise((resolve) => setTimeout(resolve, 400));
347
- assert.ok(!records().some((r) => r.event === 'push-response'), 'push must buffer on the paused data plane — no response while quiesced');
348
- assert.equal(membrane.calls.length, 0, 'no wake while quiesced');
349
- // Resume arrives OVER MCPL: host/command rides the control plane, so it
350
- // is deliverable through the very pause it lifts.
351
- writeFileSync(resumePath, 'go');
352
- await waitFor('resume handled via host/command', () => records().some((r) => r.event === 'resume-response'
353
- && r.result?.ok === true));
354
- assert.equal(framework.getHostModeStatus().quiesced, false);
355
- await waitFor('buffered push flushed after resume', () => records().some((r) => r.event === 'push-response'));
356
- }
357
- finally {
358
- await framework.stop();
359
- rmSync(dir, { recursive: true, force: true });
360
- }
361
- });
362
- // ---------------------------------------------------------------------------
363
- // Review-fix regressions (code review 08-21)
364
- // ---------------------------------------------------------------------------
365
- /** A membrane whose stream sleeps before producing its response — a turn
366
- * that settles on its own after `delayMs`, so a drain window's real length
367
- * becomes observable: a collapsed window returns undrained immediately, a
368
- * sane one waits for the turn. */
369
- class DelayedMembrane extends MockMembrane {
370
- delayMs;
371
- constructor(delayMs) {
372
- super();
373
- this.delayMs = delayMs;
374
- }
375
- streamYielding(request, options) {
376
- const inner = super.streamYielding(request, options);
377
- const delayMs = this.delayMs;
378
- return {
379
- cancel: () => inner.cancel(),
380
- provideToolResults: (...args) => inner.provideToolResults(...args),
381
- get isWaitingForTools() { return inner.isWaitingForTools; },
382
- get pendingToolCallIds() { return inner.pendingToolCallIds; },
383
- get toolDepth() { return inner.toolDepth; },
384
- async *[Symbol.asyncIterator]() {
385
- await new Promise((resolve) => setTimeout(resolve, delayMs));
386
- yield* inner;
387
- },
388
- };
389
- }
390
- }
391
- test('a non-finite timeoutMs falls back to the default drain window, never NaN-collapses', async () => {
392
- // NaN reached quiesce() via Number('12O000') on the HTTP ingress. With the
393
- // old Math.max(1_000, NaN) the deadline was NaN and the drain window
394
- // collapsed to zero. Discriminating observable: a turn that settles after
395
- // 600ms is drained by a sane window and NOT by a collapsed one.
396
- const membrane = new DelayedMembrane(600);
397
- membrane.pushResponse(createMockResponse([{ type: 'text', text: 'late' }]));
398
- await withFramework(membrane, async (framework) => {
399
- framework.start();
400
- framework.nudgeAgent('agent', 'operator');
401
- await waitFor('turn to start', () => membrane.calls.length === 1);
402
- const started = Date.now();
403
- const status = await framework.quiesce({ timeoutMs: Number('12O000') });
404
- assert.equal(status.quiesced, true);
405
- assert.equal(status.drained, true, 'the window waited for the turn');
406
- assert.ok(Date.now() - started >= 400, 'quiesce actually waited');
407
- });
408
- });
409
- test('timeoutMs is clamped inside quiesce() — a sub-second value still drains a short turn', async () => {
410
- const membrane = new DelayedMembrane(600);
411
- membrane.pushResponse(createMockResponse([{ type: 'text', text: 'late' }]));
412
- await withFramework(membrane, async (framework) => {
413
- framework.start();
414
- framework.nudgeAgent('agent', 'operator');
415
- await waitFor('turn to start', () => membrane.calls.length === 1);
416
- // 1ms honoured literally would return undrained; the [1s, 10m] floor
417
- // (now inside quiesce(), shared by WS/HTTP/host-command) waits it out.
418
- const status = await framework.quiesce({ timeoutMs: 1 });
419
- assert.equal(status.drained, true);
420
- assert.equal(AgentFramework.QUIESCE_TIMEOUT_MAX_MS, 600_000);
421
- });
422
- });
423
- test('a concurrent resume() supersedes a draining quiesce: no abandon, no stale trace', async () => {
424
- const membrane = new HangingMembrane();
425
- await withFramework(membrane, async (framework) => {
426
- const traces = [];
427
- framework.onTrace((event) => traces.push(event));
428
- framework.start();
429
- framework.nudgeAgent('agent', 'operator');
430
- await waitFor('turn to start', () => membrane.calls.length === 1);
431
- const pending = framework.quiesce({ timeoutMs: 5_000, abandon: true });
432
- await new Promise((resolve) => setTimeout(resolve, 400));
433
- assert.equal(framework.getHostModeStatus().quiesced, true, 'draining');
434
- await framework.resume();
435
- const status = await pending;
436
- assert.equal(status.quiesced, false, 'the superseded quiesce reports the live mode');
437
- assert.ok(!traces.some((t) => t.type === 'inference:aborted'), 'the turn that outlived the window was NOT abandoned after the resume');
438
- assert.ok(!traces.some((t) => t.type === 'host:quiesce'), 'no stale host:quiesce trace');
439
- // Release the hung turn so teardown is clean.
440
- framework.getAgent('agent').cancelStream();
441
- await waitFor('agent idle', () => framework.getAgent('agent').state.status === 'idle');
442
- });
443
- });
444
- test('abandon reports turns it cannot cancel (token held, no stream)', async () => {
445
- const membrane = new MockMembrane();
446
- await withFramework(membrane, async (framework) => {
447
- const traces = [];
448
- framework.onTrace((event) => traces.push(event));
449
- // A turn between dequeue and stream registration: token held, agent idle.
450
- const tokens = framework.activeTurnTokens;
451
- tokens.set('agent', {});
452
- try {
453
- const status = await framework.quiesce({ timeoutMs: 1_000, abandon: true });
454
- assert.equal(status.drained, false);
455
- assert.deepEqual(status.unabandonable, ['agent']);
456
- const trace = traces.find((t) => t.type === 'host:quiesce');
457
- assert.deepEqual(trace?.unabandonable, ['agent']);
458
- assert.equal(membrane.calls.length, 0, 'nothing was cancelled or started');
459
- }
460
- finally {
461
- tokens.delete('agent');
462
- }
463
- });
464
- });
465
- test('a cancel that surfaces as a stream ERROR still settles as an operator abort', async () => {
466
- // Some stream implementations report cancellation through the error
467
- // branch rather than `aborted`; the quiesce_abandoned contract must hold
468
- // on both: no exhausted accounting, lifecycle 'aborted', agent back idle.
469
- class ErroringHangStream extends HangingStream {
470
- async *[Symbol.asyncIterator]() {
471
- await this.waitForCancel();
472
- yield { type: 'error', error: new Error('stream cancelled') };
473
- }
474
- }
475
- class ErroringMembrane extends MockMembrane {
476
- streamYielding(request) {
477
- this.calls.push(request);
478
- return new ErroringHangStream();
479
- }
480
- }
481
- const membrane = new ErroringMembrane();
482
- await withFramework(membrane, async (framework) => {
483
- const traces = [];
484
- framework.onTrace((event) => traces.push(event));
485
- framework.start();
486
- framework.nudgeAgent('agent', 'operator');
487
- await waitFor('turn to start', () => membrane.calls.length === 1);
488
- const status = await framework.quiesce({ timeoutMs: 1_000, abandon: true });
489
- assert.equal(status.drained, true);
490
- await waitFor('agent back to idle', () => framework.getAgent('agent').state.status === 'idle');
491
- assert.ok(traces.some((t) => t.type === 'inference:aborted'
492
- && t.reason === 'quiesce_abandoned'));
493
- assert.ok(!traces.some((t) => t.type === 'inference:exhausted'));
494
- const lifecycle = traces
495
- .filter((t) => String(t.type).includes('lifecycle'))
496
- .map((t) => t.phase);
497
- if (lifecycle.length > 0)
498
- assert.ok(!lifecycle.includes('completed'), 'an abandoned turn is not "completed"');
499
- });
500
- });
501
- test('abandon can escalate an already-quiesced, undrained host', async () => {
502
- class HangingStream {
503
- pendingResolve = null;
504
- aborted = false;
505
- cancel() { this.aborted = true; this.pendingResolve?.(); }
506
- provideToolResults() { }
507
- get isWaitingForTools() { return false; }
508
- get pendingToolCallIds() { return []; }
509
- get toolDepth() { return 0; }
510
- async *[Symbol.asyncIterator]() {
511
- if (!this.aborted) {
512
- await new Promise((resolve) => { this.pendingResolve = resolve; });
513
- }
514
- yield { type: 'aborted', reason: 'user' };
515
- }
516
- }
517
- class HangingMembrane extends MockMembrane {
518
- streamYielding(request) {
519
- this.calls.push(request);
520
- return new HangingStream();
521
- }
522
- }
523
- const membrane = new HangingMembrane();
524
- await withFramework(membrane, async (framework) => {
525
- framework.start();
526
- framework.nudgeAgent('agent', 'operator');
527
- await waitFor('turn to start', () => membrane.calls.length === 1);
528
- const first = await framework.quiesce({ timeoutMs: 1_000 });
529
- assert.equal(first.drained, false, 'hung turn survives the first window');
530
- // Old behavior: `if (this.quiesced) return status` made this a no-op and
531
- // the only way out was resume()+re-quiesce, reopening planes mid-surgery.
532
- const second = await framework.quiesce({ abandon: true });
533
- assert.equal(second.drained, true, 'second quiesce escalates to abandon');
534
- });
535
- });
536
- test('context writes are deferred while quiesced and flushed by resume', async () => {
537
- const membrane = new MockMembrane();
538
- await withFramework(membrane, async (framework) => {
539
- await framework.quiesce({ reason: 'refold' });
540
- const cm = framework.getAgent('agent').getContextManager();
541
- const before = cm.getAllMessages().length;
542
- // Module events / api message.send route through framework.addMessage
543
- // (private — invoked here the way handleProcessEvent invokes it).
544
- framework.addMessage('user', [{ type: 'text', text: 'mid-surgery message' }]);
545
- assert.equal(cm.getAllMessages().length, before, 'no context append while the window is open');
546
- await framework.resume();
547
- assert.equal(cm.getAllMessages().length, before + 1, 'the deferred write lands at resume');
548
- });
549
- });
550
- test('a batch carrying a budget restart re-parks its sibling wakes instead of consuming them', async () => {
551
- const membrane = new MockMembrane();
552
- // The restart's continuation round needs a response to complete on — an
553
- // empty mock stream yields no `complete` and the agent never leaves
554
- // `streaming`, which reads as a scheduler hang rather than a re-park bug.
555
- membrane.pushResponse(createMockResponse([{ type: 'text', text: 'restart round' }]));
556
- await withFramework(membrane, async (framework) => {
557
- await framework.quiesce();
558
- // A parked wake exists...
559
- framework.nudgeAgent('agent', 'operator');
560
- // ...and a budget restart lands in the same pendingRequests batch.
561
- framework.pendingRequests.push({
562
- agentName: 'agent',
563
- reason: 'context_budget_restart',
564
- source: 'framework',
565
- timestamp: Date.now(),
566
- });
567
- // Drive one scheduler pass: the restart starts its continuation turn, but
568
- // the nudge must survive as a parked request rather than being consumed
569
- // by it — exactly one provider call, and the survivor IS the nudge.
570
- await framework.runUntilIdle();
571
- await waitFor('sibling wake re-parked', () => framework.getHostModeStatus().gatedRequests >= 1);
572
- assert.equal(membrane.calls.length, 1, 'only the restart ran');
573
- const parked = framework.pendingRequests;
574
- assert.ok(parked.some((r) => r.reason.startsWith('admin-nudge')), 'the parked survivor is the nudge');
575
- assert.ok(!parked.some((r) => r.reason === 'context_budget_restart'), 'the restart was consumed');
576
- });
577
- });
578
- test('resume flushes deferred writes per message: one poison write neither drops the rest nor skips the reopen', async () => {
579
- const membrane = new MockMembrane();
580
- await withFramework(membrane, async (framework) => {
581
- const traces = [];
582
- framework.onTrace((event) => traces.push(event));
583
- await framework.quiesce({ reason: 'refold' });
584
- const agent = framework.getAgent('agent');
585
- const cm = agent.getContextManager();
586
- const before = cm.getAllMessages().length;
587
- const add = framework.addMessage.bind(framework);
588
- add('user', [{ type: 'text', text: 'first' }]);
589
- add('user', [{ type: 'text', text: 'poison' }]);
590
- add('user', [{ type: 'text', text: 'third' }]);
591
- assert.equal(framework.getHostModeStatus().deferredWrites, 3);
592
- const realAdd = cm.addMessage.bind(cm);
593
- cm.addMessage = ((participant, content, metadata, causedBy) => {
594
- const text = content[0].text;
595
- if (text === 'poison')
596
- throw new Error('store write failed');
597
- return realAdd(participant, content, metadata, causedBy);
598
- });
599
- const status = await framework.resume();
600
- assert.equal(status.quiesced, false);
601
- assert.equal(status.deferredWrites, 0, 'the queue is drained even though one write failed');
602
- assert.deepEqual(cm.getAllMessages().slice(before).map((m) => m.content[0].text), ['first', 'third'], 'the writes behind the poison one still landed');
603
- assert.ok(traces.some((t) => t.type === 'host:resume'), 'resume completed its follow-through');
604
- });
605
- });
606
- test('context writes deferred while quiesced survive a restart and land at resume', async () => {
607
- const dir = mkdtempSync(join(tmpdir(), 'host-quiesce-deferred-'));
608
- const storePath = join(dir, 'store');
609
- const config = () => ({
610
- storePath,
611
- membrane: new MockMembrane().asMembrane(),
612
- agents: [{ name: 'agent', model: 'test-model', systemPrompt: 'test' }],
613
- modules: [],
614
- });
615
- let framework = await AgentFramework.create(config());
616
- try {
617
- await framework.quiesce({ reason: 'surgery' });
618
- const before = framework.getAgent('agent').getContextManager().getAllMessages().length;
619
- framework
620
- .addMessage('user', [{ type: 'text', text: 'said during surgery' }]);
621
- assert.equal(framework.getHostModeStatus().deferredWrites, 1);
622
- await framework.stop(); // crash-equivalent: the queue was in memory
623
- framework = await AgentFramework.create(config());
624
- assert.equal(framework.getHostModeStatus().quiesced, true);
625
- assert.equal(framework.getHostModeStatus().deferredWrites, 1, 'restored from the store');
626
- await framework.resume();
627
- const cm = framework.getAgent('agent').getContextManager();
628
- const texts = cm.getAllMessages().slice(before).map((m) => m.content[0].text);
629
- assert.deepEqual(texts, ['said during surgery']);
630
- assert.equal(framework.getHostModeStatus().deferredWrites, 0);
631
- await framework.stop();
632
- framework = await AgentFramework.create(config());
633
- assert.equal(framework.getHostModeStatus().deferredWrites, 0, 'slot cleared after the flush');
634
- }
635
- finally {
636
- await framework.stop();
637
- rmSync(dir, { recursive: true, force: true });
638
- }
639
- });
640
- // ---------------------------------------------------------------------------
641
- // Review round 2 (antra-tess): admission bypass, branch-independent
642
- // persistence, crash-safe resume flush.
643
- // ---------------------------------------------------------------------------
644
- test('a wake parked on provider admission does not start after quiesce; it runs at resume', async () => {
645
- const membrane = new MockMembrane();
646
- membrane.pushResponse(createMockResponse([{ type: 'text', text: 'after resume' }]));
647
- await withFramework(membrane, async (framework) => {
648
- framework.start();
649
- const internals = framework;
650
- // Hold an auxiliary (compression-style) provider call in flight.
651
- let releaseAux;
652
- const auxDone = internals.withAuxiliaryAdmission('agent', () => new Promise((resolve) => { releaseAux = resolve; }));
653
- await waitFor('auxiliary in flight', () => true);
654
- // A wake passes the scheduler and parks behind the auxiliary: it owns
655
- // provider admission but no turn token yet.
656
- framework.nudgeAgent('agent', 'operator');
657
- await internals.processInferenceRequests();
658
- assert.equal(internals.providerGates.get('agent')?.primaryDepth, 1, 'admission owned');
659
- assert.equal(internals.activeTurnTokens.size, 0, 'no turn token yet');
660
- // Quiesce with a short window: the parked admission is NOT drained.
661
- const status = await framework.quiesce({ reason: 'surgery', timeoutMs: 1_000 });
662
- assert.equal(status.quiesced, true);
663
- assert.equal(status.parkedAdmissions, 1, 'status reports the parked wake');
664
- assert.equal(status.drained, false, 'a parked admission is not "drained"');
665
- // Release the auxiliary: before the fix this started a turn while quiesced.
666
- releaseAux();
667
- await auxDone;
668
- await waitFor('admission released', () => (internals.providerGates.get('agent')?.primaryDepth ?? 0) === 0);
669
- await new Promise((resolve) => setTimeout(resolve, 100));
670
- assert.equal(membrane.calls.length, 0, 'NO inference while quiesced');
671
- assert.equal(framework.getHostModeStatus().quiesced, true);
672
- assert.ok(framework.getHostModeStatus().gatedRequests >= 1, 'the wake was requeued, not dropped');
673
- assert.equal(framework.getHostModeStatus().drained, true, 'drained once the admission was given back');
674
- await framework.resume();
675
- await waitFor('requeued wake to run after resume', () => membrane.calls.length === 1);
676
- });
677
- });
678
- test('quiesce survives a historical rollback + restart (host mode lives outside branch history)', async () => {
679
- const dir = mkdtempSync(join(tmpdir(), 'host-quiesce-rollback-'));
680
- const storePath = join(dir, 'store');
681
- const config = () => ({
682
- storePath,
683
- membrane: new MockMembrane().asMembrane(),
684
- agents: [{ name: 'agent', model: 'test-model', systemPrompt: 'test' }],
685
- modules: [],
686
- });
687
- let framework = await AgentFramework.create(config());
688
- try {
689
- const cm = framework.getAgent('agent').getContextManager();
690
- const checkpoint = cm.addMessage('user', [{ type: 'text', text: 'checkpoint' }]);
691
- cm.addMessage('user', [{ type: 'text', text: 'later' }]);
692
- await framework.quiesce({ reason: 'refold' });
693
- framework
694
- .addMessage('user', [{ type: 'text', text: 'deferred during surgery' }]);
695
- assert.equal(framework.getHostModeStatus().deferredWrites, 1);
696
- // The surgery itself: time-travel to before the quiesce marker was written.
697
- const branch = cm.branchAt(checkpoint, 'rollback/agent/test');
698
- await cm.switchBranch(branch);
699
- assert.equal(framework.getHostModeStatus().quiesced, true, 'live flag unaffected');
700
- assert.equal(existsSync(join(storePath, 'recovery', 'host-mode.json')), true, 'marker is a recovery file');
701
- await framework.stop();
702
- framework = await AgentFramework.create(config());
703
- const booted = framework.getHostModeStatus();
704
- assert.equal(booted.quiesced, true, 'a restart after a rollback still boots quiesced');
705
- assert.equal(booted.reason, 'refold');
706
- assert.equal(booted.deferredWrites, 1, 'deferred writes were not orphaned by the rollback either');
707
- assert.equal(framework.getAgent('agent').getContextManager().currentBranch().name, 'rollback/agent/test');
708
- await framework.resume();
709
- assert.equal(framework.getHostModeStatus().quiesced, false);
710
- const texts = framework.getAgent('agent').getContextManager().getAllMessages()
711
- .map((m) => m.content[0].text);
712
- assert.deepEqual(texts.slice(-2), ['checkpoint', 'deferred during surgery']);
713
- await framework.stop();
714
- framework = await AgentFramework.create(config());
715
- assert.equal(framework.getHostModeStatus().quiesced, false, 'resume cleared the recovery file durably');
716
- }
717
- finally {
718
- await framework.stop();
719
- rmSync(dir, { recursive: true, force: true });
720
- }
721
- });
722
- test('a failed chronicle sync keeps flushed deferred writes in the durable queue until a sync succeeds', async () => {
723
- const dir = mkdtempSync(join(tmpdir(), 'host-quiesce-syncfail-'));
724
- const storePath = join(dir, 'store');
725
- const config = () => ({
726
- storePath,
727
- membrane: new MockMembrane().asMembrane(),
728
- agents: [{ name: 'agent', model: 'test-model', systemPrompt: 'test' }],
729
- modules: [],
730
- });
731
- let framework = await AgentFramework.create(config());
732
- try {
733
- await framework.quiesce({ reason: 'surgery' });
734
- const before = framework.getAgent('agent').getContextManager().getMessageCount();
735
- const add = framework.addMessage.bind(framework);
736
- add('user', [{ type: 'text', text: 'one' }]);
737
- add('user', [{ type: 'text', text: 'two' }]);
738
- const queuePath = join(storePath, 'recovery', 'deferred-writes.json');
739
- const pending = () => JSON.parse(readFileSync(queuePath, 'utf8')).pending.length;
740
- assert.equal(pending(), 2);
741
- // Every sync during resume fails: the messages are appended in memory
742
- // but must NOT be acknowledged — the durable queue keeps both.
743
- const store = framework.store;
744
- const realSync = store.sync.bind(store);
745
- store.sync = () => { throw new Error('disk full'); };
746
- await framework.resume();
747
- assert.deepEqual(framework.getAgent('agent').getContextManager().getAllMessages().slice(before)
748
- .map((m) => m.content[0].text), ['one', 'two'], 'landed in memory');
749
- assert.equal(framework.getHostModeStatus().deferredWrites, 0, 'nothing left pending in memory');
750
- assert.equal(pending(), 2, 'durable queue still lists both — not acked without a sync');
751
- // Sync works again: stop() acks (sync, then rewrite the queue).
752
- store.sync = realSync;
753
- await framework.stop();
754
- assert.equal(pending(), 0, 'acked once the chronicle state was durable');
755
- framework = await AgentFramework.create(config());
756
- assert.equal(framework.getHostModeStatus().deferredWrites, 0);
757
- assert.deepEqual(framework.getAgent('agent').getContextManager().getAllMessages().slice(before)
758
- .map((m) => m.content[0].text), ['one', 'two'], 'exactly once after reopen');
759
- }
760
- finally {
761
- await framework.stop();
762
- rmSync(dir, { recursive: true, force: true });
763
- }
764
- });
765
- const CRASH_CHILD = fileURLToPath(new URL('./helpers/quiesce-crash-child.js', import.meta.url));
766
- const CRASH_SCENARIOS = [
767
- { mode: 'after-ack', label: 'right after the first ack of the resume flush',
768
- expect: ['ACKED-BUT-NOT-SYNCED', 'STILL-PENDING'], bootQuiesced: true },
769
- { mode: 'before-sync', label: 'before the chronicle sync of the resume flush',
770
- expect: ['ACKED-BUT-NOT-SYNCED', 'STILL-PENDING'], bootQuiesced: true },
771
- { mode: 'turn-start-ack', label: "after an ORDINARY turn-start flush's sync but before its queue rewrite",
772
- expect: ['ONCE-ONLY'], bootQuiesced: false },
773
- { mode: 'redefer', label: "at the first re-deferral write of a two-message batch (abandoned turn's teardown while quiesced)",
774
- expect: ['REDEFER-FIRST', 'REDEFER-SECOND'], bootQuiesced: true },
775
- { mode: 'big-batch', label: 'after a 2,101-message resume batch was synced but before it was acked',
776
- expect: Array.from({ length: 2_101 }, (_, i) => `BIG-${i}`), bootQuiesced: true },
777
- ];
778
- for (const scenario of CRASH_SCENARIOS) {
779
- test(`a REAL process exit ${scenario.label} loses no deferred write and duplicates none`, async () => {
780
- const dir = mkdtempSync(join(tmpdir(), `host-quiesce-crash-${scenario.mode}-`));
781
- const storePath = join(dir, 'store');
782
- const config = () => ({
783
- storePath,
784
- membrane: new MockMembrane().asMembrane(),
785
- agents: [{ name: 'agent', model: 'test-model', systemPrompt: 'test' }],
786
- modules: [],
787
- });
788
- let framework = null;
789
- try {
790
- const child = spawnSync(process.execPath, [CRASH_CHILD, storePath, scenario.mode], {
791
- encoding: 'utf8',
792
- timeout: 60_000,
793
- });
794
- assert.equal(child.status, 0, `child staged the crash (stderr: ${child.stderr.slice(-800)})`);
795
- const wanted = new Set(scenario.expect);
796
- const texts = () => framework.getAgent('agent').getContextManager().getAllMessages()
797
- .map((m) => m.content[0].text)
798
- .filter((t) => wanted.has(t));
799
- framework = await AgentFramework.create(config());
800
- const booted = framework.getHostModeStatus();
801
- assert.equal(booted.quiesced, scenario.bootQuiesced);
802
- if (booted.quiesced)
803
- await framework.resume();
804
- assert.deepEqual(texts(), [...scenario.expect], 'present exactly once, in order');
805
- assert.equal(framework.getHostModeStatus().deferredWrites, 0);
806
- await framework.stop();
807
- framework = await AgentFramework.create(config());
808
- assert.equal(framework.getHostModeStatus().quiesced, false);
809
- assert.equal(framework.getHostModeStatus().deferredWrites, 0);
810
- assert.deepEqual(texts(), [...scenario.expect], 'still exactly once after a second reopen');
811
- }
812
- finally {
813
- await framework?.stop();
814
- rmSync(dir, { recursive: true, force: true });
815
- }
816
- });
817
- }
818
- test('a serving boot recovers a stranded deferred-write queue regardless of the mode flag', async () => {
819
- const dir = mkdtempSync(join(tmpdir(), 'host-quiesce-stranded-'));
820
- const storePath = join(dir, 'store');
821
- const config = () => ({
822
- storePath,
823
- membrane: new MockMembrane().asMembrane(),
824
- agents: [{ name: 'agent', model: 'test-model', systemPrompt: 'test' }],
825
- modules: [],
826
- });
827
- let framework = await AgentFramework.create(config());
828
- let before;
829
- try {
830
- before = framework.getAgent('agent').getContextManager().getMessageCount();
831
- await framework.stop();
832
- // The state an older build could leave behind: flag cleared, queue not.
833
- mkdirSync(join(storePath, 'recovery'), { recursive: true });
834
- writeFileSync(join(storePath, 'recovery', 'host-mode.json'), JSON.stringify({ version: 1, quiesced: false }));
835
- writeFileSync(join(storePath, 'recovery', 'deferred-writes.json'), JSON.stringify({
836
- version: 1,
837
- pending: [{ id: 'stranded-1', participant: 'user', content: [{ type: 'text', text: 'stranded' }] }],
838
- }));
839
- framework = await AgentFramework.create(config());
840
- assert.equal(framework.getHostModeStatus().quiesced, false);
841
- assert.equal(framework.getHostModeStatus().deferredWrites, 0, 'recovered at boot');
842
- const texts = framework.getAgent('agent').getContextManager().getAllMessages().slice(before)
843
- .map((m) => m.content[0].text);
844
- assert.deepEqual(texts, ['stranded']);
845
- const queue = JSON.parse(readFileSync(join(storePath, 'recovery', 'deferred-writes.json'), 'utf8'));
846
- assert.equal(queue.pending.length, 0, 'acked durably');
847
- }
848
- finally {
849
- await framework.stop();
850
- rmSync(dir, { recursive: true, force: true });
851
- }
852
- });
853
- test('nudge while quiesced says so', async () => {
854
- const membrane = new MockMembrane();
855
- await withFramework(membrane, async (framework) => {
856
- await framework.quiesce();
857
- const r = framework.nudgeAgent('agent', 'operator');
858
- assert.equal(r.ok, true);
859
- assert.equal(r.quiesced, true);
860
- assert.equal(framework.getHostModeStatus().gatedRequests, 1);
861
- });
862
- });
863
- //# sourceMappingURL=host-quiesce.test.js.map