@animalabs/agent-framework 0.22.0 → 0.22.2

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 (418) hide show
  1. package/README.md +12 -5
  2. package/dist/src/agent.d.ts +192 -19
  3. package/dist/src/agent.d.ts.map +1 -1
  4. package/dist/src/agent.js +407 -66
  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 +84 -23
  17. package/dist/src/api/server.js.map +1 -1
  18. package/dist/src/api/types.d.ts +9 -1
  19. package/dist/src/api/types.d.ts.map +1 -1
  20. package/dist/src/code-execution/py-runner.d.ts.map +1 -1
  21. package/dist/src/code-execution/py-runner.js.map +1 -1
  22. package/dist/src/framework.d.ts +682 -103
  23. package/dist/src/framework.d.ts.map +1 -1
  24. package/dist/src/framework.js +3202 -718
  25. package/dist/src/framework.js.map +1 -1
  26. package/dist/src/gate/event-gate.d.ts.map +1 -1
  27. package/dist/src/gate/gate-script.d.ts.map +1 -1
  28. package/dist/src/gate/gate-script.js.map +1 -1
  29. package/dist/src/index.d.ts +4 -4
  30. package/dist/src/index.d.ts.map +1 -1
  31. package/dist/src/index.js +2 -2
  32. package/dist/src/index.js.map +1 -1
  33. package/dist/src/mcpl/capability-grant.d.ts.map +1 -1
  34. package/dist/src/mcpl/channel-registry.d.ts +26 -7
  35. package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
  36. package/dist/src/mcpl/channel-registry.js +102 -22
  37. package/dist/src/mcpl/channel-registry.js.map +1 -1
  38. package/dist/src/mcpl/checkpoint-manager.d.ts.map +1 -1
  39. package/dist/src/mcpl/checkpoint-manager.js.map +1 -1
  40. package/dist/src/mcpl/conversation-router.d.ts.map +1 -1
  41. package/dist/src/mcpl/errors.js.map +1 -1
  42. package/dist/src/mcpl/feature-set-manager.d.ts.map +1 -1
  43. package/dist/src/mcpl/feature-set-manager.js +4 -3
  44. package/dist/src/mcpl/feature-set-manager.js.map +1 -1
  45. package/dist/src/mcpl/hook-orchestrator.d.ts.map +1 -1
  46. package/dist/src/mcpl/index.d.ts +2 -0
  47. package/dist/src/mcpl/index.d.ts.map +1 -1
  48. package/dist/src/mcpl/index.js.map +1 -1
  49. package/dist/src/mcpl/inference-router.d.ts.map +1 -1
  50. package/dist/src/mcpl/log-value.d.ts +54 -0
  51. package/dist/src/mcpl/log-value.d.ts.map +1 -0
  52. package/dist/src/mcpl/log-value.js +109 -0
  53. package/dist/src/mcpl/log-value.js.map +1 -0
  54. package/dist/src/mcpl/prose-stream-router.d.ts +6 -6
  55. package/dist/src/mcpl/prose-stream-router.d.ts.map +1 -1
  56. package/dist/src/mcpl/prose-stream-router.js +4 -4
  57. package/dist/src/mcpl/prose-stream-router.js.map +1 -1
  58. package/dist/src/mcpl/push-coalescer.d.ts +38 -3
  59. package/dist/src/mcpl/push-coalescer.d.ts.map +1 -1
  60. package/dist/src/mcpl/push-coalescer.js +81 -16
  61. package/dist/src/mcpl/push-coalescer.js.map +1 -1
  62. package/dist/src/mcpl/push-handler.d.ts +26 -3
  63. package/dist/src/mcpl/push-handler.d.ts.map +1 -1
  64. package/dist/src/mcpl/push-handler.js +87 -23
  65. package/dist/src/mcpl/push-handler.js.map +1 -1
  66. package/dist/src/mcpl/reference-fetcher.d.ts +2 -1
  67. package/dist/src/mcpl/reference-fetcher.d.ts.map +1 -1
  68. package/dist/src/mcpl/reference-fetcher.js +20 -9
  69. package/dist/src/mcpl/reference-fetcher.js.map +1 -1
  70. package/dist/src/mcpl/references.d.ts +29 -6
  71. package/dist/src/mcpl/references.d.ts.map +1 -1
  72. package/dist/src/mcpl/references.js +57 -16
  73. package/dist/src/mcpl/references.js.map +1 -1
  74. package/dist/src/mcpl/refusal-lines.d.ts +37 -0
  75. package/dist/src/mcpl/refusal-lines.d.ts.map +1 -0
  76. package/dist/src/mcpl/refusal-lines.js +61 -0
  77. package/dist/src/mcpl/refusal-lines.js.map +1 -0
  78. package/dist/src/mcpl/scope-manager.d.ts.map +1 -1
  79. package/dist/src/mcpl/server-connection.d.ts +46 -3
  80. package/dist/src/mcpl/server-connection.d.ts.map +1 -1
  81. package/dist/src/mcpl/server-connection.js +98 -15
  82. package/dist/src/mcpl/server-connection.js.map +1 -1
  83. package/dist/src/mcpl/server-registry.d.ts.map +1 -1
  84. package/dist/src/mcpl/tool-classes.d.ts +1 -1
  85. package/dist/src/mcpl/tool-classes.d.ts.map +1 -1
  86. package/dist/src/mcpl/tool-classes.js +3 -2
  87. package/dist/src/mcpl/tool-classes.js.map +1 -1
  88. package/dist/src/mcpl/tool-lifecycle.d.ts.map +1 -1
  89. package/dist/src/mcpl/tool-lifecycle.js.map +1 -1
  90. package/dist/src/mcpl/transport.d.ts +23 -5
  91. package/dist/src/mcpl/transport.d.ts.map +1 -1
  92. package/dist/src/mcpl/transport.js +103 -10
  93. package/dist/src/mcpl/transport.js.map +1 -1
  94. package/dist/src/mcpl/types.d.ts +30 -26
  95. package/dist/src/mcpl/types.d.ts.map +1 -1
  96. package/dist/src/mcpl/types.js.map +1 -1
  97. package/dist/src/module-registry.d.ts +9 -3
  98. package/dist/src/module-registry.d.ts.map +1 -1
  99. package/dist/src/module-registry.js +3 -2
  100. package/dist/src/module-registry.js.map +1 -1
  101. package/dist/src/modules/api/index.d.ts.map +1 -1
  102. package/dist/src/modules/discord/discord-js-client.d.ts.map +1 -1
  103. package/dist/src/modules/discord/discord-js-client.js.map +1 -1
  104. package/dist/src/modules/discord/index.d.ts.map +1 -1
  105. package/dist/src/modules/discord/index.js +4 -2
  106. package/dist/src/modules/discord/index.js.map +1 -1
  107. package/dist/src/modules/health/index.d.ts.map +1 -1
  108. package/dist/src/modules/health/index.js.map +1 -1
  109. package/dist/src/modules/history/index.d.ts.map +1 -1
  110. package/dist/src/modules/history/index.js.map +1 -1
  111. package/dist/src/modules/history/semantic.d.ts.map +1 -1
  112. package/dist/src/modules/history/semantic.js.map +1 -1
  113. package/dist/src/modules/workspace/branch-intent.d.ts.map +1 -1
  114. package/dist/src/modules/workspace/branch-intent.js.map +1 -1
  115. package/dist/src/modules/workspace/disk-agreement.d.ts +22 -4
  116. package/dist/src/modules/workspace/disk-agreement.d.ts.map +1 -1
  117. package/dist/src/modules/workspace/disk-agreement.js +63 -25
  118. package/dist/src/modules/workspace/disk-agreement.js.map +1 -1
  119. package/dist/src/modules/workspace/effects.d.ts.map +1 -1
  120. package/dist/src/modules/workspace/index.d.ts +8 -4
  121. package/dist/src/modules/workspace/index.d.ts.map +1 -1
  122. package/dist/src/modules/workspace/index.js +85 -16
  123. package/dist/src/modules/workspace/index.js.map +1 -1
  124. package/dist/src/modules/workspace/observe.d.ts +56 -11
  125. package/dist/src/modules/workspace/observe.d.ts.map +1 -1
  126. package/dist/src/modules/workspace/observe.js +288 -43
  127. package/dist/src/modules/workspace/observe.js.map +1 -1
  128. package/dist/src/modules/workspace/reconcile.d.ts +31 -1
  129. package/dist/src/modules/workspace/reconcile.d.ts.map +1 -1
  130. package/dist/src/modules/workspace/reconcile.js +63 -12
  131. package/dist/src/modules/workspace/reconcile.js.map +1 -1
  132. package/dist/src/modules/workspace/types.d.ts +27 -2
  133. package/dist/src/modules/workspace/types.d.ts.map +1 -1
  134. package/dist/src/modules/workspace/types.js.map +1 -1
  135. package/dist/src/modules/workspace/watcher.d.ts.map +1 -1
  136. package/dist/src/modules/workspace/watcher.js.map +1 -1
  137. package/dist/src/operator-log.d.ts +41 -0
  138. package/dist/src/operator-log.d.ts.map +1 -1
  139. package/dist/src/operator-log.js.map +1 -1
  140. package/dist/src/provider-waits.d.ts +216 -0
  141. package/dist/src/provider-waits.d.ts.map +1 -0
  142. package/dist/src/provider-waits.js +482 -0
  143. package/dist/src/provider-waits.js.map +1 -0
  144. package/dist/src/queue.d.ts.map +1 -1
  145. package/dist/src/record-journal.d.ts.map +1 -1
  146. package/dist/src/record-journal.js.map +1 -1
  147. package/dist/src/recovery/discord-awareness-outbox.d.ts.map +1 -1
  148. package/dist/src/recovery/discord-awareness-outbox.js.map +1 -1
  149. package/dist/src/recovery/offline-branch.d.ts.map +1 -1
  150. package/dist/src/recovery/offline-branch.js +29 -24
  151. package/dist/src/recovery/offline-branch.js.map +1 -1
  152. package/dist/src/recovery/recover-cli.js.map +1 -1
  153. package/dist/src/refusal-reactions.d.ts +14 -12
  154. package/dist/src/refusal-reactions.d.ts.map +1 -1
  155. package/dist/src/refusal-reactions.js +14 -12
  156. package/dist/src/refusal-reactions.js.map +1 -1
  157. package/dist/src/runtime/liveness-watchdog.d.ts.map +1 -1
  158. package/dist/src/runtime/liveness-watchdog.js.map +1 -1
  159. package/dist/src/shutdown.d.ts.map +1 -1
  160. package/dist/src/shutdown.js.map +1 -1
  161. package/dist/src/stored-removal.d.ts +73 -0
  162. package/dist/src/stored-removal.d.ts.map +1 -0
  163. package/dist/src/stored-removal.js +100 -0
  164. package/dist/src/stored-removal.js.map +1 -0
  165. package/dist/src/thinking-token-stamp.js.map +1 -1
  166. package/dist/src/tool-image-ledger.d.ts.map +1 -1
  167. package/dist/src/tool-image-ledger.js.map +1 -1
  168. package/dist/src/tool-presentation.d.ts.map +1 -1
  169. package/dist/src/tool-presentation.js.map +1 -1
  170. package/dist/src/tool-result-guard.d.ts +30 -13
  171. package/dist/src/tool-result-guard.d.ts.map +1 -1
  172. package/dist/src/tool-result-guard.js +71 -25
  173. package/dist/src/tool-result-guard.js.map +1 -1
  174. package/dist/src/tune-out/coordinator.d.ts.map +1 -1
  175. package/dist/src/tune-out/coordinator.js.map +1 -1
  176. package/dist/src/tune-out/tools.d.ts +1 -1
  177. package/dist/src/tune-out/tools.d.ts.map +1 -1
  178. package/dist/src/types/agent.d.ts +42 -6
  179. package/dist/src/types/agent.d.ts.map +1 -1
  180. package/dist/src/types/events.d.ts +12 -0
  181. package/dist/src/types/events.d.ts.map +1 -1
  182. package/dist/src/types/framework.d.ts +10 -0
  183. package/dist/src/types/framework.d.ts.map +1 -1
  184. package/dist/src/types/module.d.ts +20 -8
  185. package/dist/src/types/module.d.ts.map +1 -1
  186. package/dist/src/types/trace.d.ts +75 -13
  187. package/dist/src/types/trace.d.ts.map +1 -1
  188. package/dist/src/usage/usage-tracker.d.ts.map +1 -1
  189. package/dist/test/agent-runtime-settings.test.js +1139 -3
  190. package/dist/test/agent-runtime-settings.test.js.map +1 -1
  191. package/dist/test/batched-wake-locus.test.js.map +1 -1
  192. package/dist/test/channel-label-history.test.js.map +1 -1
  193. package/dist/test/code-execution.test.js.map +1 -1
  194. package/dist/test/conversation-fork-injection-scoping.test.js.map +1 -1
  195. package/dist/test/conversation-router.test.js.map +1 -1
  196. package/dist/test/conversation-routing.test.js +240 -6
  197. package/dist/test/conversation-routing.test.js.map +1 -1
  198. package/dist/test/discord-awareness-outbox.test.js +107 -0
  199. package/dist/test/discord-awareness-outbox.test.js.map +1 -1
  200. package/dist/test/discord-typing-keepalive.test.d.ts +2 -0
  201. package/dist/test/discord-typing-keepalive.test.d.ts.map +1 -0
  202. package/dist/test/discord-typing-keepalive.test.js +77 -0
  203. package/dist/test/discord-typing-keepalive.test.js.map +1 -0
  204. package/dist/test/ephemeral-settle.test.js.map +1 -1
  205. package/dist/test/event-gate-passthrough.test.js.map +1 -1
  206. package/dist/test/event-gate-policy-mutation.test.js.map +1 -1
  207. package/dist/test/event-gate-rate-limit.test.js.map +1 -1
  208. package/dist/test/event-gate-script.test.js.map +1 -1
  209. package/dist/test/event-gate-selfwake.test.js.map +1 -1
  210. package/dist/test/event-gate-tags.test.js.map +1 -1
  211. package/dist/test/event-gate.test.js.map +1 -1
  212. package/dist/test/explicit-prose-routing.test.js +363 -44
  213. package/dist/test/explicit-prose-routing.test.js.map +1 -1
  214. package/dist/test/framework.test.js +160 -1
  215. package/dist/test/framework.test.js.map +1 -1
  216. package/dist/test/helpers/coalescing-fixture.d.ts +2 -0
  217. package/dist/test/helpers/coalescing-fixture.d.ts.map +1 -1
  218. package/dist/test/helpers/coalescing-fixture.js +11 -4
  219. package/dist/test/helpers/coalescing-fixture.js.map +1 -1
  220. package/dist/test/helpers/mock-membrane.d.ts.map +1 -1
  221. package/dist/test/helpers/mock-membrane.js.map +1 -1
  222. package/dist/test/hide-then-turn.test.d.ts +2 -0
  223. package/dist/test/hide-then-turn.test.d.ts.map +1 -0
  224. package/dist/test/hide-then-turn.test.js +101 -0
  225. package/dist/test/hide-then-turn.test.js.map +1 -0
  226. package/dist/test/history-module-overview.test.js.map +1 -1
  227. package/dist/test/history-module-semantic.test.js.map +1 -1
  228. package/dist/test/history-module.test.js.map +1 -1
  229. package/dist/test/history-semantic-review-findings.test.js.map +1 -1
  230. package/dist/test/host-quiesce.test.js +125 -0
  231. package/dist/test/host-quiesce.test.js.map +1 -1
  232. package/dist/test/inference-exhaustion-rewind.test.js +220 -14
  233. package/dist/test/inference-exhaustion-rewind.test.js.map +1 -1
  234. package/dist/test/inference-failure-bounds.test.d.ts +2 -0
  235. package/dist/test/inference-failure-bounds.test.d.ts.map +1 -0
  236. package/dist/test/inference-failure-bounds.test.js +1202 -0
  237. package/dist/test/inference-failure-bounds.test.js.map +1 -0
  238. package/dist/test/kv-unified-open-flight-retry.test.js.map +1 -1
  239. package/dist/test/late-events-after-stop.test.d.ts +2 -0
  240. package/dist/test/late-events-after-stop.test.d.ts.map +1 -0
  241. package/dist/test/late-events-after-stop.test.js +122 -0
  242. package/dist/test/late-events-after-stop.test.js.map +1 -0
  243. package/dist/test/liveness-watchdog.test.js.map +1 -1
  244. package/dist/test/maintenance-timer.test.js +1564 -2
  245. package/dist/test/maintenance-timer.test.js.map +1 -1
  246. package/dist/test/mcp-server-bin.test.d.ts +2 -0
  247. package/dist/test/mcp-server-bin.test.d.ts.map +1 -0
  248. package/dist/test/mcp-server-bin.test.js +142 -0
  249. package/dist/test/mcp-server-bin.test.js.map +1 -0
  250. package/dist/test/mcpl-awareness-barrier.test.js +141 -0
  251. package/dist/test/mcpl-awareness-barrier.test.js.map +1 -1
  252. package/dist/test/mcpl-child-env.test.js +1 -1
  253. package/dist/test/mcpl-child-env.test.js.map +1 -1
  254. package/dist/test/mcpl-coalesced-content-parity.test.d.ts +2 -0
  255. package/dist/test/mcpl-coalesced-content-parity.test.d.ts.map +1 -0
  256. package/dist/test/mcpl-coalesced-content-parity.test.js +532 -0
  257. package/dist/test/mcpl-coalesced-content-parity.test.js.map +1 -0
  258. package/dist/test/mcpl-coalescing.test.js +78 -16
  259. package/dist/test/mcpl-coalescing.test.js.map +1 -1
  260. package/dist/test/mcpl-config-diagnostics.test.js +6 -3
  261. package/dist/test/mcpl-config-diagnostics.test.js.map +1 -1
  262. package/dist/test/mcpl-gate-roundtrip.test.js.map +1 -1
  263. package/dist/test/mcpl-manifest-changed.test.js +2 -1
  264. package/dist/test/mcpl-manifest-changed.test.js.map +1 -1
  265. package/dist/test/mcpl-reconnect-events.test.js.map +1 -1
  266. package/dist/test/mcpl-reconnect-reregistration.test.js +2 -0
  267. package/dist/test/mcpl-reconnect-reregistration.test.js.map +1 -1
  268. package/dist/test/mcpl-reference-fetcher.test.js +232 -4
  269. package/dist/test/mcpl-reference-fetcher.test.js.map +1 -1
  270. package/dist/test/mcpl-reference-fields.test.js +69 -2
  271. package/dist/test/mcpl-reference-fields.test.js.map +1 -1
  272. package/dist/test/mcpl-rejection-log-lines.test.d.ts +2 -0
  273. package/dist/test/mcpl-rejection-log-lines.test.d.ts.map +1 -0
  274. package/dist/test/mcpl-rejection-log-lines.test.js +349 -0
  275. package/dist/test/mcpl-rejection-log-lines.test.js.map +1 -0
  276. package/dist/test/mcpl-stderr-tail.test.d.ts +2 -0
  277. package/dist/test/mcpl-stderr-tail.test.d.ts.map +1 -0
  278. package/dist/test/mcpl-stderr-tail.test.js +210 -0
  279. package/dist/test/mcpl-stderr-tail.test.js.map +1 -0
  280. package/dist/test/mcpl-tool-lifecycle-e2e.test.js.map +1 -1
  281. package/dist/test/mcpl-tool-lifecycle-emitter.test.js.map +1 -1
  282. package/dist/test/mcpl-tool-lifecycle-script.test.js.map +1 -1
  283. package/dist/test/mcpl-tool-lifecycle.test.js.map +1 -1
  284. package/dist/test/mcpl-transport-close.test.d.ts +2 -0
  285. package/dist/test/mcpl-transport-close.test.d.ts.map +1 -0
  286. package/dist/test/mcpl-transport-close.test.js +373 -0
  287. package/dist/test/mcpl-transport-close.test.js.map +1 -0
  288. package/dist/test/mcpl-transport-spawn.test.d.ts +2 -0
  289. package/dist/test/mcpl-transport-spawn.test.d.ts.map +1 -0
  290. package/dist/test/mcpl-transport-spawn.test.js +58 -0
  291. package/dist/test/mcpl-transport-spawn.test.js.map +1 -0
  292. package/dist/test/mcpl-ws-transport.test.js +104 -0
  293. package/dist/test/mcpl-ws-transport.test.js.map +1 -1
  294. package/dist/test/offline-recovery-branch.test.js +344 -0
  295. package/dist/test/offline-recovery-branch.test.js.map +1 -1
  296. package/dist/test/operator-surgery.test.js +197 -0
  297. package/dist/test/operator-surgery.test.js.map +1 -1
  298. package/dist/test/ops-alert.test.js +2 -1
  299. package/dist/test/ops-alert.test.js.map +1 -1
  300. package/dist/test/overbudget-drain-breaker.test.js +1 -0
  301. package/dist/test/overbudget-drain-breaker.test.js.map +1 -1
  302. package/dist/test/pack-installs-alone.test.d.ts +2 -0
  303. package/dist/test/pack-installs-alone.test.d.ts.map +1 -0
  304. package/dist/test/pack-installs-alone.test.js +284 -0
  305. package/dist/test/pack-installs-alone.test.js.map +1 -0
  306. package/dist/test/physical-window-restart.test.d.ts +6 -4
  307. package/dist/test/physical-window-restart.test.d.ts.map +1 -1
  308. package/dist/test/physical-window-restart.test.js +275 -10
  309. package/dist/test/physical-window-restart.test.js.map +1 -1
  310. package/dist/test/placed-reaction-baseline.test.d.ts +2 -0
  311. package/dist/test/placed-reaction-baseline.test.d.ts.map +1 -0
  312. package/dist/test/placed-reaction-baseline.test.js +312 -0
  313. package/dist/test/placed-reaction-baseline.test.js.map +1 -0
  314. package/dist/test/present-while-acting.test.js +949 -6
  315. package/dist/test/present-while-acting.test.js.map +1 -1
  316. package/dist/test/provider-acceleration-cooldown.test.js +5 -1
  317. package/dist/test/provider-acceleration-cooldown.test.js.map +1 -1
  318. package/dist/test/provider-waits.test.d.ts +2 -0
  319. package/dist/test/provider-waits.test.d.ts.map +1 -0
  320. package/dist/test/provider-waits.test.js +2259 -0
  321. package/dist/test/provider-waits.test.js.map +1 -0
  322. package/dist/test/puppet-tool-call.test.js +2 -0
  323. package/dist/test/puppet-tool-call.test.js.map +1 -1
  324. package/dist/test/reaction-baseline-platform.test.d.ts +2 -0
  325. package/dist/test/reaction-baseline-platform.test.d.ts.map +1 -0
  326. package/dist/test/reaction-baseline-platform.test.js +124 -0
  327. package/dist/test/reaction-baseline-platform.test.js.map +1 -0
  328. package/dist/test/record-journal.test.js.map +1 -1
  329. package/dist/test/refusal-reaction-baseline.test.js +10 -3
  330. package/dist/test/refusal-reaction-baseline.test.js.map +1 -1
  331. package/dist/test/refusal-rewind.test.js +9 -0
  332. package/dist/test/refusal-rewind.test.js.map +1 -1
  333. package/dist/test/refusal-single-call.test.js.map +1 -1
  334. package/dist/test/release-bump.test.d.ts +2 -0
  335. package/dist/test/release-bump.test.d.ts.map +1 -0
  336. package/dist/test/release-bump.test.js +248 -0
  337. package/dist/test/release-bump.test.js.map +1 -0
  338. package/dist/test/release-changelog.test.js.map +1 -1
  339. package/dist/test/release-holds.test.d.ts +2 -0
  340. package/dist/test/release-holds.test.d.ts.map +1 -0
  341. package/dist/test/release-holds.test.js +456 -0
  342. package/dist/test/release-holds.test.js.map +1 -0
  343. package/dist/test/same-round-think-policy.test.js.map +1 -1
  344. package/dist/test/save-recent-image.test.js +138 -2
  345. package/dist/test/save-recent-image.test.js.map +1 -1
  346. package/dist/test/shutdown-errors.test.js.map +1 -1
  347. package/dist/test/silent-heartbeat-rows.test.js.map +1 -1
  348. package/dist/test/stop-with-host-operations.test.d.ts +20 -0
  349. package/dist/test/stop-with-host-operations.test.d.ts.map +1 -0
  350. package/dist/test/stop-with-host-operations.test.js +1174 -0
  351. package/dist/test/stop-with-host-operations.test.js.map +1 -0
  352. package/dist/test/stop-with-work-in-flight.test.js +162 -50
  353. package/dist/test/stop-with-work-in-flight.test.js.map +1 -1
  354. package/dist/test/surgery-marks-receipt.test.d.ts +2 -0
  355. package/dist/test/surgery-marks-receipt.test.d.ts.map +1 -0
  356. package/dist/test/surgery-marks-receipt.test.js +540 -0
  357. package/dist/test/surgery-marks-receipt.test.js.map +1 -0
  358. package/dist/test/tool-batch-hook.test.js.map +1 -1
  359. package/dist/test/tool-result-guard.test.js +352 -16
  360. package/dist/test/tool-result-guard.test.js.map +1 -1
  361. package/dist/test/tool-result-spill.test.js.map +1 -1
  362. package/dist/test/tool-wrapper-prose-guard-integration.test.js.map +1 -1
  363. package/dist/test/trunk-channel-routing.test.js +330 -7
  364. package/dist/test/trunk-channel-routing.test.js.map +1 -1
  365. package/dist/test/tune-out-e2e.test.js.map +1 -1
  366. package/dist/test/unconvertible-tool-result.test.js.map +1 -1
  367. package/dist/test/unsent-compiles.test.d.ts +2 -0
  368. package/dist/test/unsent-compiles.test.d.ts.map +1 -0
  369. package/dist/test/unsent-compiles.test.js +139 -0
  370. package/dist/test/unsent-compiles.test.js.map +1 -0
  371. package/dist/test/workspace-branch-continuation.test.js.map +1 -1
  372. package/dist/test/workspace-materialize-freshness.test.js.map +1 -1
  373. package/dist/test/workspace-read-text.test.js.map +1 -1
  374. package/dist/test/workspace-three-way.test.js +1022 -7
  375. package/dist/test/workspace-three-way.test.js.map +1 -1
  376. package/dist/test/workspace-watcher.test.js.map +1 -1
  377. package/dist/test/xml-round-persist.test.js.map +1 -1
  378. package/dist/tsconfig.tsbuildinfo +1 -1
  379. package/package.json +8 -6
  380. package/src/agent.ts +415 -67
  381. package/src/api/mcp-server-core.ts +681 -0
  382. package/src/api/mcp-server.ts +16 -685
  383. package/src/api/server.ts +87 -26
  384. package/src/api/types.ts +9 -1
  385. package/src/framework.ts +3389 -782
  386. package/src/index.ts +9 -4
  387. package/src/mcpl/channel-registry.ts +126 -31
  388. package/src/mcpl/feature-set-manager.ts +4 -3
  389. package/src/mcpl/index.ts +2 -0
  390. package/src/mcpl/log-value.ts +116 -0
  391. package/src/mcpl/prose-stream-router.ts +6 -6
  392. package/src/mcpl/push-coalescer.ts +76 -12
  393. package/src/mcpl/push-handler.ts +95 -23
  394. package/src/mcpl/reference-fetcher.ts +18 -8
  395. package/src/mcpl/references.ts +57 -13
  396. package/src/mcpl/refusal-lines.ts +59 -0
  397. package/src/mcpl/server-connection.ts +125 -15
  398. package/src/mcpl/tool-classes.ts +3 -2
  399. package/src/mcpl/transport.ts +105 -14
  400. package/src/mcpl/types.ts +5 -1
  401. package/src/module-registry.ts +17 -9
  402. package/src/modules/discord/index.ts +4 -2
  403. package/src/modules/workspace/disk-agreement.ts +74 -18
  404. package/src/modules/workspace/index.ts +85 -15
  405. package/src/modules/workspace/observe.ts +295 -43
  406. package/src/modules/workspace/reconcile.ts +90 -12
  407. package/src/modules/workspace/types.ts +26 -1
  408. package/src/operator-log.ts +30 -0
  409. package/src/provider-waits.ts +523 -0
  410. package/src/recovery/offline-branch.ts +32 -28
  411. package/src/refusal-reactions.ts +14 -12
  412. package/src/stored-removal.ts +126 -0
  413. package/src/tool-result-guard.ts +72 -24
  414. package/src/types/agent.ts +42 -6
  415. package/src/types/events.ts +12 -0
  416. package/src/types/framework.ts +10 -0
  417. package/src/types/module.ts +20 -8
  418. package/src/types/trace.ts +76 -14
@@ -9,7 +9,7 @@ import { type ToolClass, type ToolClassSource } from './mcpl/tool-classes.js';
9
9
  import { ChannelRegistry } from './mcpl/channel-registry.js';
10
10
  import { ConversationRouter } from './mcpl/conversation-router.js';
11
11
  import type { SessionUsageSnapshot } from './usage/types.js';
12
- import { type OperatorLogEntry, type OperatorLogInput, type OperatorRequester } from './operator-log.js';
12
+ import { type SurgeryMarkerReceipt, type OperatorLogEntry, type OperatorLogInput, type OperatorRequester } from './operator-log.js';
13
13
  /**
14
14
  * Feasibility verdict for a runtime-settings patch, derived through the SAME
15
15
  * settings→config mapping the live apply path uses (`Agent.planRuntimeSettings`
@@ -104,9 +104,83 @@ export declare class ResumeBlockedError extends Error {
104
104
  preview: RuntimeSettingsPreview;
105
105
  }>);
106
106
  }
107
+ /**
108
+ * How `runEphemeralToCompletion` rejects when a retryable provider failure
109
+ * states a wait the run won't sleep: one longer than an ephemeral run sleeps
110
+ * in its turn (600 s), an infinite one, or one that is `NaN`. The run ends at
111
+ * once, without retrying inside the wait, and every other ending of the run
112
+ * rejects with a plain `Error`. `retryAfterMs` is the wait as the provider
113
+ * stated it, in milliseconds, so `Infinity` or `NaN` in those two cases: a
114
+ * host that schedules a rerun from it handles a value that isn't finite, and
115
+ * one past the 2,147,483,647 ms a timer can hold. The message says the same
116
+ * in words. A host can test `instanceof` or the `name`, which also holds for
117
+ * an error from another copy of this package.
118
+ */
119
+ export declare class ProviderWaitNotSleptError extends Error {
120
+ readonly retryAfterMs: number;
121
+ constructor(message: string, retryAfterMs: number);
122
+ }
107
123
  interface InferenceToolSnapshot {
108
124
  sameRoundThinkTextPolicy: SameRoundThinkTextPolicy;
109
125
  }
126
+ /**
127
+ * Whether the poison-history breaker may shed the newest exchange for a
128
+ * failure: an `invalid_request` at HTTP 400, 413 or 422 or with no status, or
129
+ * a `context_length` at 413. The status is a heuristic for when a shed may
130
+ * help, not proof that the history is at fault.
131
+ *
132
+ * 400 and 422 are how a provider answers a request that fails its
133
+ * validation, as a history it can't accept does, but other refusals come
134
+ * back the same way, such as a refusal of the account that membrane doesn't
135
+ * recognize by its text. A 413 is the request's size. When the newest
136
+ * exchange made it too large, as an oversized attachment does, shedding that
137
+ * exchange may bring the request back under the limit, and nothing else in
138
+ * the framework recovers a 413; when the history as a whole is too large,
139
+ * the shed doesn't help, and the breaker stops at its rewind cap. The 413 arm
140
+ * takes both labels membranes have given a 413, invalid_request and
141
+ * context_length (see the notes below). Other statuses keep the history,
142
+ * since a shed takes the exchange out of the agent's context, which only an
143
+ * operator's undo brings back, and the status gives no sign that a shed
144
+ * would help: a 404 is a model or an endpoint that doesn't exist, and 405,
145
+ * 409, 410 and 415 are about the HTTP request or the resource, as a rule,
146
+ * rather than the conversation.
147
+ *
148
+ * The table test in test/inference-exhaustion-rewind.test.ts is this
149
+ * predicate's contract. The notes below on which membrane version gives which
150
+ * label are its history, and will go stale as hosts move to newer releases.
151
+ *
152
+ * Which failures reach the gate with which label depends on the membrane:
153
+ * - As membrane 0.5.86 classifies them: Anthropic files a 400 as
154
+ * invalid_request (after its context check) and its other 4xx as unknown.
155
+ * The chat adapters never file one as invalid_request, since they classify
156
+ * by the error's message text, and a context_length they file that way
157
+ * carries status 400 whatever the response's was. The raw-fetch Responses
158
+ * adapter files every status it doesn't list (404, 405, 409, 410, 413,
159
+ * 415, 422 …) as invalid_request, so it alone produces an invalid_request
160
+ * at 413 or 422, and no 0.5.86 adapter produces a context_length at 413.
161
+ * - From membrane 0.5.87 (membrane #56 and #107), this package's floor, every
162
+ * adapter sends an HTTP failure through one status table
163
+ * (errorFromProviderStatus). On a 400 or 422, auth codes and reasons and
164
+ * the two account refusals it recognizes by their text (a balance too low,
165
+ * usage limits reached) are auth, and a context overflow, by its code or
166
+ * text, is context_length. A 401, 402 or 403 is auth, a 408 timeout, a 429
167
+ * rate_limit, a 404 invalid_request and a 413 context_length; other 4xx
168
+ * are invalid_request. So a 413 the table types sheds, an Anthropic one
169
+ * included, while a context_length at 400 or 422, a token overflow, keeps
170
+ * the history, and so does an account refusal, which is auth. An adapter
171
+ * can type a failure before the table does, as Anthropic's does for a
172
+ * gateway's aggregate error (server). A failure with no HTTP status takes
173
+ * the status its provider code implies when the table knows the code, as
174
+ * for Anthropic's mid-stream errors, and is otherwise typed from its
175
+ * message, with no status. The 422 arm also covers an
176
+ * OpenAI-compatible server, such as a FastAPI one, that answers a
177
+ * validation failure with 422. The test of provider answers through the
178
+ * table, beside the table test, pins how the two meet at the floor.
179
+ *
180
+ * An error with no status, from a membrane that reports none, keeps the rule
181
+ * the breaker had before: the type alone.
182
+ */
183
+ export declare function shedMayHelp(errorType: string | undefined, httpStatus: number | undefined): boolean;
110
184
  export declare class AgentFramework {
111
185
  private toolPresentations;
112
186
  private presentationPreviews;
@@ -116,6 +190,10 @@ export declare class AgentFramework {
116
190
  private stopPromise;
117
191
  private stopCompleted;
118
192
  private ownedStoreClosed;
193
+ /** An operator's operations in flight, and the config materializations they
194
+ * start. stop() waits until this set is empty before it tears down, unless
195
+ * its wait budget runs out. */
196
+ private readonly operatorOperations;
119
197
  private membrane;
120
198
  private queue;
121
199
  private agents;
@@ -123,16 +201,6 @@ export declare class AgentFramework {
123
201
  private inferencePolicy;
124
202
  private errorPolicy;
125
203
  private pendingRequests;
126
- /**
127
- * Per-agent channel that triggered the agent's CURRENT inference turn, if any
128
- * (item-3 redux). Read by the ChannelRegistry's `activeChannelResolver` to
129
- * route a single-trunk agent's plain-text speech back to the channel it is
130
- * answering, instead of the process-global most-recent-inbound locus that a
131
- * concurrent message elsewhere can hijack. Set at turn start (or cleared for a
132
- * heartbeat / no-trigger turn) in startAgentStream; overwritten by the next
133
- * turn. Never read between turns (a given agent runs one turn at a time).
134
- */
135
- private activeTriggerChannels;
136
204
  private running;
137
205
  private loopPromise;
138
206
  /** Quiesce/maintenance mode (issue #122). DELIBERATELY separate from
@@ -155,6 +223,14 @@ export declare class AgentFramework {
155
223
  private maintenanceRunId;
156
224
  private currentMaintenanceRun;
157
225
  private maintenanceHistory;
226
+ /** Each agent's last reported maintenance failure, its whole text and when
227
+ * it was alerted, until its maintenance goes without one
228
+ * (reportMaintenanceFailure). */
229
+ private maintenanceFailureReported;
230
+ /** Run records whose failure repeated one already reported, and whose report was suppressed. */
231
+ private maintenanceRepeats;
232
+ /** An operator's maintain (maintenanceTick) asked for the pass running or about to run: the run it records is kept in the history whatever it met. A pass with nothing to run records none. */
233
+ private maintenancePassRequested;
158
234
  private providerGates;
159
235
  private providerAccelerationCooldowns;
160
236
  private providerAccelerationRecoveries;
@@ -162,6 +238,10 @@ export declare class AgentFramework {
162
238
  private providerAccelerationDefaultCooldownMs;
163
239
  private providerAccelerationJitterMs;
164
240
  private providerHoldHook;
241
+ /** Provider waits (stated retry-after) per (agent, model), kept across restarts. */
242
+ private providerWaits;
243
+ /** Wakers for error-policy retry waits in progress: stop() ends them. */
244
+ private retryWaitWakers;
165
245
  private providerAdmissionClosed;
166
246
  /** Invalidates framework turns still assembling when stop begins. */
167
247
  private lifecycleGeneration;
@@ -172,32 +252,6 @@ export declare class AgentFramework {
172
252
  private processLoggingPersist;
173
253
  private processLoggingBroadcast;
174
254
  private activeStreams;
175
- /** Per-agent output locus FROZEN for the CURRENT logical turn. Resolved
176
- * eagerly in startAgentStream (home → addressed trigger → global default)
177
- * and never moved until the next turn: mid-turn injected messages — ambient
178
- * chatter, reactions, system markers — must not hijack where the agent's
179
- * plain prose lands (2026-07-21 Cairn lounge misroute). Lives here — not in
180
- * driveStream locals — so the pin survives a context-budget stream restart,
181
- * which continues the same logical turn in a fresh driveStream. Cleared or
182
- * re-set at the start of every non-restart turn. Since 2026-07-31 the pin
183
- * is no longer fully frozen: an ADDRESSED conversational injection — or a
184
- * conversational follow-up in a channel the agent itself explicitly sent
185
- * into this turn (turnEngagedChannels) — re-pins it at the boundary (see
186
- * the addressed re-pin block in the tool-result handler). Ambient chatter
187
- * elsewhere, reactions, and system markers still cannot move it. */
188
- private turnLocusPins;
189
- /** Channels the agent EXPLICITLY sent into during the CURRENT turn
190
- * (SEND_ENGAGEMENT_TOOLS, successful calls), per agent. Second re-pin
191
- * signal: a conversational reply in a channel the agent just engaged is
192
- * addressed by context even without a mention (2026-07-31 n=7: q's
193
- * #portables follow-up — no @mention — was answered in trailing prose
194
- * that followed the stale pin into repligate's DM). No author-kind
195
- * filter: agent-residents are full participants, and the bot flag
196
- * tracks nothing that matters (antra). Reactions/system markers are
197
- * excluded by isConversationalInjection; the engaged-this-turn scope
198
- * keeps unrelated channels from moving the pin. Cleared at every fresh
199
- * turn's start; budget restarts keep it. */
200
- private turnEngagedChannels;
201
255
  /** A tool boundary injected fresh CONVERSATIONAL input (a real message —
202
256
  * not a reaction or a system marker) into the live stream. Tells
203
257
  * driveStream to clear sticky explicit-send suppression before handling
@@ -211,12 +265,13 @@ export declare class AgentFramework {
211
265
  /** Latest bounced (undelivered) prose per agent — the `{{unsent}}` source. */
212
266
  private proseClipboards;
213
267
  /**
214
- * Each agent's routing state for its current turn (TurnRouting): the
215
- * sticky destination, the turn's destination for a resumed stream,
216
- * hybrid's hold, a `!` continuation and receipt tallies. A fresh turn starts a new object
217
- * instead of clearing the old one, and a stream that resumes the turn
218
- * (resumesLogicalTurn) keeps it. A queued delivery holds the object of the
219
- * turn that queued it, so prose a turn leaves queued when it ends (a
268
+ * Each agent's routing state for its current logical turn (TurnRouting):
269
+ * its trigger channel, locus and engaged channels, the sticky destination,
270
+ * the turn's destination, hybrid's hold, a ` !` continuation and receipt
271
+ * tallies. The start that opens a turn makes a
272
+ * new object instead of clearing the old one, and every later stream of
273
+ * the turn shares it (openLogical). A queued delivery holds the object of
274
+ * the turn that queued it, so prose a turn leaves queued when it ends (a
220
275
  * skip_reply ends it before its posts have run) still follows that turn's
221
276
  * destination, and its late writes can't reach the next turn.
222
277
  */
@@ -228,23 +283,25 @@ export declare class AgentFramework {
228
283
  */
229
284
  private proseSpeechChains;
230
285
  /**
231
- * Each agent's open logical turn (LogicalTurn). It stays open from the
232
- * fresh start that opens it until the turn settles (settleAgent: it
233
- * completes, a tool ends it, or it fails or is abandoned), and every fresh
234
- * start that routes prose while it is open continues it: a framework
235
- * retry, the start that consumes tool results the non-streaming fallback
236
- * left (whichever wake the scheduler starts it with), the later compile a
237
- * provider-capacity hold defers a turn to. A silent start neither
238
- * continues nor opens one. A stream that ends without settling needs to do
239
- * nothing to carry its turn. Settling only detaches the turn from future
240
- * starts: the settling stream keeps its own object, which its remaining
241
- * deliveries, its receipt and its ` !` check go on using (a completion
242
- * settles before it awaits its chain and writes its receipt). So every
243
- * logical end must close inheritance once, before the next fresh start:
244
- * a turn left open would hand its object, late writes and all, to an
245
- * unrelated turn. A tool-ended turn settles before the next turn can
246
- * start. Only the stream that holds the open turn closes it; disposal
247
- * drops it, and stop() clears every agent's.
286
+ * Each agent's open logical turn: its routing state and receipt tallies
287
+ * (TurnRouting). It stays open from the start that opens it until the
288
+ * turn settles (settleAgent: it completes, a tool ends it, or it fails or
289
+ * is abandoned), and every start that routes prose while it is open
290
+ * continues it with that object: a framework retry, the start that
291
+ * consumes tool results the non-streaming fallback left (whichever wake
292
+ * the scheduler starts it with), the later compile a provider-capacity
293
+ * hold defers a turn to. A silent start neither continues nor opens one,
294
+ * and leaves the open turn's object untouched (its own is the live routing
295
+ * while it runs: turnRouting). A stream that ends without
296
+ * settling needs to do nothing to carry its turn. Settling only detaches
297
+ * the turn from future starts: the settling stream keeps its own object,
298
+ * which its remaining deliveries, its receipt and its ` !` check go on
299
+ * using (a completion settles before it awaits its chain and writes its
300
+ * receipt). So every logical end must close inheritance once, before the
301
+ * next fresh start: a turn left open would hand its object, late writes
302
+ * and all, to an unrelated turn. A tool-ended turn settles before the
303
+ * next turn can start. Only the stream that holds the open turn closes
304
+ * it; disposal drops it, and stop() clears every agent's.
248
305
  */
249
306
  private openLogical;
250
307
  /** Consecutive bounce-wakes per agent; capped so an agent that keeps
@@ -307,6 +364,8 @@ export declare class AgentFramework {
307
364
  * tick counts in the success log stop meaning anything. One kick per agent
308
365
  * at a time; cleared when the kick settles (success or failure). */
309
366
  private overBudgetDrainInFlight;
367
+ /** The over-budget drain kicks running, which a branch move waits for as it waits for a maintenance pass. */
368
+ private overBudgetDrains;
310
369
  /** Per-agent current rewind episode: the single consolidated marker's id and
311
370
  * how many turns have been shed so far. One marker per episode, updated in
312
371
  * place (see updateRewindMarker); cleared when the episode ends. */
@@ -520,14 +579,35 @@ export declare class AgentFramework {
520
579
  */
521
580
  start(): void;
522
581
  /**
523
- * Stop the event loop. Failed module/MCPL cleanup can be retried with its
524
- * original context; storage stays open until that cleanup succeeds.
525
- * @param teardownTimeoutMs Optional module/MCPL wait budget. Omit to wait
526
- * until cleanup settles, as required by existing module/child contracts. This
527
- * does not bound earlier stream or event-loop quiescence, or cancel cleanup.
582
+ * Stop the event loop. After a failed or timed-out wait on operator, module
583
+ * or MCPL cleanup, storage stays open and stop() can be called again. A
584
+ * timed-out wait lets teardown go on while that work may still act on what
585
+ * is being torn down.
586
+ * @param teardownTimeoutMs Optional budget for each wait on cleanup: an
587
+ * operator's operations already running, then modules and MCPL together.
588
+ * Omit to wait until cleanup settles, as required by existing module/child
589
+ * contracts. This does not bound earlier stream, event-loop or maintenance
590
+ * quiescence (a maintenance pass or over-budget drain kick in flight), or
591
+ * cancel cleanup.
528
592
  */
529
593
  stop(teardownTimeoutMs?: number | undefined): Promise<void>;
530
594
  private resetCompletedStop;
595
+ /** Register before invoking the body, so the set holds the operation for
596
+ * its whole life: its synchronous trace callbacks can reenter stop(), and
597
+ * that stop() must find it. Invocation stays in this stack, preserving
598
+ * immediate mode changes; the returned promise carries its result to the
599
+ * caller. */
600
+ private trackOperatorOperation;
601
+ /** Whether stop() has begun: an attempt in flight (stopPromise is set before
602
+ * its body runs, which emits traces before the queue closes) or a closed
603
+ * queue (after a failed or completed stop()). The admission rule for every
604
+ * operator entry point, the host/command listener included. */
605
+ private stopHasBegun;
606
+ private refuseOperatorAfterStop;
607
+ /** Wait in rounds until the set is empty: admitted work can still start work
608
+ * of its own. All rounds share the caller's deadline rather than renewing
609
+ * its budget. */
610
+ private waitForOperatorOperations;
531
611
  private stopOwned;
532
612
  /**
533
613
  * Advance queued ContextManager work without requiring a new message.
@@ -539,12 +619,52 @@ export declare class AgentFramework {
539
619
  */
540
620
  private providerGate;
541
621
  private providerGateBlocked;
622
+ /** Acceleration and host holds park the whole agent; a provider wait holds
623
+ * only its own model, which auxiliary admission checks per call. */
624
+ private cooldownBlocksAuxiliary;
542
625
  private acquirePrimaryProviderGate;
543
626
  private releasePrimaryProviderGate;
544
627
  private flushAuxiliaryAdmission;
545
628
  private waitForAuxiliaryIdle;
546
629
  private withAuxiliaryAdmission;
630
+ /**
631
+ * Maintenance makes no provider call while a surgery holds the store. The
632
+ * surgery waits for the maintenance work that is running before it moves
633
+ * the branch, so a call that parked at the gate would make it wait on
634
+ * whatever reopens the gate: the end of a cooldown, or the retry turn a
635
+ * cooldown queues, which the hold itself keeps from starting.
636
+ */
637
+ private withdrawMaintenanceUnderSurgery;
638
+ /**
639
+ * Nor once stop() has closed provider admission: a stop that catches a
640
+ * tick is the framework stopping on purpose, so the call is withdrawn, as
641
+ * under a surgery's hold, and no failure is reported for it.
642
+ */
643
+ private withdrawMaintenanceWhenStopping;
547
644
  private auxiliaryMembraneFor;
645
+ /**
646
+ * A conversation agent's auxiliary calls (its context manager's
647
+ * compression). A conversation agent takes no provider gate: admission
648
+ * belongs to the persistent resident, and a generation-unique fork must not
649
+ * leave a gate behind. But its stated waits are recorded for (agent, model)
650
+ * as a resident's are, so they bind its auxiliary calls too: a held model
651
+ * is refused without a call, and an auxiliary call's own stated wait is
652
+ * recorded for it. (An ephemeral run records nothing, its name being
653
+ * single-use, so its context manager keeps the plain membrane.) Its
654
+ * compression is the background work a resident's is, whether a
655
+ * maintenance tick or a drain after a message starts it, so it is withdrawn
656
+ * as a resident's is: a call made while a surgery holds the store, or once
657
+ * stop() has closed provider admission, is withdrawn without being sent.
658
+ */
659
+ private conversationAuxiliaryMembraneFor;
660
+ /** The framework's membrane, with each complete() call passed through
661
+ * `admit` along with the model it names. */
662
+ private membraneAdmitting;
663
+ /** An acceleration hold's length: AF's own pacing (`ownMs`: its default
664
+ * plus jitter, capped), or the provider's stated wait in its place
665
+ * (`stated`). The stated wait is a lower bound: jitter only adds to it,
666
+ * and the cap applies only to AF's own default. A negative stated wait is
667
+ * a stated 0, as in ProviderWaits: the 1 s floor, plus jitter. */
548
668
  private accelerationCooldownMs;
549
669
  private sameInferenceRequest;
550
670
  private consultProviderHold;
@@ -552,11 +672,123 @@ export declare class AgentFramework {
552
672
  * inference on it. True = extended in place (held requests stay held). */
553
673
  private extendHostProviderHold;
554
674
  private holdProviderAcceleration;
675
+ /**
676
+ * A provider's stated wait on a turn that doesn't own provider admission:
677
+ * a conversation agent's or an ephemeral run's. Left to the error policy,
678
+ * which returns a stated wait as it is, a 429 stating two hours would hold
679
+ * the turn asleep two hours, up to three times, with nothing recorded and
680
+ * nothing raised (membrane #56 review, M3). So:
681
+ * - A conversation agent's turns come through the scheduler as a resident's
682
+ * do, so it treats the wait as a resident does: recorded for (agent,
683
+ * model), alerted past PROVIDER_WAIT_ALERT_MS, and the turn held until the
684
+ * wait passes or an operator releases it ('held'). A non-retryable failure
685
+ * records the wait for the calls after it and keeps its own disposition.
686
+ * - An ephemeral run's name is single-use, so a wait recorded for it would
687
+ * bind nothing, and its caller is waiting on it. A retryable stated wait
688
+ * up to PROVIDER_ACCELERATION_MAX_COOLDOWN_MS is left to the error policy,
689
+ * slept and retried. A longer one, or one that can't be represented, ends
690
+ * the run now ('fail'): it is never retried before the provider's time,
691
+ * and the caller hears why at once.
692
+ * Anything else is the error policy's.
693
+ */
694
+ private nonOwningProviderWait;
695
+ /** Why an ephemeral run ended instead of sleeping a provider's stated wait,
696
+ * for its caller: the text, and the wait itself, which its rejection
697
+ * carries (ProviderWaitNotSleptError). */
698
+ private statedWaitNotSlept;
699
+ /** When a hold's timer next fires: at its deadline, stepped past what one
700
+ * timer can hold. A hold with no deadline (a wait held until released, or
701
+ * the stand-in for unreadable records) asks again as often as unreadable
702
+ * records are read again: records that read again end it, and nothing
703
+ * announces that. */
704
+ private providerHoldTimerMs;
555
705
  private releaseProviderAccelerationCooldown;
706
+ /**
707
+ * Wait an error policy's retry delay, all of it: the delay can be a
708
+ * provider's retry-after, and a single timer past 2^31-1 ms fires almost at
709
+ * once. Steps through longer waits; stop() wakes it so a shutting-down
710
+ * framework is never left with a wait parked for days.
711
+ */
712
+ private waitForRetry;
713
+ /**
714
+ * Record a provider's stated wait (a classified error carrying
715
+ * `retryAfterMs`) for (agent, model). Returns the wait that binds now,
716
+ * which is the longer of this one and any outstanding one. A wait that
717
+ * newly binds past PROVIDER_WAIT_ALERT_MS, or until released, raises an
718
+ * ops alert.
719
+ */
720
+ private recordProviderWait;
721
+ /**
722
+ * Hold this agent's primary turns for a provider wait on its model. The
723
+ * requests are kept and released together, into one fresh compile, when
724
+ * the wait ends: the same path an acceleration cooldown takes, without
725
+ * parking auxiliary calls to other models.
726
+ */
727
+ private holdForProviderWait;
728
+ /**
729
+ * Refuse an auxiliary call to a model the provider asked this agent to wait
730
+ * on, without calling it. The refusal is a retryable rate limit carrying
731
+ * the remaining wait, so a caller that paces (context-manager's compression
732
+ * lane, from its corrective round #138 on) waits it out instead of spending
733
+ * a call. It is marked
734
+ * `providerAdmission: 'deferred'`: no call was made, so a caller can keep
735
+ * the wait without counting a failed call (room-225 #47927).
736
+ */
737
+ private refuseHeldProviderModel;
738
+ /**
739
+ * Release provider waits: one model's for an agent, or every model's. The
740
+ * explicit operator override for a wait that should not be honoured (the
741
+ * passing of time needs no call). Recorded, so a restart does not bring the
742
+ * wait back; held primary turns are released into one fresh compile. An
743
+ * acceleration hold the released wait lengthened keeps only AF's own pacing
744
+ * for its failure; a host hold stays the host's.
745
+ */
746
+ releaseProviderWait(agentName: string, model?: string, by?: string): Array<{
747
+ model: string;
748
+ until: string | null;
749
+ release: 'recorded' | 'pending' | 'in-process override';
750
+ }>;
751
+ /** Provider waits binding now, for health and doctor tooling. */
752
+ providerWaitSnapshot(agentName?: string): Array<{
753
+ agent: string;
754
+ model: string;
755
+ until: string | null;
756
+ reason: string;
757
+ setAt: string;
758
+ }>;
556
759
  private recordProviderAccelerationRecovery;
557
760
  private cancelProviderAdmission;
558
761
  private startQueuedMaintenance;
762
+ /** resume()'s refusal while a surgery holds the store. */
763
+ private refuseResumeUnderSurgery;
764
+ /** Whether maintenance work is running: a pass, or an over-budget drain kick. */
765
+ private maintenanceRunning;
766
+ /** Wait for the maintenance work that is running, whatever its outcome. */
767
+ private settleMaintenancePass;
559
768
  private runQueuedMaintenance;
769
+ /**
770
+ * One agent's maintenance failure: recorded on its run, bounded as every
771
+ * failure sink is (`record.error`), and logged and alerted for that agent
772
+ * with the whole text. A failure that lasts, such as a manager whose
773
+ * strategy failed to initialize, meets every pass, a few seconds apart. It
774
+ * is logged and alerted again only when its whole text changes, once
775
+ * opsAlert's cooldown for it has passed since the webhook last posted it
776
+ * (so the webhook, which posts a kind at most once per cooldown, hears a
777
+ * failure that lasts), or after a pass in which that agent's maintenance
778
+ * went without a failure (maintenanceFailureReported). A record whose
779
+ * failure isn't reported again is marked as a repeat, and a pass whose
780
+ * every record is a repeat that took no tick stays out of the history.
781
+ */
782
+ private reportMaintenanceFailure;
783
+ /**
784
+ * An agent's context readiness, or the error that reading it threw. The
785
+ * context manager refuses while its strategy's initialization is pending
786
+ * or has failed (context-manager 0.14), and a strategy can refuse on its
787
+ * own, as the autobiographical one does after a store-level branch switch
788
+ * it hasn't reloaded for. Every such throw is that agent's failure.
789
+ */
790
+ private contextReadiness;
791
+ /** The strategy's progress snapshot, for diagnostics: one it can't give reads as none. */
560
792
  private contextProgress;
561
793
  /**
562
794
  * A server's request or notification the host couldn't handle, answered
@@ -590,6 +822,15 @@ export declare class AgentFramework {
590
822
  * result is dropped, and the drop is logged.
591
823
  */
592
824
  pushEvent(event: ProcessEvent): void;
825
+ /**
826
+ * A module's event. stop() closes the queue before it stops modules, so a
827
+ * module's event can arrive after that: from a listener that fires while
828
+ * stop() runs, or from the module's own stop(). Nothing will process it,
829
+ * and a throw there can go unhandled or fail stop(), so it's dropped with a
830
+ * log line naming the module. Otherwise it's queued as pushEvent() queues
831
+ * it, or, through the deprecated queue handle, without the trace.
832
+ */
833
+ private pushModuleEvent;
593
834
  /**
594
835
  * Add a trace event listener for observability.
595
836
  */
@@ -602,9 +843,11 @@ export declare class AgentFramework {
602
843
  */
603
844
  get channels(): ChannelRegistry | null;
604
845
  /**
605
- * Remove a trace event listener.
846
+ * Remove a trace event listener: its first subscription, if it holds more
847
+ * than one.
606
848
  */
607
849
  offTrace(listener: TraceEventListener): void;
850
+ private removeTraceRegistration;
608
851
  /**
609
852
  * Add a module at runtime.
610
853
  */
@@ -785,6 +1028,7 @@ export declare class AgentFramework {
785
1028
  timeoutMs?: number;
786
1029
  abandon?: boolean;
787
1030
  }): Promise<HostModeStatus>;
1031
+ private runQuiesce;
788
1032
  /** Cancel every turn-alive stream via the quiesce_abandoned kind and give
789
1033
  * teardown a bounded grace to settle. Shared by the drain-timeout path and
790
1034
  * the already-quiesced escalation path. */
@@ -800,6 +1044,7 @@ export declare class AgentFramework {
800
1044
  resume(opts?: {
801
1045
  force?: boolean;
802
1046
  }): Promise<HostModeStatus>;
1047
+ private runResume;
803
1048
  /**
804
1049
  * Land every deferred write whose target has no turn alive, one at a time,
805
1050
  * acknowledging each durably as it lands (the persisted queue is rewritten
@@ -870,13 +1115,28 @@ export declare class AgentFramework {
870
1115
  * were activated right now — WITHOUT running inference, opening a stream, or
871
1116
  * mutating agent state. Intended for debug/preview tooling.
872
1117
  *
873
- * Transparency contract (default): the preview is side-effect-free and
874
- * leaves no trace on the system. It does only read-only work —
875
- * `ContextManager.compile` (which never triggers compression itself;
876
- * compression runs in the background out-of-band), tool filtering, and
877
- * system-prompt assembly — then delegates to `Agent.buildActivationRequest`.
878
- * No tokens are spent, nothing is written to Chronicle, and no external
879
- * MCPL server is contacted.
1118
+ * What a preview commits (default): nothing of its own. It compiles as a
1119
+ * dry run (`dryRun`), filters tools and assembles the system prompt, then
1120
+ * delegates to `Agent.buildActivationRequest`. No tokens are spent, no
1121
+ * external MCPL server is contacted, no fold resolution is persisted and
1122
+ * none of the compression its fold plan calls for is queued; the consumed
1123
+ * watermark and any prepared budget change are left alone; and once
1124
+ * context-manager's thinking binding (context-manager#160, not yet
1125
+ * released) ships, no stamps are committed and no compile awaits
1126
+ * acceptance. In context-manager 0.14 its dry run leaves nothing else
1127
+ * behind but the release of an expired compression hold, as any compile
1128
+ * does (see `Agent.compileWithInjections`). The preview keeps in-memory
1129
+ * bookkeeping of its own, such as handing the context manager the
1130
+ * compression tool definitions, as every activation request does.
1131
+ * Under the autobiographical strategy, a budget the context can't fit
1132
+ * still throws, as for a committing compile: a dry run skips only
1133
+ * context-manager's post-pick check, and an adaptive fold plan that
1134
+ * doesn't fit then overruns at the middle's emission, with a refusal that
1135
+ * names the tokens and the limit. Windowed passthrough's newest message
1136
+ * alone is the one window that comes back larger than the budget. For a
1137
+ * verdict instead of the refusal, `previewContextSettings` returns
1138
+ * context-manager's own at a budget, with the agent's `maxTokens` reserved
1139
+ * for the response.
880
1140
  *
881
1141
  * The trade-off is fidelity: the dynamically-gathered ContextInjection[]
882
1142
  * (module `gatherContext` + MCPL `beforeInference` hooks) are NOT included
@@ -901,15 +1161,18 @@ export declare class AgentFramework {
901
1161
  *
902
1162
  * Unlike `previewActivation` (which renders a request), this returns the
903
1163
  * picker's plan: resulting tokens, whether it fits, how many summaries would
904
- * have to be produced first, and the per-chunk fold levels. Commits nothing:
905
- * no resolution persistence, no compression enqueue, no transition
906
- * bookkeeping — see `AutobiographicalStrategy.previewContext`.
1164
+ * have to be produced first, and the per-chunk fold levels. It commits
1165
+ * nothing: its select is a dry run, which in context-manager 0.14 leaves
1166
+ * what a select leaves behind as the last committing compile left it —
1167
+ * see `AutobiographicalStrategy.previewContext` and
1168
+ * `Agent.compileWithInjections`.
907
1169
  *
908
1170
  * Returns null when the agent's strategy has no fold plan (non-adaptive).
909
1171
  */
910
1172
  previewContextSettings(agentName: string, budgetTokens: number, overrides?: Record<string, unknown>, opts?: {
911
1173
  render?: boolean;
912
1174
  }): unknown;
1175
+ private previewContextFor;
913
1176
  /**
914
1177
  * Feasibility preview for a runtime-settings patch — or, with no patch, for
915
1178
  * the agent's CURRENT settings (the resume-gate case: quiesce maintenance
@@ -924,11 +1187,18 @@ export declare class AgentFramework {
924
1187
  * the compile budget and rejected safe-by-construction paced descents.
925
1188
  *
926
1189
  * Never throws for preview-layer reasons: strategy without previewContext,
927
- * preview overlap, stale branch generation, and the hierarchical (non-
928
- * adaptive) path all come back as `{available: false, reason}`. Unknown
929
- * agent still throws, matching the sibling accessors.
1190
+ * preview overlap, stale branch generation, the hierarchical (non-
1191
+ * adaptive) path, and a context manager that refuses its queries (its
1192
+ * strategy's initialization pending or failed) all come back as
1193
+ * `{available: false, reason}`. Unknown agent still throws, matching the
1194
+ * sibling accessors, and so does a patch whose values the agent refuses,
1195
+ * whatever its context manager's state. Whether the strategy takes live
1196
+ * tail and pace settings is the manager's to say, so while it refuses, a
1197
+ * patch that sets them gets no verdict either.
930
1198
  */
931
1199
  previewAgentRuntimeSettings(agentName: string, patch?: AgentRuntimeSettingsPatch): RuntimeSettingsPreview;
1200
+ /** previewAgentRuntimeSettings for an agent in hand: boot restore previews one not yet registered. */
1201
+ private previewRuntimeSettingsFor;
932
1202
  /**
933
1203
  * Check if process logging is enabled.
934
1204
  */
@@ -973,6 +1243,7 @@ export declare class AgentFramework {
973
1243
  getSessionUsage(): SessionUsageSnapshot;
974
1244
  private restoreUsageState;
975
1245
  private persistUsageState;
1246
+ /** An agent's persisted record, or null when it has none; throws when the store can't be read. */
976
1247
  private readAgentRuntimeSettings;
977
1248
  private validatePersistedAgentRuntimeSettings;
978
1249
  /** Load resident-set inline caps from framework state, dropping (loudly)
@@ -980,6 +1251,57 @@ export declare class AgentFramework {
980
1251
  private readPersistedToolResultInlineCaps;
981
1252
  /** Write (cap) or clear (null) one agent's resident-set inline cap. */
982
1253
  private persistToolResultInlineCap;
1254
+ /**
1255
+ * Apply an agent's persisted settings at boot, each on its own, the budget
1256
+ * last. A persisted setting never stops the agent booting, except a
1257
+ * think-text policy, which fails closed: an invalid one is refused before
1258
+ * this (validatePersistedAgentRuntimeSettings), and a valid one always
1259
+ * applies. A tail, pace or budget that can't be applied now (a tail or pace
1260
+ * on a strategy without live settings, a budget no longer above maxTokens,
1261
+ * a lower one restored paced on a strategy that can't prepare a smaller
1262
+ * window) is kept set but unapplied (Agent.keepRuntimeSettings), so a later
1263
+ * persisting write keeps it in the record.
1264
+ *
1265
+ * A budget below the recipe's restores as a paced descent from it, unless
1266
+ * the record carries its marker (`contextBudgetReachedTokens`, written when
1267
+ * a compile fit at it) and the preflight says it fits now: then it is
1268
+ * applied at once. The preflight plans the stored context as the context
1269
+ * manager will, with the restored tail and pace, so it sees what a restart
1270
+ * can change there: a new maxTokens (the response reserve) or strategy
1271
+ * configuration. It also sees a context that grew while the agent ran at
1272
+ * another budget after the record was written, through a persist: false
1273
+ * change. The system prompt, tools and injections are outside the context
1274
+ * manager's budget, so they don't enter it (context-manager #162). If a
1275
+ * compile at a budget applied at once this way is refused, the agent
1276
+ * restores it paced then (armed by Agent.restoreRuntimeSettings, run in
1277
+ * Agent.compileAtLiveBudgetNoting). A budget at or above the recipe's is
1278
+ * applied at once with or without the marker, as an increase always is.
1279
+ *
1280
+ * When a marked budget isn't applied at once or a setting can't be
1281
+ * applied, one line says why, what couldn't be applied, and the budget set
1282
+ * beside the one compiles plan at.
1283
+ */
1284
+ private restorePersistedRuntimeSettings;
1285
+ /**
1286
+ * What persists for an agent: its overrides, and `contextBudgetReachedTokens`
1287
+ * when the agent's proof stands for the overridden budget: a compile fit at
1288
+ * it, or the boot applied it at once on the record's proof, and the live
1289
+ * budget hasn't changed since (context-manager #162). A
1290
+ * change of budget, immediate or not, carries none until a compile at it
1291
+ * fits; arming or cancelling a descent leaves the proof as it was.
1292
+ */
1293
+ private persistedRuntimeSettingsOf;
1294
+ /**
1295
+ * A compile at the agent's live budget came out differently from the last
1296
+ * (Agent.onContextBudgetCompiled). Keep the persisted record's
1297
+ * `contextBudgetReachedTokens` true to it: written when a compile fits at
1298
+ * the record's own budget, withdrawn when the context manager refuses that
1299
+ * budget. Nothing else in the record changes, and a budget other than the
1300
+ * record's (one applied with `persist: false`, or a descent's starting
1301
+ * budget) writes nothing. A record that can't be read, or written, is
1302
+ * logged, and the next compile at that budget tells it again.
1303
+ */
1304
+ private recordCompiledContextBudget;
983
1305
  private persistAgentRuntimeSettings;
984
1306
  /** Persist (or clear, with null) the host quiesce mode. First process-global
985
1307
  * key in the framework/state slot: quiesce survives a restart BY DESIGN — a
@@ -1014,6 +1336,17 @@ export declare class AgentFramework {
1014
1336
  * events after an ephemeral/conversation agent has been disposed. */
1015
1337
  private recordLogicalTurnToolCalls;
1016
1338
  private recordEphemeralToolCalls;
1339
+ /**
1340
+ * A start dropped before its stream sends anything (its agent was replaced,
1341
+ * or stop() closed admission or ended the lifecycle the start began in)
1342
+ * ends the logical turn it was running. stop() ends every open turn
1343
+ * (openLogical), but a fresh start that awaited its batches' assembly
1344
+ * across a stop() reaches its routing after it and opens its turn. That
1345
+ * turn would then stay open, and the agent's first start after a restart
1346
+ * would continue the dropped turn's routing. The identity check leaves any
1347
+ * other turn open.
1348
+ */
1349
+ private endDroppedTurn;
1017
1350
  /** A logical turn's end, for every agent: it closes the agent's open
1018
1351
  * logical turn when it is the settling stream's own (openLogical), and
1019
1352
  * settles an active ephemeral run. The run's tool-call count comes from
@@ -1026,6 +1359,9 @@ export declare class AgentFramework {
1026
1359
  * The agent is temporarily registered, inference is triggered, and the
1027
1360
  * framework drives the stream (emitting traces, logging, dispatching tools).
1028
1361
  * Returns the agent's speech output when it finishes (no more tool calls).
1362
+ * Rejects with ProviderWaitNotSleptError when the run ends rather than sleep
1363
+ * a retryable failure's stated wait, and with a plain Error for any other
1364
+ * ending.
1029
1365
  *
1030
1366
  * The caller provides a pre-created agent + contextManager (from createEphemeralAgent).
1031
1367
  * The task message should already be in the context manager.
@@ -1169,8 +1505,14 @@ export declare class AgentFramework {
1169
1505
  *
1170
1506
  * host-status — report the quiesce state (drained / parked wakes /
1171
1507
  * running background scripts).
1508
+ *
1509
+ * release-provider-wait — end an agent's provider wait (a provider's
1510
+ * stated retry-after, kept across restarts) for one `model` or all, as an
1511
+ * explicit, recorded operator override.
1172
1512
  */
1173
1513
  private handleHostCommand;
1514
+ /** handleHostCommand's work, run where stop() can wait for it. */
1515
+ private runHostCommand;
1174
1516
  /**
1175
1517
  * The last message the agent would see in its context right now, via the
1176
1518
  * transparent `previewActivation` render (no inference, no Chronicle
@@ -1201,6 +1543,22 @@ export declare class AgentFramework {
1201
1543
  * Get the most recent process logs (tail).
1202
1544
  */
1203
1545
  tailProcessLogs(count?: number, eventType?: string): ProcessLogEntryWithId[];
1546
+ /**
1547
+ * Switch the store to an existing branch, start the delivery of the
1548
+ * Discord awareness marks the move changes (startDiscordAwarenessDelivery),
1549
+ * and re-materialize the config mount from it. Resolves once the mount has
1550
+ * run; if it fails, it rejects with the store already moved. The marks'
1551
+ * delivery isn't awaited, and its failure doesn't fail the switch. The
1552
+ * store has moved by the time the call returns, before its promise
1553
+ * settles, and a refusal moves nothing. An operator's operation: refused
1554
+ * once stop() has begun, and waited for by stop() while it runs.
1555
+ *
1556
+ * The branch moves under every agent sharing the store, so the switch
1557
+ * reserves the store as a surgery does: every agent must be idle, or it is
1558
+ * refused (OperatorActionError 'agent-busy'), and no turn starts until the
1559
+ * switch is done.
1560
+ */
1561
+ switchBranch(name: string): Promise<void>;
1204
1562
  /**
1205
1563
  * Undo the last inference turn for an agent.
1206
1564
  *
@@ -1217,6 +1575,9 @@ export declare class AgentFramework {
1217
1575
  fromBranch?: string;
1218
1576
  toBranch?: string;
1219
1577
  };
1578
+ /** undoLastTurn's work, for a host/command undo already admitted: a stop()
1579
+ * begun by a trace of one of its turns doesn't refuse the next. */
1580
+ private runUndoLastTurn;
1220
1581
  /**
1221
1582
  * Redo a previously undone turn for an agent.
1222
1583
  *
@@ -1271,6 +1632,12 @@ export declare class AgentFramework {
1271
1632
  * Discord messages that left the live context get awareness markers via the
1272
1633
  * durable outbox, exactly as message-granular `undo` does.
1273
1634
  *
1635
+ * Returns once the switch has landed: the body is applied, with a
1636
+ * marker-scheduling receipt (`markers`). It does not wait for Discord to
1637
+ * accept the reactions: delivery is started, behind the MCPL data-plane
1638
+ * gate, and continues without the caller or the store reservation waiting
1639
+ * on it; its per-message outcomes stay in the outbox ledger.
1640
+ *
1274
1641
  * Throws `OperatorActionError` (`agent-busy`, `unknown-message`, …) — the
1275
1642
  * agent must be idle; nothing is queued.
1276
1643
  */
@@ -1294,6 +1661,8 @@ export declare class AgentFramework {
1294
1661
  channelId: string;
1295
1662
  messageId: string;
1296
1663
  }>;
1664
+ /** Whether awareness marks were scheduled; never a delivery claim. */
1665
+ markers: SurgeryMarkerReceipt;
1297
1666
  lastVisible: {
1298
1667
  participant?: string;
1299
1668
  role?: string;
@@ -1307,6 +1676,9 @@ export declare class AgentFramework {
1307
1676
  * removed together. Discord originals get awareness markers via the outbox;
1308
1677
  * the batch is `explicit`-activated only after every removal succeeded, and
1309
1678
  * a crash mid-way is finished at next boot (resumePreparedDiscordSuppressions).
1679
+ * Like rollbackToMessage, it returns once the body change has landed, with
1680
+ * a marker-scheduling receipt (`markers`); delivery continues without the
1681
+ * caller waiting on it.
1310
1682
  *
1311
1683
  * Not retroactive over derived state: a message already folded into an
1312
1684
  * autobiographical summary stays in that summary — roll back to before it
@@ -1329,14 +1701,76 @@ export declare class AgentFramework {
1329
1701
  channelId: string;
1330
1702
  messageId: string;
1331
1703
  }>;
1704
+ /** Whether awareness marks were scheduled; never a delivery claim. */
1705
+ markers: SurgeryMarkerReceipt;
1332
1706
  lastVisible: {
1333
1707
  participant?: string;
1334
1708
  role?: string;
1335
1709
  preview?: string;
1336
1710
  } | null;
1337
1711
  }>;
1338
- /** Re-materialize config files from the (new) active branch — fire and
1339
- * forget; the gate picks changes up via mtime. Mirrors undoLastTurn. */
1712
+ /**
1713
+ * Record a surgery's prepared marker batch as active once its body change
1714
+ * has landed, and say what happened. Never throws: the body is already
1715
+ * applied, so a ledger failure here is reported in the receipt rather than
1716
+ * as a failed surgery an operator might retry. A batch that could not be
1717
+ * activated is retired, so no later reconciliation can deliver it behind a
1718
+ * receipt saying it was not scheduled (`not-scheduled`). If retiring fails
1719
+ * too, the receipt says only that the outcome is `unresolved`: the batch is
1720
+ * retained, and it may still be delivered. A rollback's batch
1721
+ * (activated by target branch) may be promoted by the very next
1722
+ * reconciliation, the one the delivery it starts runs; a suppression's
1723
+ * (activated explicitly) waits for the next start.
1724
+ *
1725
+ * A batch with no refs (a suppression journal with nothing addressable) is
1726
+ * still activated, which closes its resume journal. It schedules no marks,
1727
+ * so it reports `none` whatever the ledger does. If it can be neither
1728
+ * activated nor retired, its journal is left prepared and closes at the
1729
+ * next start: every interval it names has already committed, so the resume
1730
+ * skips them all and activates it.
1731
+ */
1732
+ private activateSurgeryMarkers;
1733
+ /**
1734
+ * Start awareness delivery after a branch move (a surgery, a switch, an
1735
+ * undo or redo) without the caller awaiting it. No operator response waits
1736
+ * for Discord to accept marks: the MCPL data-plane gate alone holds channel
1737
+ * traffic that arrives after it until they are attempted.
1738
+ * The sync's body installs that gate synchronously, before its first
1739
+ * await, so calling this while a surgery still holds the store puts the
1740
+ * gate up before the store is released. With no drain running, the
1741
+ * drain starts in the same synchronous run (the first reaction request can
1742
+ * be written before this returns); with one running, this generation's pass
1743
+ * follows it (drainForGeneration). Either way delivery continues
1744
+ * independently: the caller's response and any store reservation stop
1745
+ * waiting on remote reactions. A turn may run during delivery when its wake
1746
+ * carries no channel traffic (a scheduler timer, a provider admission), and
1747
+ * also when its channel traffic was admitted before the gate went up
1748
+ * (queued when a surgery began, or arriving during its switch or fork): the
1749
+ * surgery's store reservation, which used to hold such a turn through the
1750
+ * drain, now ends once the gate is up. A failure is accounted by the gate
1751
+ * itself: the current generation's failure recycles the connections (or,
1752
+ * once the host is stopping, releases the gate instead), and a superseded
1753
+ * one leaves that to the newer generation, whose own pass meets the same
1754
+ * ledger. Here it is logged and raised as an ops alert, and the next sync,
1755
+ * reconnect or start delivers what is still pending.
1756
+ *
1757
+ * Like a server's drain, the delivery runs apart from the operation that
1758
+ * started it: it isn't an operator's operation, so stop() doesn't wait for
1759
+ * it. A drain already running when stop() begins runs on while the
1760
+ * connections close, and what it can't deliver stays pending in the
1761
+ * durable outbox. Once stop() has begun, none is started, since there's
1762
+ * no point opening a drain that the teardown is about to cut off: the
1763
+ * marks stay pending, and the next start's barrier reconciles the outbox
1764
+ * with the branch and delivers them.
1765
+ *
1766
+ * @param after What moved the branch, for the log and the alert
1767
+ * ("rollback", "branch switch", "undo" …).
1768
+ * @param agentName The agent the move was for, or "framework" for a
1769
+ * branch switch that names none.
1770
+ */
1771
+ startDiscordAwarenessDelivery(after: string, agentName?: string): void;
1772
+ /** Start config file IO without holding the caller or a surgery's store
1773
+ * reservation. The gate picks it up by mtime; stop() still waits for it. */
1340
1774
  private materializeConfigMountAfterBranchSwitch;
1341
1775
  /**
1342
1776
  * Check if undo/redo is available for an agent.
@@ -1419,9 +1853,10 @@ export declare class AgentFramework {
1419
1853
  /**
1420
1854
  * Spawn a persistent per-channel conversation agent ("fork") from the
1421
1855
  * template agent: own ContextManager under `conversations/{name}`, seeded
1422
- * with a copy of the template's compiled context (the SubagentModule
1423
- * wholesale-copy pattern), registered in the event loop like any agent —
1424
- * but never primary.
1856
+ * with the template's compiled context without its thinking or its unpaired
1857
+ * tool blocks (the SubagentModule wholesale-copy pattern; see the seeding
1858
+ * comment below), registered in the event loop like any agent — but never
1859
+ * primary.
1425
1860
  */
1426
1861
  private createConversationAgent;
1427
1862
  /** Persist the router's generation counters (see hydration in create()). */
@@ -1590,6 +2025,59 @@ export declare class AgentFramework {
1590
2025
  * inference; never locus-eligible itself (system + no channel metadata).
1591
2026
  */
1592
2027
  private announceLocusIfChanged;
2028
+ /**
2029
+ * The channel a message moves its turn's locus to, by the addressed
2030
+ * re-pin rule (2026-07-31, n=6 and n=7): a conversational message (not a
2031
+ * reaction or a system marker) that addressed the agent, or that follows
2032
+ * up in a channel the turn sent into (TurnRouting.engaged). Undefined for
2033
+ * any other message. A tool boundary weighs the messages it injects by it,
2034
+ * and noteArrival the ones no boundary of the turn weighs.
2035
+ */
2036
+ private repinChannel;
2037
+ /**
2038
+ * Weigh a message that no tool boundary of the agent's open logical turn
2039
+ * will weigh: one that would re-pin the locus becomes one of the turn's
2040
+ * arrivals (TurnRouting.arrivals). A message tune-out diverted
2041
+ * (metadata.tuneOut) never enters a resident's compiled view, so the agent
2042
+ * won't see it, and it moves nothing.
2043
+ */
2044
+ private noteArrival;
2045
+ /**
2046
+ * Whether `agent`'s store is the residents' one message slot, which every
2047
+ * ordinary resident reads (sharedSlotAgents). The subconscious reads that
2048
+ * slot through a merged view, but its own store is isolated, as a fork's
2049
+ * or an ephemeral agent's is.
2050
+ */
2051
+ private isOrdinaryResident;
2052
+ /**
2053
+ * Weigh a message just stored in an ordinary resident's store for every
2054
+ * other ordinary resident's open turn, running or not: residents read one
2055
+ * message slot, and a tool boundary weighs only the messages drained for
2056
+ * its own agent, so no boundary of another resident's turn weighs it.
2057
+ */
2058
+ private noteForOtherResidents;
2059
+ /**
2060
+ * The channel of the turn's newest arrival whose message is still in the
2061
+ * agent's store (TurnRouting.arrivals). A message removed since it was
2062
+ * stored, such as an unread coalesced message its server retracted, moves
2063
+ * nothing, and an earlier one that remains still does. Compression keeps a
2064
+ * message in the store; the last compile can't be the test, since an
2065
+ * arrival between the turn's streams isn't in it yet.
2066
+ */
2067
+ private remainingArrival;
2068
+ /**
2069
+ * Move a turn's locus to the channel its conversation moved to: an
2070
+ * addressed message, or a follow-up in a channel the turn engaged (the
2071
+ * addressed re-pin, repinChannel). Ambient chatter never moves it. Leaves
2072
+ * a durable `[routing]` notice in the window and updates
2073
+ * lastAnnouncedLocus once it's stored, so the next turn's announce-on-change
2074
+ * diffs against what the agent was last told. Returns the notice as stored, for a live
2075
+ * stream to inject with its boundary's other messages. Returns undefined
2076
+ * when the locus is already there, and when the notice couldn't be
2077
+ * stored. The locus has moved then too, but the announce baseline hasn't,
2078
+ * so the agent's next turn announces where its speech lands.
2079
+ */
2080
+ private repinTurnLocus;
1593
2081
  /**
1594
2082
  * Durable window notice for a channel the agent did not ask to open —
1595
2083
  * subscription-policy admission, or an open forced by the agent's own
@@ -1649,6 +2137,18 @@ export declare class AgentFramework {
1649
2137
  */
1650
2138
  private maybePrimeProseMode;
1651
2139
  private startAgentStream;
2140
+ /**
2141
+ * End a turn that beginAgentTurn drops before it sends anything. The turn
2142
+ * emitted inference:started, and listeners that bracket a turn, such as a
2143
+ * typing loop or an activity indicator, end it on a terminal event, so it
2144
+ * gets inference:aborted with `reason`, and lastInference records its end
2145
+ * as driveStream's would, when the record is still this turn's. Nothing of
2146
+ * the kind when another turn of this agent's name holds the turn token (one
2147
+ * begun after a stop and start, or by a replacement agent object): the
2148
+ * event and the record carry only the name, so this frame's would end that
2149
+ * newer turn instead.
2150
+ */
2151
+ private abortDroppedTurn;
1652
2152
  /**
1653
2153
  * Body of startAgentStream, split out so the caller's try/finally owns the
1654
2154
  * turn token unconditionally. Returns true iff the token was handed off to
@@ -1710,6 +2210,8 @@ export declare class AgentFramework {
1710
2210
  toolUseId: string;
1711
2211
  result: ToolResult;
1712
2212
  }>;
2213
+ /** puppetToolCall's work, run where stop() can wait for it. */
2214
+ private runPuppetToolCall;
1713
2215
  private executeToolCallFrom;
1714
2216
  private executeMcplToolCall;
1715
2217
  /** Event-pushing wrapper for the model-driven dispatch path. */
@@ -1919,15 +2421,18 @@ export declare class AgentFramework {
1919
2421
  * inference, so this never causes a retry/wake loop.
1920
2422
  * 3. escalation — after N consecutive failures the agent is hard-down;
1921
2423
  * log that loudly (a repeated identical failure is the textbook signal).
1922
- * 4. breaker — when the failures are an `invalid_request` (a 400-class
1923
- * rejection of the history itself, e.g. corrupted tool_use/tool_result
1924
- * pairing or an oversized attachment), retrying the same context can
1925
- * never succeed: every new push event wakes the agent onto the same
1926
- * poisoned history forever. At the hard-down threshold, automatically
1927
- * quarantine: shed the newest complete exchange (the same forced-rewind
1928
- * primitive `/unstick` uses — shedNewestTurn never orphans a
1929
- * tool_use/thinking block) and retry, bounded by the same rewind cap so
1930
- * the breaker can never eat the whole history.
2424
+ * 4. breaker — when a failure at or past the hard-down threshold suggests
2425
+ * the provider refused the request's content or size (shedMayHelp:
2426
+ * an `invalid_request` at HTTP 400, 413 or 422 or with no status, or a
2427
+ * `context_length` at 413, such as a provider's answer to a corrupted
2428
+ * tool_use/tool_result pairing or an oversized attachment), retrying
2429
+ * the same context is likely to fail the same way, and every new push
2430
+ * event would wake the agent onto that same history. At the hard-down
2431
+ * threshold, automatically quarantine: shed the newest complete
2432
+ * exchange (the same forced-rewind primitive `/unstick` uses —
2433
+ * shedNewestTurn never orphans a tool_use/thinking block) and retry,
2434
+ * bounded by the same rewind cap so the breaker can never eat the
2435
+ * whole history.
1931
2436
  */
1932
2437
  /**
1933
2438
  * Live health snapshot for /healthz and doctor tooling: gate state, queued
@@ -1969,9 +2474,12 @@ export declare class AgentFramework {
1969
2474
  private noteRefusal;
1970
2475
  /**
1971
2476
  * Classify a terminal inference error for the `inference:exhausted` trace.
1972
- * Single-sourced for every emit site: the downstream breakers (poison-history
1973
- * quarantine, OverBudget drain kick) gate on `errorType`, so classification
1974
- * drift between sites would silently disable a safety net.
2477
+ * Single-sourced for every emit site that has an error to classify (a
2478
+ * stream the framework aborted has none): the downstream breakers gate on
2479
+ * what it returns (the poison-history quarantine on `errorType` and
2480
+ * `httpStatus`, through shedMayHelp; the OverBudget drain kick on
2481
+ * `errorType`), so classification drift between sites would silently
2482
+ * change when a safety net acts.
1975
2483
  *
1976
2484
  * context-manager's refusal errors are matched by a real `instanceof` since
1977
2485
  * CM exports them from its package root (context-manager#41 / #71; floor
@@ -1998,7 +2506,7 @@ export declare class AgentFramework {
1998
2506
  * primitives as the refusal auto-rewind / `/unstick` (shedNewestTurn +
1999
2507
  * the single consolidated episode marker) — and queues a retry so the
2000
2508
  * rewound history is verified immediately instead of waiting for the next
2001
- * push event to wake the agent onto the same poisoned context.
2509
+ * push event to wake the agent onto the same context.
2002
2510
  *
2003
2511
  * Bounded: at most `refusalHandling.maxRewinds` (default 3, hard cap 10)
2004
2512
  * sheds per failure episode; the budget resets on any successful inference.
@@ -2011,8 +2519,19 @@ export declare class AgentFramework {
2011
2519
  * Fail-open: individual server connection failures don't prevent framework startup.
2012
2520
  */
2013
2521
  private initializeMcpl;
2014
- /** Reconcile the durable ledger with Chronicle, then deliver every server's work. */
2015
- syncDiscordAwarenessMarkers(_onlyServerId?: string): Promise<void>;
2522
+ /**
2523
+ * Reconcile the durable ledger with Chronicle, then deliver every server's
2524
+ * work. A drain still running is waited for and then followed by a fresh
2525
+ * pass (drainForGeneration). Like the other operator entry points, it's
2526
+ * refused once stop() has begun, and stop() waits for one already running.
2527
+ * The framework's own branch moves start their delivery without awaiting
2528
+ * it (startDiscordAwarenessDelivery).
2529
+ */
2530
+ syncDiscordAwarenessMarkers(onlyServerId?: string): Promise<void>;
2531
+ /** The sync's work. It installs the MCPL data-plane gate before its first
2532
+ * await, so a caller that starts it while holding the store puts the gate
2533
+ * up before releasing the store. */
2534
+ private runDiscordAwarenessSync;
2016
2535
  private resumePreparedDiscordSuppressions;
2017
2536
  /**
2018
2537
  * Deliver every due ref independently. Permanent Discord failures are kept
@@ -2024,12 +2543,32 @@ export declare class AgentFramework {
2024
2543
  private writeDiscordAwarenessSuccess;
2025
2544
  private writeDiscordAwarenessFailure;
2026
2545
  private beginDiscordAwarenessBarrier;
2546
+ /**
2547
+ * One server's drain for a new generation: a gate completes only after
2548
+ * every operation pending when it was armed has been attempted. A drain
2549
+ * already running can't promise that. It never re-sends a key it has
2550
+ * attempted, so an operation re-pended while it runs (a rollback, its undo,
2551
+ * then a redo, all mid-drain) stays pending, and it may already have made
2552
+ * its last read of the ledger, missing a batch activated since. So a
2553
+ * generation that finds a drain running waits for it, then drains again
2554
+ * with a fresh pass that reads the ledger anew. Two generations waiting on
2555
+ * the same drain share the fresh pass that follows it.
2556
+ */
2557
+ private drainForGeneration;
2558
+ /**
2559
+ * Wait out the awareness gate for an inbound event: the generation current
2560
+ * now, and any generation installed while waiting, until none is current
2561
+ * or the current one is one already waited for. A handler that waited only
2562
+ * for the generation it first saw would go on behind a newer one armed
2563
+ * meanwhile. Rejects as the generation it waited for rejects.
2564
+ */
2565
+ private awaitDiscordAwarenessBarriers;
2027
2566
  /**
2028
2567
  * Install one framework-global Discord-awareness generation before releasing
2029
- * any inference-bearing event. With pending work, every MCPL data plane is
2030
- * paused while all control planes remain live. With no pending work, ready()
2031
- * runs synchronously so request responders preserve their historical
2032
- * same-stack behavior.
2568
+ * any inference-bearing event. With pending work or a drain still running,
2569
+ * every MCPL data plane is paused while all control planes remain live.
2570
+ * With neither, ready() runs synchronously so request responders preserve
2571
+ * their historical same-stack behavior.
2033
2572
  */
2034
2573
  private installMcplDataPlaneGate;
2035
2574
  private releaseMcplDataPlaneGate;
@@ -2079,6 +2618,43 @@ export declare class AgentFramework {
2079
2618
  * disconnect are resumed, not reset.
2080
2619
  */
2081
2620
  private registerMcplServerFeatures;
2621
+ /**
2622
+ * Snapshot the protective Discord reaction default for this deployment, as
2623
+ * suppression tokens: the forms the Discord adapter's suppression matcher
2624
+ * reads, not marker payloads for an add, a remove or a replay. It covers
2625
+ * the reactions the framework places: refusal markers, the adapter's own
2626
+ * default awareness marker, the configured awareness marker, and retained
2627
+ * outbox markers (including offline recovery choices and marks that can
2628
+ * later be removed or replayed). A custom emoji appears as its bare ID,
2629
+ * which suppression matches even after a rename; stored markers and the
2630
+ * actual add/remove payloads stay unchanged. Explicit adapter or operator
2631
+ * suppression settings still take precedence. Throws on an unreadable
2632
+ * ledger rather than reporting a partial baseline.
2633
+ */
2634
+ getPlacedReactionBaseline(): readonly string[];
2635
+ /**
2636
+ * The reaction baseline an operator chose for a stdio server, if any: a
2637
+ * value declared in its env, or one inherited from the host with
2638
+ * `inheritEnv`, the declared one first. A value with no tokens, as
2639
+ * discord-mcpl's parser reads them, counts as unset: the adapter splits on
2640
+ * commas and keeps a token only when its normalizer leaves something of it
2641
+ * (blank, `:`, `::` and a lone U+FE0F leave nothing), so such a value (an
2642
+ * empty systemd `Environment=`, say, or `${A},${B}` or `:${NAME}:` with the
2643
+ * variables empty) would otherwise turn the protective default off without
2644
+ * anyone choosing that.
2645
+ *
2646
+ * Windows names are matched in both sources: Workers expose a case-
2647
+ * sensitive `process.env` copy. Within one source, Node's spawn keeps the
2648
+ * first spelling in sorted order, so each source is resolved that way.
2649
+ *
2650
+ * A value is read as the child will see it. A config loaded from JSON can
2651
+ * carry a non-string there despite the type, and spawn writes every
2652
+ * defined value as its string form, so a number is a declared value, not a
2653
+ * failed connect. A null counts as unset, like a blank: written in JSON it
2654
+ * means no value, and read as spawn's "null" it would replace the
2655
+ * protective default with a list that suppresses nothing.
2656
+ */
2657
+ private declaredReactionBaseline;
2082
2658
  /**
2083
2659
  * Connect a new MCPL server at runtime. Refreshes the tool list and
2084
2660
  * notifies the agent of newly available tools. Throws if the MCPL
@@ -2086,6 +2662,7 @@ export declare class AgentFramework {
2086
2662
  * connection/handshake fails.
2087
2663
  */
2088
2664
  connectMcplServer(config: import('./mcpl/types.js').McplServerConfig): Promise<void>;
2665
+ private runConnectMcplServer;
2089
2666
  /**
2090
2667
  * Disconnect an MCPL server at runtime: close the connection, destroy its
2091
2668
  * feature-set and checkpoint state (permanent removal — unlike a transient
@@ -2094,6 +2671,7 @@ export declare class AgentFramework {
2094
2671
  * No-op-ish if the server is not connected (still clears routing state).
2095
2672
  */
2096
2673
  disconnectMcplServer(id: string): Promise<void>;
2674
+ private runDisconnectMcplServer;
2097
2675
  /**
2098
2676
  * Restart an MCPL server at runtime: disconnect, then reconnect with the
2099
2677
  * same (or an updated) config. This actually respawns a stdio child —
@@ -2101,6 +2679,7 @@ export declare class AgentFramework {
2101
2679
  * failures. Throws if the server has no stored config and none is given.
2102
2680
  */
2103
2681
  restartMcplServer(id: string, newConfig?: import('./mcpl/types.js').McplServerConfig): Promise<void>;
2682
+ private runRestartMcplServer;
2104
2683
  /**
2105
2684
  * List configured MCPL servers with live connection status and the number
2106
2685
  * of tools each currently contributes.