@animalabs/agent-framework 0.22.2 → 0.22.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (935) hide show
  1. package/README.md +3 -1
  2. package/dist/src/agent.d.ts +77 -12
  3. package/dist/src/agent.d.ts.map +1 -1
  4. package/dist/src/agent.js +136 -40
  5. package/dist/src/agent.js.map +1 -1
  6. package/dist/src/api/mcp-server-core.js +1 -1
  7. package/dist/src/api/mcp-server-core.js.map +1 -1
  8. package/dist/src/api/server.d.ts.map +1 -1
  9. package/dist/src/api/server.js +5 -1
  10. package/dist/src/api/server.js.map +1 -1
  11. package/dist/src/api/types.d.ts +1 -1
  12. package/dist/src/api/types.d.ts.map +1 -1
  13. package/dist/src/branch-names.d.ts +14 -0
  14. package/dist/src/branch-names.d.ts.map +1 -0
  15. package/dist/src/branch-names.js +22 -0
  16. package/dist/src/branch-names.js.map +1 -0
  17. package/dist/src/closest-names.d.ts +28 -0
  18. package/dist/src/closest-names.d.ts.map +1 -0
  19. package/dist/src/closest-names.js +98 -0
  20. package/dist/src/closest-names.js.map +1 -0
  21. package/dist/src/code-execution/py-runner.d.ts +16 -5
  22. package/dist/src/code-execution/py-runner.d.ts.map +1 -1
  23. package/dist/src/code-execution/py-runner.js +186 -74
  24. package/dist/src/code-execution/py-runner.js.map +1 -1
  25. package/dist/src/code-execution/runtime-py.d.ts.map +1 -1
  26. package/dist/src/code-execution/runtime-py.js +49 -3
  27. package/dist/src/code-execution/runtime-py.js.map +1 -1
  28. package/dist/src/code-execution/tool-definition.d.ts +12 -1
  29. package/dist/src/code-execution/tool-definition.d.ts.map +1 -1
  30. package/dist/src/code-execution/tool-definition.js +21 -3
  31. package/dist/src/code-execution/tool-definition.js.map +1 -1
  32. package/dist/src/config-checks.d.ts +28 -0
  33. package/dist/src/config-checks.d.ts.map +1 -0
  34. package/dist/src/config-checks.js +52 -0
  35. package/dist/src/config-checks.js.map +1 -0
  36. package/dist/src/deadline-timer.d.ts +21 -0
  37. package/dist/src/deadline-timer.d.ts.map +1 -0
  38. package/dist/src/deadline-timer.js +43 -0
  39. package/dist/src/deadline-timer.js.map +1 -0
  40. package/dist/src/error-message.d.ts +30 -0
  41. package/dist/src/error-message.d.ts.map +1 -0
  42. package/dist/src/error-message.js +50 -0
  43. package/dist/src/error-message.js.map +1 -0
  44. package/dist/src/framework.d.ts +828 -88
  45. package/dist/src/framework.d.ts.map +1 -1
  46. package/dist/src/framework.js +5011 -1326
  47. package/dist/src/framework.js.map +1 -1
  48. package/dist/src/gate/event-gate.d.ts +8 -0
  49. package/dist/src/gate/event-gate.d.ts.map +1 -1
  50. package/dist/src/gate/event-gate.js +27 -3
  51. package/dist/src/gate/event-gate.js.map +1 -1
  52. package/dist/src/index.d.ts +4 -2
  53. package/dist/src/index.d.ts.map +1 -1
  54. package/dist/src/index.js +4 -2
  55. package/dist/src/index.js.map +1 -1
  56. package/dist/src/mcpl/channel-registry.d.ts +144 -6
  57. package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
  58. package/dist/src/mcpl/channel-registry.js +424 -263
  59. package/dist/src/mcpl/channel-registry.js.map +1 -1
  60. package/dist/src/mcpl/checkpoint-manager.d.ts +21 -1
  61. package/dist/src/mcpl/checkpoint-manager.d.ts.map +1 -1
  62. package/dist/src/mcpl/checkpoint-manager.js +91 -30
  63. package/dist/src/mcpl/checkpoint-manager.js.map +1 -1
  64. package/dist/src/mcpl/conversation-router.d.ts +19 -3
  65. package/dist/src/mcpl/conversation-router.d.ts.map +1 -1
  66. package/dist/src/mcpl/conversation-router.js +23 -8
  67. package/dist/src/mcpl/conversation-router.js.map +1 -1
  68. package/dist/src/mcpl/convert-block.d.ts +20 -0
  69. package/dist/src/mcpl/convert-block.d.ts.map +1 -0
  70. package/dist/src/mcpl/convert-block.js +89 -0
  71. package/dist/src/mcpl/convert-block.js.map +1 -0
  72. package/dist/src/mcpl/errors.d.ts +13 -0
  73. package/dist/src/mcpl/errors.d.ts.map +1 -1
  74. package/dist/src/mcpl/errors.js +28 -0
  75. package/dist/src/mcpl/errors.js.map +1 -1
  76. package/dist/src/mcpl/hook-orchestrator.d.ts +23 -0
  77. package/dist/src/mcpl/hook-orchestrator.d.ts.map +1 -1
  78. package/dist/src/mcpl/hook-orchestrator.js +83 -72
  79. package/dist/src/mcpl/hook-orchestrator.js.map +1 -1
  80. package/dist/src/mcpl/inbound-source.d.ts +114 -0
  81. package/dist/src/mcpl/inbound-source.d.ts.map +1 -0
  82. package/dist/src/mcpl/inbound-source.js +83 -0
  83. package/dist/src/mcpl/inbound-source.js.map +1 -0
  84. package/dist/src/mcpl/index.d.ts +3 -1
  85. package/dist/src/mcpl/index.d.ts.map +1 -1
  86. package/dist/src/mcpl/index.js +3 -1
  87. package/dist/src/mcpl/index.js.map +1 -1
  88. package/dist/src/mcpl/inference-router.d.ts +15 -11
  89. package/dist/src/mcpl/inference-router.d.ts.map +1 -1
  90. package/dist/src/mcpl/inference-router.js +153 -84
  91. package/dist/src/mcpl/inference-router.js.map +1 -1
  92. package/dist/src/mcpl/push-coalescer.d.ts +33 -11
  93. package/dist/src/mcpl/push-coalescer.d.ts.map +1 -1
  94. package/dist/src/mcpl/push-coalescer.js +52 -20
  95. package/dist/src/mcpl/push-coalescer.js.map +1 -1
  96. package/dist/src/mcpl/push-handler.d.ts +16 -9
  97. package/dist/src/mcpl/push-handler.d.ts.map +1 -1
  98. package/dist/src/mcpl/push-handler.js +18 -83
  99. package/dist/src/mcpl/push-handler.js.map +1 -1
  100. package/dist/src/mcpl/reference-fetcher.d.ts +14 -2
  101. package/dist/src/mcpl/reference-fetcher.d.ts.map +1 -1
  102. package/dist/src/mcpl/reference-fetcher.js +72 -30
  103. package/dist/src/mcpl/reference-fetcher.js.map +1 -1
  104. package/dist/src/mcpl/references.d.ts +47 -12
  105. package/dist/src/mcpl/references.d.ts.map +1 -1
  106. package/dist/src/mcpl/references.js +74 -21
  107. package/dist/src/mcpl/references.js.map +1 -1
  108. package/dist/src/mcpl/server-connection.d.ts +89 -10
  109. package/dist/src/mcpl/server-connection.d.ts.map +1 -1
  110. package/dist/src/mcpl/server-connection.js +405 -129
  111. package/dist/src/mcpl/server-connection.js.map +1 -1
  112. package/dist/src/mcpl/server-registry.d.ts +10 -1
  113. package/dist/src/mcpl/server-registry.d.ts.map +1 -1
  114. package/dist/src/mcpl/server-registry.js +14 -3
  115. package/dist/src/mcpl/server-registry.js.map +1 -1
  116. package/dist/src/mcpl/skip-reply-wake.d.ts +36 -0
  117. package/dist/src/mcpl/skip-reply-wake.d.ts.map +1 -0
  118. package/dist/src/mcpl/skip-reply-wake.js +55 -0
  119. package/dist/src/mcpl/skip-reply-wake.js.map +1 -0
  120. package/dist/src/mcpl/transport.d.ts +51 -2
  121. package/dist/src/mcpl/transport.d.ts.map +1 -1
  122. package/dist/src/mcpl/transport.js +114 -20
  123. package/dist/src/mcpl/transport.js.map +1 -1
  124. package/dist/src/mcpl/types.d.ts +14 -3
  125. package/dist/src/mcpl/types.d.ts.map +1 -1
  126. package/dist/src/mcpl/types.js.map +1 -1
  127. package/dist/src/mcpl/visible-content.d.ts +15 -0
  128. package/dist/src/mcpl/visible-content.d.ts.map +1 -1
  129. package/dist/src/mcpl/visible-content.js +25 -0
  130. package/dist/src/mcpl/visible-content.js.map +1 -1
  131. package/dist/src/module-registry.d.ts +19 -1
  132. package/dist/src/module-registry.d.ts.map +1 -1
  133. package/dist/src/module-registry.js +54 -25
  134. package/dist/src/module-registry.js.map +1 -1
  135. package/dist/src/modules/api/index.js +1 -1
  136. package/dist/src/modules/api/index.js.map +1 -1
  137. package/dist/src/modules/discord/discord-js-client.d.ts +1 -0
  138. package/dist/src/modules/discord/discord-js-client.d.ts.map +1 -1
  139. package/dist/src/modules/discord/discord-js-client.js +25 -9
  140. package/dist/src/modules/discord/discord-js-client.js.map +1 -1
  141. package/dist/src/modules/discord/index.d.ts +29 -3
  142. package/dist/src/modules/discord/index.d.ts.map +1 -1
  143. package/dist/src/modules/discord/index.js +379 -143
  144. package/dist/src/modules/discord/index.js.map +1 -1
  145. package/dist/src/modules/discord/types.d.ts +14 -1
  146. package/dist/src/modules/discord/types.d.ts.map +1 -1
  147. package/dist/src/modules/health/index.d.ts.map +1 -1
  148. package/dist/src/modules/health/index.js +2 -1
  149. package/dist/src/modules/health/index.js.map +1 -1
  150. package/dist/src/modules/history/index.d.ts +3 -1
  151. package/dist/src/modules/history/index.d.ts.map +1 -1
  152. package/dist/src/modules/history/index.js +359 -127
  153. package/dist/src/modules/history/index.js.map +1 -1
  154. package/dist/src/modules/history/semantic.d.ts +28 -1
  155. package/dist/src/modules/history/semantic.d.ts.map +1 -1
  156. package/dist/src/modules/history/semantic.js +177 -32
  157. package/dist/src/modules/history/semantic.js.map +1 -1
  158. package/dist/src/modules/unknown-tool.d.ts +10 -0
  159. package/dist/src/modules/unknown-tool.d.ts.map +1 -0
  160. package/dist/src/modules/unknown-tool.js +17 -0
  161. package/dist/src/modules/unknown-tool.js.map +1 -0
  162. package/dist/src/modules/workspace/disk-agreement.d.ts +32 -2
  163. package/dist/src/modules/workspace/disk-agreement.d.ts.map +1 -1
  164. package/dist/src/modules/workspace/disk-agreement.js +30 -2
  165. package/dist/src/modules/workspace/disk-agreement.js.map +1 -1
  166. package/dist/src/modules/workspace/effects.d.ts +64 -6
  167. package/dist/src/modules/workspace/effects.d.ts.map +1 -1
  168. package/dist/src/modules/workspace/effects.js +291 -44
  169. package/dist/src/modules/workspace/effects.js.map +1 -1
  170. package/dist/src/modules/workspace/index.d.ts +119 -23
  171. package/dist/src/modules/workspace/index.d.ts.map +1 -1
  172. package/dist/src/modules/workspace/index.js +793 -247
  173. package/dist/src/modules/workspace/index.js.map +1 -1
  174. package/dist/src/modules/workspace/observe.d.ts +75 -8
  175. package/dist/src/modules/workspace/observe.d.ts.map +1 -1
  176. package/dist/src/modules/workspace/observe.js +174 -14
  177. package/dist/src/modules/workspace/observe.js.map +1 -1
  178. package/dist/src/modules/workspace/reconcile.d.ts +58 -7
  179. package/dist/src/modules/workspace/reconcile.d.ts.map +1 -1
  180. package/dist/src/modules/workspace/reconcile.js +521 -56
  181. package/dist/src/modules/workspace/reconcile.js.map +1 -1
  182. package/dist/src/modules/workspace/types.d.ts +18 -4
  183. package/dist/src/modules/workspace/types.d.ts.map +1 -1
  184. package/dist/src/modules/workspace/types.js.map +1 -1
  185. package/dist/src/modules/workspace/watcher.d.ts +7 -2
  186. package/dist/src/modules/workspace/watcher.d.ts.map +1 -1
  187. package/dist/src/modules/workspace/watcher.js +28 -4
  188. package/dist/src/modules/workspace/watcher.js.map +1 -1
  189. package/dist/src/prose-drafts.d.ts +240 -0
  190. package/dist/src/prose-drafts.d.ts.map +1 -0
  191. package/dist/src/prose-drafts.js +362 -0
  192. package/dist/src/prose-drafts.js.map +1 -0
  193. package/dist/src/prose-segments.d.ts +21 -2
  194. package/dist/src/prose-segments.d.ts.map +1 -1
  195. package/dist/src/prose-segments.js +46 -9
  196. package/dist/src/prose-segments.js.map +1 -1
  197. package/dist/src/recovery/offline-branch.d.ts +1 -0
  198. package/dist/src/recovery/offline-branch.d.ts.map +1 -1
  199. package/dist/src/recovery/offline-branch.js +3 -1
  200. package/dist/src/recovery/offline-branch.js.map +1 -1
  201. package/dist/src/safe-slice.d.ts +5 -1
  202. package/dist/src/safe-slice.d.ts.map +1 -1
  203. package/dist/src/safe-slice.js +9 -1
  204. package/dist/src/safe-slice.js.map +1 -1
  205. package/dist/src/tool-image-ledger.d.ts +87 -19
  206. package/dist/src/tool-image-ledger.d.ts.map +1 -1
  207. package/dist/src/tool-image-ledger.js +135 -32
  208. package/dist/src/tool-image-ledger.js.map +1 -1
  209. package/dist/src/tool-presentation.d.ts +9 -0
  210. package/dist/src/tool-presentation.d.ts.map +1 -1
  211. package/dist/src/tool-presentation.js +257 -60
  212. package/dist/src/tool-presentation.js.map +1 -1
  213. package/dist/src/tool-result-guard.d.ts.map +1 -1
  214. package/dist/src/tool-result-guard.js +7 -10
  215. package/dist/src/tool-result-guard.js.map +1 -1
  216. package/dist/src/tool-result-history.d.ts +32 -3
  217. package/dist/src/tool-result-history.d.ts.map +1 -1
  218. package/dist/src/tool-result-history.js +106 -19
  219. package/dist/src/tool-result-history.js.map +1 -1
  220. package/dist/src/tune-out/coordinator.d.ts +25 -1
  221. package/dist/src/tune-out/coordinator.d.ts.map +1 -1
  222. package/dist/src/tune-out/coordinator.js +260 -65
  223. package/dist/src/tune-out/coordinator.js.map +1 -1
  224. package/dist/src/types/agent.d.ts +17 -5
  225. package/dist/src/types/agent.d.ts.map +1 -1
  226. package/dist/src/types/events.d.ts +17 -0
  227. package/dist/src/types/events.d.ts.map +1 -1
  228. package/dist/src/types/framework.d.ts +21 -5
  229. package/dist/src/types/framework.d.ts.map +1 -1
  230. package/dist/src/types/inference-log.d.ts +1 -1
  231. package/dist/src/types/inference-log.d.ts.map +1 -1
  232. package/dist/src/types/module.d.ts +23 -4
  233. package/dist/src/types/module.d.ts.map +1 -1
  234. package/dist/src/types/trace.d.ts +95 -6
  235. package/dist/src/types/trace.d.ts.map +1 -1
  236. package/dist/src/usage/usage-tracker.d.ts +5 -0
  237. package/dist/src/usage/usage-tracker.d.ts.map +1 -1
  238. package/dist/src/usage/usage-tracker.js +35 -8
  239. package/dist/src/usage/usage-tracker.js.map +1 -1
  240. package/package.json +3 -4
  241. package/src/agent.ts +162 -40
  242. package/src/api/mcp-server-core.ts +1 -1
  243. package/src/api/server.ts +4 -1
  244. package/src/api/types.ts +1 -1
  245. package/src/branch-names.ts +19 -0
  246. package/src/closest-names.ts +94 -0
  247. package/src/code-execution/py-runner.ts +200 -76
  248. package/src/code-execution/runtime-py.ts +49 -3
  249. package/src/code-execution/tool-definition.ts +28 -4
  250. package/src/config-checks.ts +48 -0
  251. package/src/deadline-timer.ts +44 -0
  252. package/src/error-message.ts +48 -0
  253. package/src/framework.ts +5352 -1388
  254. package/src/gate/event-gate.ts +28 -3
  255. package/src/index.ts +11 -2
  256. package/src/mcpl/channel-registry.ts +517 -286
  257. package/src/mcpl/checkpoint-manager.ts +104 -29
  258. package/src/mcpl/conversation-router.ts +28 -8
  259. package/src/mcpl/convert-block.ts +97 -0
  260. package/src/mcpl/errors.ts +28 -0
  261. package/src/mcpl/hook-orchestrator.ts +84 -77
  262. package/src/mcpl/inbound-source.ts +156 -0
  263. package/src/mcpl/index.ts +10 -1
  264. package/src/mcpl/inference-router.ts +174 -99
  265. package/src/mcpl/push-coalescer.ts +60 -24
  266. package/src/mcpl/push-handler.ts +20 -90
  267. package/src/mcpl/reference-fetcher.ts +71 -26
  268. package/src/mcpl/references.ts +81 -22
  269. package/src/mcpl/server-connection.ts +427 -132
  270. package/src/mcpl/server-registry.ts +15 -4
  271. package/src/mcpl/skip-reply-wake.ts +73 -0
  272. package/src/mcpl/transport.ts +120 -18
  273. package/src/mcpl/types.ts +14 -3
  274. package/src/mcpl/visible-content.ts +27 -0
  275. package/src/module-registry.ts +58 -23
  276. package/src/modules/api/index.ts +1 -1
  277. package/src/modules/discord/discord-js-client.ts +26 -10
  278. package/src/modules/discord/index.ts +391 -158
  279. package/src/modules/discord/types.ts +15 -2
  280. package/src/modules/health/index.ts +2 -1
  281. package/src/modules/history/index.ts +410 -120
  282. package/src/modules/history/semantic.ts +189 -32
  283. package/src/modules/unknown-tool.ts +16 -0
  284. package/src/modules/workspace/disk-agreement.ts +51 -3
  285. package/src/modules/workspace/effects.ts +279 -35
  286. package/src/modules/workspace/index.ts +810 -260
  287. package/src/modules/workspace/observe.ts +194 -20
  288. package/src/modules/workspace/reconcile.ts +619 -64
  289. package/src/modules/workspace/types.ts +18 -4
  290. package/src/modules/workspace/watcher.ts +27 -4
  291. package/src/prose-drafts.ts +481 -0
  292. package/src/prose-segments.ts +51 -8
  293. package/src/recovery/offline-branch.ts +4 -1
  294. package/src/safe-slice.ts +9 -1
  295. package/src/tool-image-ledger.ts +153 -34
  296. package/src/tool-presentation.ts +224 -40
  297. package/src/tool-result-guard.ts +7 -8
  298. package/src/tool-result-history.ts +124 -20
  299. package/src/tune-out/coordinator.ts +259 -65
  300. package/src/types/agent.ts +17 -7
  301. package/src/types/events.ts +17 -0
  302. package/src/types/framework.ts +21 -5
  303. package/src/types/inference-log.ts +1 -1
  304. package/src/types/module.ts +24 -4
  305. package/src/types/trace.ts +101 -6
  306. package/src/usage/usage-tracker.ts +32 -8
  307. package/dist/test/activation-request-sanitize.test.d.ts +0 -2
  308. package/dist/test/activation-request-sanitize.test.d.ts.map +0 -1
  309. package/dist/test/activation-request-sanitize.test.js +0 -89
  310. package/dist/test/activation-request-sanitize.test.js.map +0 -1
  311. package/dist/test/agent-cache-ttl.test.d.ts +0 -2
  312. package/dist/test/agent-cache-ttl.test.d.ts.map +0 -1
  313. package/dist/test/agent-cache-ttl.test.js +0 -41
  314. package/dist/test/agent-cache-ttl.test.js.map +0 -1
  315. package/dist/test/agent-runtime-settings.test.d.ts +0 -2
  316. package/dist/test/agent-runtime-settings.test.d.ts.map +0 -1
  317. package/dist/test/agent-runtime-settings.test.js +0 -1598
  318. package/dist/test/agent-runtime-settings.test.js.map +0 -1
  319. package/dist/test/api-admin-gate.test.d.ts +0 -2
  320. package/dist/test/api-admin-gate.test.d.ts.map +0 -1
  321. package/dist/test/api-admin-gate.test.js +0 -116
  322. package/dist/test/api-admin-gate.test.js.map +0 -1
  323. package/dist/test/assistant-persist-refusal.test.d.ts +0 -2
  324. package/dist/test/assistant-persist-refusal.test.d.ts.map +0 -1
  325. package/dist/test/assistant-persist-refusal.test.js +0 -63
  326. package/dist/test/assistant-persist-refusal.test.js.map +0 -1
  327. package/dist/test/batched-wake-locus.test.d.ts +0 -2
  328. package/dist/test/batched-wake-locus.test.d.ts.map +0 -1
  329. package/dist/test/batched-wake-locus.test.js +0 -166
  330. package/dist/test/batched-wake-locus.test.js.map +0 -1
  331. package/dist/test/busy-agent-scheduler.test.d.ts +0 -2
  332. package/dist/test/busy-agent-scheduler.test.d.ts.map +0 -1
  333. package/dist/test/busy-agent-scheduler.test.js +0 -92
  334. package/dist/test/busy-agent-scheduler.test.js.map +0 -1
  335. package/dist/test/channel-incoming-targeting.test.d.ts +0 -2
  336. package/dist/test/channel-incoming-targeting.test.d.ts.map +0 -1
  337. package/dist/test/channel-incoming-targeting.test.js +0 -81
  338. package/dist/test/channel-incoming-targeting.test.js.map +0 -1
  339. package/dist/test/channel-label-history.test.d.ts +0 -2
  340. package/dist/test/channel-label-history.test.d.ts.map +0 -1
  341. package/dist/test/channel-label-history.test.js +0 -424
  342. package/dist/test/channel-label-history.test.js.map +0 -1
  343. package/dist/test/channel-lifecycle-provenance.test.d.ts +0 -2
  344. package/dist/test/channel-lifecycle-provenance.test.d.ts.map +0 -1
  345. package/dist/test/channel-lifecycle-provenance.test.js +0 -47
  346. package/dist/test/channel-lifecycle-provenance.test.js.map +0 -1
  347. package/dist/test/channel-registry-routing.test.d.ts +0 -2
  348. package/dist/test/channel-registry-routing.test.d.ts.map +0 -1
  349. package/dist/test/channel-registry-routing.test.js +0 -446
  350. package/dist/test/channel-registry-routing.test.js.map +0 -1
  351. package/dist/test/channel-registry-typing.test.d.ts +0 -2
  352. package/dist/test/channel-registry-typing.test.d.ts.map +0 -1
  353. package/dist/test/channel-registry-typing.test.js +0 -91
  354. package/dist/test/channel-registry-typing.test.js.map +0 -1
  355. package/dist/test/channels-changed-respond-first.test.d.ts +0 -2
  356. package/dist/test/channels-changed-respond-first.test.d.ts.map +0 -1
  357. package/dist/test/channels-changed-respond-first.test.js +0 -74
  358. package/dist/test/channels-changed-respond-first.test.js.map +0 -1
  359. package/dist/test/checkpoint-attribution.test.d.ts +0 -2
  360. package/dist/test/checkpoint-attribution.test.d.ts.map +0 -1
  361. package/dist/test/checkpoint-attribution.test.js +0 -200
  362. package/dist/test/checkpoint-attribution.test.js.map +0 -1
  363. package/dist/test/code-execution.test.d.ts +0 -11
  364. package/dist/test/code-execution.test.d.ts.map +0 -1
  365. package/dist/test/code-execution.test.js +0 -1272
  366. package/dist/test/code-execution.test.js.map +0 -1
  367. package/dist/test/component-defaults.test.d.ts +0 -2
  368. package/dist/test/component-defaults.test.d.ts.map +0 -1
  369. package/dist/test/component-defaults.test.js +0 -54
  370. package/dist/test/component-defaults.test.js.map +0 -1
  371. package/dist/test/conversation-fork-injection-scoping.test.d.ts +0 -2
  372. package/dist/test/conversation-fork-injection-scoping.test.d.ts.map +0 -1
  373. package/dist/test/conversation-fork-injection-scoping.test.js +0 -200
  374. package/dist/test/conversation-fork-injection-scoping.test.js.map +0 -1
  375. package/dist/test/conversation-router.test.d.ts +0 -2
  376. package/dist/test/conversation-router.test.d.ts.map +0 -1
  377. package/dist/test/conversation-router.test.js +0 -174
  378. package/dist/test/conversation-router.test.js.map +0 -1
  379. package/dist/test/conversation-routing.test.d.ts +0 -7
  380. package/dist/test/conversation-routing.test.d.ts.map +0 -1
  381. package/dist/test/conversation-routing.test.js +0 -621
  382. package/dist/test/conversation-routing.test.js.map +0 -1
  383. package/dist/test/deferred-wake-integrity.test.d.ts +0 -29
  384. package/dist/test/deferred-wake-integrity.test.d.ts.map +0 -1
  385. package/dist/test/deferred-wake-integrity.test.js +0 -320
  386. package/dist/test/deferred-wake-integrity.test.js.map +0 -1
  387. package/dist/test/discord-awareness-outbox.test.d.ts +0 -2
  388. package/dist/test/discord-awareness-outbox.test.d.ts.map +0 -1
  389. package/dist/test/discord-awareness-outbox.test.js +0 -371
  390. package/dist/test/discord-awareness-outbox.test.js.map +0 -1
  391. package/dist/test/discord-history-delete-window.test.d.ts +0 -2
  392. package/dist/test/discord-history-delete-window.test.d.ts.map +0 -1
  393. package/dist/test/discord-history-delete-window.test.js +0 -81
  394. package/dist/test/discord-history-delete-window.test.js.map +0 -1
  395. package/dist/test/discord-history-sync.test.d.ts +0 -2
  396. package/dist/test/discord-history-sync.test.d.ts.map +0 -1
  397. package/dist/test/discord-history-sync.test.js +0 -56
  398. package/dist/test/discord-history-sync.test.js.map +0 -1
  399. package/dist/test/discord-typing-keepalive.test.d.ts +0 -2
  400. package/dist/test/discord-typing-keepalive.test.d.ts.map +0 -1
  401. package/dist/test/discord-typing-keepalive.test.js +0 -77
  402. package/dist/test/discord-typing-keepalive.test.js.map +0 -1
  403. package/dist/test/ephemeral-settle.test.d.ts +0 -2
  404. package/dist/test/ephemeral-settle.test.d.ts.map +0 -1
  405. package/dist/test/ephemeral-settle.test.js +0 -354
  406. package/dist/test/ephemeral-settle.test.js.map +0 -1
  407. package/dist/test/event-gate-passthrough.test.d.ts +0 -15
  408. package/dist/test/event-gate-passthrough.test.d.ts.map +0 -1
  409. package/dist/test/event-gate-passthrough.test.js +0 -289
  410. package/dist/test/event-gate-passthrough.test.js.map +0 -1
  411. package/dist/test/event-gate-policy-mutation.test.d.ts +0 -2
  412. package/dist/test/event-gate-policy-mutation.test.d.ts.map +0 -1
  413. package/dist/test/event-gate-policy-mutation.test.js +0 -137
  414. package/dist/test/event-gate-policy-mutation.test.js.map +0 -1
  415. package/dist/test/event-gate-rate-limit.test.d.ts +0 -2
  416. package/dist/test/event-gate-rate-limit.test.d.ts.map +0 -1
  417. package/dist/test/event-gate-rate-limit.test.js +0 -627
  418. package/dist/test/event-gate-rate-limit.test.js.map +0 -1
  419. package/dist/test/event-gate-script.test.d.ts +0 -2
  420. package/dist/test/event-gate-script.test.d.ts.map +0 -1
  421. package/dist/test/event-gate-script.test.js +0 -95
  422. package/dist/test/event-gate-script.test.js.map +0 -1
  423. package/dist/test/event-gate-selfwake.test.d.ts +0 -15
  424. package/dist/test/event-gate-selfwake.test.d.ts.map +0 -1
  425. package/dist/test/event-gate-selfwake.test.js +0 -125
  426. package/dist/test/event-gate-selfwake.test.js.map +0 -1
  427. package/dist/test/event-gate-tags.test.d.ts +0 -2
  428. package/dist/test/event-gate-tags.test.d.ts.map +0 -1
  429. package/dist/test/event-gate-tags.test.js +0 -76
  430. package/dist/test/event-gate-tags.test.js.map +0 -1
  431. package/dist/test/event-gate.test.d.ts +0 -2
  432. package/dist/test/event-gate.test.d.ts.map +0 -1
  433. package/dist/test/event-gate.test.js +0 -919
  434. package/dist/test/event-gate.test.js.map +0 -1
  435. package/dist/test/explicit-prose-routing.test.d.ts +0 -11
  436. package/dist/test/explicit-prose-routing.test.d.ts.map +0 -1
  437. package/dist/test/explicit-prose-routing.test.js +0 -1715
  438. package/dist/test/explicit-prose-routing.test.js.map +0 -1
  439. package/dist/test/framework.test.d.ts +0 -5
  440. package/dist/test/framework.test.d.ts.map +0 -1
  441. package/dist/test/framework.test.js +0 -1048
  442. package/dist/test/framework.test.js.map +0 -1
  443. package/dist/test/gather-context-timeout.test.d.ts +0 -2
  444. package/dist/test/gather-context-timeout.test.d.ts.map +0 -1
  445. package/dist/test/gather-context-timeout.test.js +0 -120
  446. package/dist/test/gather-context-timeout.test.js.map +0 -1
  447. package/dist/test/health-snapshot.test.d.ts +0 -2
  448. package/dist/test/health-snapshot.test.d.ts.map +0 -1
  449. package/dist/test/health-snapshot.test.js +0 -74
  450. package/dist/test/health-snapshot.test.js.map +0 -1
  451. package/dist/test/helpers/coalescing-fixture.d.ts +0 -74
  452. package/dist/test/helpers/coalescing-fixture.d.ts.map +0 -1
  453. package/dist/test/helpers/coalescing-fixture.js +0 -152
  454. package/dist/test/helpers/coalescing-fixture.js.map +0 -1
  455. package/dist/test/helpers/coalescing-kill-child.d.ts +0 -2
  456. package/dist/test/helpers/coalescing-kill-child.d.ts.map +0 -1
  457. package/dist/test/helpers/coalescing-kill-child.js +0 -24
  458. package/dist/test/helpers/coalescing-kill-child.js.map +0 -1
  459. package/dist/test/helpers/mock-membrane.d.ts +0 -53
  460. package/dist/test/helpers/mock-membrane.d.ts.map +0 -1
  461. package/dist/test/helpers/mock-membrane.js +0 -168
  462. package/dist/test/helpers/mock-membrane.js.map +0 -1
  463. package/dist/test/helpers/pytc-stop-rows.d.ts +0 -11
  464. package/dist/test/helpers/pytc-stop-rows.d.ts.map +0 -1
  465. package/dist/test/helpers/pytc-stop-rows.js +0 -143
  466. package/dist/test/helpers/pytc-stop-rows.js.map +0 -1
  467. package/dist/test/helpers/quiesce-crash-child.d.ts +0 -2
  468. package/dist/test/helpers/quiesce-crash-child.d.ts.map +0 -1
  469. package/dist/test/helpers/quiesce-crash-child.js +0 -156
  470. package/dist/test/helpers/quiesce-crash-child.js.map +0 -1
  471. package/dist/test/hide-then-turn.test.d.ts +0 -2
  472. package/dist/test/hide-then-turn.test.d.ts.map +0 -1
  473. package/dist/test/hide-then-turn.test.js +0 -101
  474. package/dist/test/hide-then-turn.test.js.map +0 -1
  475. package/dist/test/history-module-overview.test.d.ts +0 -2
  476. package/dist/test/history-module-overview.test.d.ts.map +0 -1
  477. package/dist/test/history-module-overview.test.js +0 -711
  478. package/dist/test/history-module-overview.test.js.map +0 -1
  479. package/dist/test/history-module-realstore.test.d.ts +0 -2
  480. package/dist/test/history-module-realstore.test.d.ts.map +0 -1
  481. package/dist/test/history-module-realstore.test.js +0 -363
  482. package/dist/test/history-module-realstore.test.js.map +0 -1
  483. package/dist/test/history-module-semantic.test.d.ts +0 -2
  484. package/dist/test/history-module-semantic.test.d.ts.map +0 -1
  485. package/dist/test/history-module-semantic.test.js +0 -213
  486. package/dist/test/history-module-semantic.test.js.map +0 -1
  487. package/dist/test/history-module-ux.test.d.ts +0 -2
  488. package/dist/test/history-module-ux.test.d.ts.map +0 -1
  489. package/dist/test/history-module-ux.test.js +0 -304
  490. package/dist/test/history-module-ux.test.js.map +0 -1
  491. package/dist/test/history-module.test.d.ts +0 -2
  492. package/dist/test/history-module.test.d.ts.map +0 -1
  493. package/dist/test/history-module.test.js +0 -619
  494. package/dist/test/history-module.test.js.map +0 -1
  495. package/dist/test/history-semantic-review-findings.test.d.ts +0 -2
  496. package/dist/test/history-semantic-review-findings.test.d.ts.map +0 -1
  497. package/dist/test/history-semantic-review-findings.test.js +0 -338
  498. package/dist/test/history-semantic-review-findings.test.js.map +0 -1
  499. package/dist/test/history-semantic-sync-converges.test.d.ts +0 -2
  500. package/dist/test/history-semantic-sync-converges.test.d.ts.map +0 -1
  501. package/dist/test/history-semantic-sync-converges.test.js +0 -109
  502. package/dist/test/history-semantic-sync-converges.test.js.map +0 -1
  503. package/dist/test/host-quiesce.test.d.ts +0 -2
  504. package/dist/test/host-quiesce.test.d.ts.map +0 -1
  505. package/dist/test/host-quiesce.test.js +0 -988
  506. package/dist/test/host-quiesce.test.js.map +0 -1
  507. package/dist/test/inference-exhaustion-rewind.test.d.ts +0 -2
  508. package/dist/test/inference-exhaustion-rewind.test.d.ts.map +0 -1
  509. package/dist/test/inference-exhaustion-rewind.test.js +0 -387
  510. package/dist/test/inference-exhaustion-rewind.test.js.map +0 -1
  511. package/dist/test/inference-failure-bounds.test.d.ts +0 -2
  512. package/dist/test/inference-failure-bounds.test.d.ts.map +0 -1
  513. package/dist/test/inference-failure-bounds.test.js +0 -1202
  514. package/dist/test/inference-failure-bounds.test.js.map +0 -1
  515. package/dist/test/inference-failure-observability.test.d.ts +0 -2
  516. package/dist/test/inference-failure-observability.test.d.ts.map +0 -1
  517. package/dist/test/inference-failure-observability.test.js +0 -84
  518. package/dist/test/inference-failure-observability.test.js.map +0 -1
  519. package/dist/test/journal-tool.test.d.ts +0 -2
  520. package/dist/test/journal-tool.test.d.ts.map +0 -1
  521. package/dist/test/journal-tool.test.js +0 -33
  522. package/dist/test/journal-tool.test.js.map +0 -1
  523. package/dist/test/kv-unified-open-flight-retry.test.d.ts +0 -2
  524. package/dist/test/kv-unified-open-flight-retry.test.d.ts.map +0 -1
  525. package/dist/test/kv-unified-open-flight-retry.test.js +0 -189
  526. package/dist/test/kv-unified-open-flight-retry.test.js.map +0 -1
  527. package/dist/test/kv-unified-wiring.test.d.ts +0 -2
  528. package/dist/test/kv-unified-wiring.test.d.ts.map +0 -1
  529. package/dist/test/kv-unified-wiring.test.js +0 -95
  530. package/dist/test/kv-unified-wiring.test.js.map +0 -1
  531. package/dist/test/late-events-after-stop.test.d.ts +0 -2
  532. package/dist/test/late-events-after-stop.test.d.ts.map +0 -1
  533. package/dist/test/late-events-after-stop.test.js +0 -122
  534. package/dist/test/late-events-after-stop.test.js.map +0 -1
  535. package/dist/test/liveness-watchdog.test.d.ts +0 -2
  536. package/dist/test/liveness-watchdog.test.d.ts.map +0 -1
  537. package/dist/test/liveness-watchdog.test.js +0 -94
  538. package/dist/test/liveness-watchdog.test.js.map +0 -1
  539. package/dist/test/machine-close-provenance.test.d.ts +0 -2
  540. package/dist/test/machine-close-provenance.test.d.ts.map +0 -1
  541. package/dist/test/machine-close-provenance.test.js +0 -116
  542. package/dist/test/machine-close-provenance.test.js.map +0 -1
  543. package/dist/test/maintenance-timer.test.d.ts +0 -2
  544. package/dist/test/maintenance-timer.test.d.ts.map +0 -1
  545. package/dist/test/maintenance-timer.test.js +0 -1827
  546. package/dist/test/maintenance-timer.test.js.map +0 -1
  547. package/dist/test/mcp-server-bin.test.d.ts +0 -2
  548. package/dist/test/mcp-server-bin.test.d.ts.map +0 -1
  549. package/dist/test/mcp-server-bin.test.js +0 -142
  550. package/dist/test/mcp-server-bin.test.js.map +0 -1
  551. package/dist/test/mcpl-access-provider.test.d.ts +0 -2
  552. package/dist/test/mcpl-access-provider.test.d.ts.map +0 -1
  553. package/dist/test/mcpl-access-provider.test.js +0 -20
  554. package/dist/test/mcpl-access-provider.test.js.map +0 -1
  555. package/dist/test/mcpl-awareness-barrier.test.d.ts +0 -2
  556. package/dist/test/mcpl-awareness-barrier.test.d.ts.map +0 -1
  557. package/dist/test/mcpl-awareness-barrier.test.js +0 -769
  558. package/dist/test/mcpl-awareness-barrier.test.js.map +0 -1
  559. package/dist/test/mcpl-capability-grant.test.d.ts +0 -10
  560. package/dist/test/mcpl-capability-grant.test.d.ts.map +0 -1
  561. package/dist/test/mcpl-capability-grant.test.js +0 -111
  562. package/dist/test/mcpl-capability-grant.test.js.map +0 -1
  563. package/dist/test/mcpl-capability-scoping.test.d.ts +0 -2
  564. package/dist/test/mcpl-capability-scoping.test.d.ts.map +0 -1
  565. package/dist/test/mcpl-capability-scoping.test.js +0 -266
  566. package/dist/test/mcpl-capability-scoping.test.js.map +0 -1
  567. package/dist/test/mcpl-child-env.test.d.ts +0 -2
  568. package/dist/test/mcpl-child-env.test.d.ts.map +0 -1
  569. package/dist/test/mcpl-child-env.test.js +0 -158
  570. package/dist/test/mcpl-child-env.test.js.map +0 -1
  571. package/dist/test/mcpl-coalesced-content-parity.test.d.ts +0 -2
  572. package/dist/test/mcpl-coalesced-content-parity.test.d.ts.map +0 -1
  573. package/dist/test/mcpl-coalesced-content-parity.test.js +0 -532
  574. package/dist/test/mcpl-coalesced-content-parity.test.js.map +0 -1
  575. package/dist/test/mcpl-coalescing.test.d.ts +0 -2
  576. package/dist/test/mcpl-coalescing.test.d.ts.map +0 -1
  577. package/dist/test/mcpl-coalescing.test.js +0 -1125
  578. package/dist/test/mcpl-coalescing.test.js.map +0 -1
  579. package/dist/test/mcpl-config-diagnostics.test.d.ts +0 -2
  580. package/dist/test/mcpl-config-diagnostics.test.d.ts.map +0 -1
  581. package/dist/test/mcpl-config-diagnostics.test.js +0 -452
  582. package/dist/test/mcpl-config-diagnostics.test.js.map +0 -1
  583. package/dist/test/mcpl-empty-content.test.d.ts +0 -2
  584. package/dist/test/mcpl-empty-content.test.d.ts.map +0 -1
  585. package/dist/test/mcpl-empty-content.test.js +0 -368
  586. package/dist/test/mcpl-empty-content.test.js.map +0 -1
  587. package/dist/test/mcpl-gate-roundtrip.test.d.ts +0 -2
  588. package/dist/test/mcpl-gate-roundtrip.test.d.ts.map +0 -1
  589. package/dist/test/mcpl-gate-roundtrip.test.js +0 -285
  590. package/dist/test/mcpl-gate-roundtrip.test.js.map +0 -1
  591. package/dist/test/mcpl-list-status.test.d.ts +0 -2
  592. package/dist/test/mcpl-list-status.test.d.ts.map +0 -1
  593. package/dist/test/mcpl-list-status.test.js +0 -82
  594. package/dist/test/mcpl-list-status.test.js.map +0 -1
  595. package/dist/test/mcpl-manifest-changed.test.d.ts +0 -2
  596. package/dist/test/mcpl-manifest-changed.test.d.ts.map +0 -1
  597. package/dist/test/mcpl-manifest-changed.test.js +0 -178
  598. package/dist/test/mcpl-manifest-changed.test.js.map +0 -1
  599. package/dist/test/mcpl-push-convert.test.d.ts +0 -2
  600. package/dist/test/mcpl-push-convert.test.d.ts.map +0 -1
  601. package/dist/test/mcpl-push-convert.test.js +0 -42
  602. package/dist/test/mcpl-push-convert.test.js.map +0 -1
  603. package/dist/test/mcpl-reconnect-events.test.d.ts +0 -2
  604. package/dist/test/mcpl-reconnect-events.test.d.ts.map +0 -1
  605. package/dist/test/mcpl-reconnect-events.test.js +0 -144
  606. package/dist/test/mcpl-reconnect-events.test.js.map +0 -1
  607. package/dist/test/mcpl-reconnect-reregistration.test.d.ts +0 -2
  608. package/dist/test/mcpl-reconnect-reregistration.test.d.ts.map +0 -1
  609. package/dist/test/mcpl-reconnect-reregistration.test.js +0 -238
  610. package/dist/test/mcpl-reconnect-reregistration.test.js.map +0 -1
  611. package/dist/test/mcpl-reference-fetcher.test.d.ts +0 -2
  612. package/dist/test/mcpl-reference-fetcher.test.d.ts.map +0 -1
  613. package/dist/test/mcpl-reference-fetcher.test.js +0 -427
  614. package/dist/test/mcpl-reference-fetcher.test.js.map +0 -1
  615. package/dist/test/mcpl-reference-fields.test.d.ts +0 -2
  616. package/dist/test/mcpl-reference-fields.test.d.ts.map +0 -1
  617. package/dist/test/mcpl-reference-fields.test.js +0 -149
  618. package/dist/test/mcpl-reference-fields.test.js.map +0 -1
  619. package/dist/test/mcpl-rejection-log-lines.test.d.ts +0 -2
  620. package/dist/test/mcpl-rejection-log-lines.test.d.ts.map +0 -1
  621. package/dist/test/mcpl-rejection-log-lines.test.js +0 -349
  622. package/dist/test/mcpl-rejection-log-lines.test.js.map +0 -1
  623. package/dist/test/mcpl-request-timeout.test.d.ts +0 -2
  624. package/dist/test/mcpl-request-timeout.test.d.ts.map +0 -1
  625. package/dist/test/mcpl-request-timeout.test.js +0 -138
  626. package/dist/test/mcpl-request-timeout.test.js.map +0 -1
  627. package/dist/test/mcpl-runtime-lifecycle.test.d.ts +0 -7
  628. package/dist/test/mcpl-runtime-lifecycle.test.d.ts.map +0 -1
  629. package/dist/test/mcpl-runtime-lifecycle.test.js +0 -142
  630. package/dist/test/mcpl-runtime-lifecycle.test.js.map +0 -1
  631. package/dist/test/mcpl-stderr-tail.test.d.ts +0 -2
  632. package/dist/test/mcpl-stderr-tail.test.d.ts.map +0 -1
  633. package/dist/test/mcpl-stderr-tail.test.js +0 -210
  634. package/dist/test/mcpl-stderr-tail.test.js.map +0 -1
  635. package/dist/test/mcpl-tool-class-listing.test.d.ts +0 -2
  636. package/dist/test/mcpl-tool-class-listing.test.d.ts.map +0 -1
  637. package/dist/test/mcpl-tool-class-listing.test.js +0 -147
  638. package/dist/test/mcpl-tool-class-listing.test.js.map +0 -1
  639. package/dist/test/mcpl-tool-classes.test.d.ts +0 -7
  640. package/dist/test/mcpl-tool-classes.test.d.ts.map +0 -1
  641. package/dist/test/mcpl-tool-classes.test.js +0 -80
  642. package/dist/test/mcpl-tool-classes.test.js.map +0 -1
  643. package/dist/test/mcpl-tool-lifecycle-e2e.test.d.ts +0 -2
  644. package/dist/test/mcpl-tool-lifecycle-e2e.test.d.ts.map +0 -1
  645. package/dist/test/mcpl-tool-lifecycle-e2e.test.js +0 -237
  646. package/dist/test/mcpl-tool-lifecycle-e2e.test.js.map +0 -1
  647. package/dist/test/mcpl-tool-lifecycle-emitter.test.d.ts +0 -11
  648. package/dist/test/mcpl-tool-lifecycle-emitter.test.d.ts.map +0 -1
  649. package/dist/test/mcpl-tool-lifecycle-emitter.test.js +0 -412
  650. package/dist/test/mcpl-tool-lifecycle-emitter.test.js.map +0 -1
  651. package/dist/test/mcpl-tool-lifecycle-script.test.d.ts +0 -2
  652. package/dist/test/mcpl-tool-lifecycle-script.test.d.ts.map +0 -1
  653. package/dist/test/mcpl-tool-lifecycle-script.test.js +0 -288
  654. package/dist/test/mcpl-tool-lifecycle-script.test.js.map +0 -1
  655. package/dist/test/mcpl-tool-lifecycle.test.d.ts +0 -11
  656. package/dist/test/mcpl-tool-lifecycle.test.d.ts.map +0 -1
  657. package/dist/test/mcpl-tool-lifecycle.test.js +0 -270
  658. package/dist/test/mcpl-tool-lifecycle.test.js.map +0 -1
  659. package/dist/test/mcpl-transport-close.test.d.ts +0 -2
  660. package/dist/test/mcpl-transport-close.test.d.ts.map +0 -1
  661. package/dist/test/mcpl-transport-close.test.js +0 -373
  662. package/dist/test/mcpl-transport-close.test.js.map +0 -1
  663. package/dist/test/mcpl-transport-spawn.test.d.ts +0 -2
  664. package/dist/test/mcpl-transport-spawn.test.d.ts.map +0 -1
  665. package/dist/test/mcpl-transport-spawn.test.js +0 -58
  666. package/dist/test/mcpl-transport-spawn.test.js.map +0 -1
  667. package/dist/test/mcpl-ws-transport.test.d.ts +0 -2
  668. package/dist/test/mcpl-ws-transport.test.d.ts.map +0 -1
  669. package/dist/test/mcpl-ws-transport.test.js +0 -259
  670. package/dist/test/mcpl-ws-transport.test.js.map +0 -1
  671. package/dist/test/module-context-integration.test.d.ts +0 -18
  672. package/dist/test/module-context-integration.test.d.ts.map +0 -1
  673. package/dist/test/module-context-integration.test.js +0 -181
  674. package/dist/test/module-context-integration.test.js.map +0 -1
  675. package/dist/test/offline-recovery-branch.test.d.ts +0 -2
  676. package/dist/test/offline-recovery-branch.test.d.ts.map +0 -1
  677. package/dist/test/offline-recovery-branch.test.js +0 -570
  678. package/dist/test/offline-recovery-branch.test.js.map +0 -1
  679. package/dist/test/operator-surgery.test.d.ts +0 -2
  680. package/dist/test/operator-surgery.test.d.ts.map +0 -1
  681. package/dist/test/operator-surgery.test.js +0 -595
  682. package/dist/test/operator-surgery.test.js.map +0 -1
  683. package/dist/test/ops-alert.test.d.ts +0 -2
  684. package/dist/test/ops-alert.test.d.ts.map +0 -1
  685. package/dist/test/ops-alert.test.js +0 -153
  686. package/dist/test/ops-alert.test.js.map +0 -1
  687. package/dist/test/overbudget-drain-breaker.test.d.ts +0 -2
  688. package/dist/test/overbudget-drain-breaker.test.d.ts.map +0 -1
  689. package/dist/test/overbudget-drain-breaker.test.js +0 -198
  690. package/dist/test/overbudget-drain-breaker.test.js.map +0 -1
  691. package/dist/test/pack-installs-alone.test.d.ts +0 -2
  692. package/dist/test/pack-installs-alone.test.d.ts.map +0 -1
  693. package/dist/test/pack-installs-alone.test.js +0 -284
  694. package/dist/test/pack-installs-alone.test.js.map +0 -1
  695. package/dist/test/per-agent-delivery.test.d.ts +0 -2
  696. package/dist/test/per-agent-delivery.test.d.ts.map +0 -1
  697. package/dist/test/per-agent-delivery.test.js +0 -108
  698. package/dist/test/per-agent-delivery.test.js.map +0 -1
  699. package/dist/test/physical-window-restart.test.d.ts +0 -16
  700. package/dist/test/physical-window-restart.test.d.ts.map +0 -1
  701. package/dist/test/physical-window-restart.test.js +0 -487
  702. package/dist/test/physical-window-restart.test.js.map +0 -1
  703. package/dist/test/placed-reaction-baseline.test.d.ts +0 -2
  704. package/dist/test/placed-reaction-baseline.test.d.ts.map +0 -1
  705. package/dist/test/placed-reaction-baseline.test.js +0 -312
  706. package/dist/test/placed-reaction-baseline.test.js.map +0 -1
  707. package/dist/test/present-while-acting.test.d.ts +0 -19
  708. package/dist/test/present-while-acting.test.d.ts.map +0 -1
  709. package/dist/test/present-while-acting.test.js +0 -1649
  710. package/dist/test/present-while-acting.test.js.map +0 -1
  711. package/dist/test/prose-segments.test.d.ts +0 -2
  712. package/dist/test/prose-segments.test.d.ts.map +0 -1
  713. package/dist/test/prose-segments.test.js +0 -52
  714. package/dist/test/prose-segments.test.js.map +0 -1
  715. package/dist/test/prose-stream-router.test.d.ts +0 -2
  716. package/dist/test/prose-stream-router.test.d.ts.map +0 -1
  717. package/dist/test/prose-stream-router.test.js +0 -171
  718. package/dist/test/prose-stream-router.test.js.map +0 -1
  719. package/dist/test/provider-acceleration-cooldown.test.d.ts +0 -2
  720. package/dist/test/provider-acceleration-cooldown.test.d.ts.map +0 -1
  721. package/dist/test/provider-acceleration-cooldown.test.js +0 -435
  722. package/dist/test/provider-acceleration-cooldown.test.js.map +0 -1
  723. package/dist/test/provider-waits.test.d.ts +0 -2
  724. package/dist/test/provider-waits.test.d.ts.map +0 -1
  725. package/dist/test/provider-waits.test.js +0 -2259
  726. package/dist/test/provider-waits.test.js.map +0 -1
  727. package/dist/test/puppet-tool-call.test.d.ts +0 -2
  728. package/dist/test/puppet-tool-call.test.d.ts.map +0 -1
  729. package/dist/test/puppet-tool-call.test.js +0 -226
  730. package/dist/test/puppet-tool-call.test.js.map +0 -1
  731. package/dist/test/puppet-turn-reservation.test.d.ts +0 -2
  732. package/dist/test/puppet-turn-reservation.test.d.ts.map +0 -1
  733. package/dist/test/puppet-turn-reservation.test.js +0 -139
  734. package/dist/test/puppet-turn-reservation.test.js.map +0 -1
  735. package/dist/test/reaction-baseline-platform.test.d.ts +0 -2
  736. package/dist/test/reaction-baseline-platform.test.d.ts.map +0 -1
  737. package/dist/test/reaction-baseline-platform.test.js +0 -124
  738. package/dist/test/reaction-baseline-platform.test.js.map +0 -1
  739. package/dist/test/record-journal.test.d.ts +0 -6
  740. package/dist/test/record-journal.test.d.ts.map +0 -1
  741. package/dist/test/record-journal.test.js +0 -269
  742. package/dist/test/record-journal.test.js.map +0 -1
  743. package/dist/test/refusal-reaction-baseline.test.d.ts +0 -2
  744. package/dist/test/refusal-reaction-baseline.test.d.ts.map +0 -1
  745. package/dist/test/refusal-reaction-baseline.test.js +0 -81
  746. package/dist/test/refusal-reaction-baseline.test.js.map +0 -1
  747. package/dist/test/refusal-rewind.test.d.ts +0 -2
  748. package/dist/test/refusal-rewind.test.d.ts.map +0 -1
  749. package/dist/test/refusal-rewind.test.js +0 -117
  750. package/dist/test/refusal-rewind.test.js.map +0 -1
  751. package/dist/test/refusal-single-call.test.d.ts +0 -2
  752. package/dist/test/refusal-single-call.test.d.ts.map +0 -1
  753. package/dist/test/refusal-single-call.test.js +0 -177
  754. package/dist/test/refusal-single-call.test.js.map +0 -1
  755. package/dist/test/release-bump.test.d.ts +0 -2
  756. package/dist/test/release-bump.test.d.ts.map +0 -1
  757. package/dist/test/release-bump.test.js +0 -248
  758. package/dist/test/release-bump.test.js.map +0 -1
  759. package/dist/test/release-changelog.test.d.ts +0 -2
  760. package/dist/test/release-changelog.test.d.ts.map +0 -1
  761. package/dist/test/release-changelog.test.js +0 -159
  762. package/dist/test/release-changelog.test.js.map +0 -1
  763. package/dist/test/release-holds.test.d.ts +0 -2
  764. package/dist/test/release-holds.test.d.ts.map +0 -1
  765. package/dist/test/release-holds.test.js +0 -456
  766. package/dist/test/release-holds.test.js.map +0 -1
  767. package/dist/test/same-round-think-policy.test.d.ts +0 -2
  768. package/dist/test/same-round-think-policy.test.d.ts.map +0 -1
  769. package/dist/test/same-round-think-policy.test.js +0 -853
  770. package/dist/test/same-round-think-policy.test.js.map +0 -1
  771. package/dist/test/save-recent-image.test.d.ts +0 -26
  772. package/dist/test/save-recent-image.test.d.ts.map +0 -1
  773. package/dist/test/save-recent-image.test.js +0 -974
  774. package/dist/test/save-recent-image.test.js.map +0 -1
  775. package/dist/test/shutdown-errors.test.d.ts +0 -2
  776. package/dist/test/shutdown-errors.test.d.ts.map +0 -1
  777. package/dist/test/shutdown-errors.test.js +0 -662
  778. package/dist/test/shutdown-errors.test.js.map +0 -1
  779. package/dist/test/silent-heartbeat-rows.test.d.ts +0 -2
  780. package/dist/test/silent-heartbeat-rows.test.d.ts.map +0 -1
  781. package/dist/test/silent-heartbeat-rows.test.js +0 -451
  782. package/dist/test/silent-heartbeat-rows.test.js.map +0 -1
  783. package/dist/test/silent-heartbeat.test.d.ts +0 -2
  784. package/dist/test/silent-heartbeat.test.d.ts.map +0 -1
  785. package/dist/test/silent-heartbeat.test.js +0 -165
  786. package/dist/test/silent-heartbeat.test.js.map +0 -1
  787. package/dist/test/state-scaling-e2e.test.d.ts +0 -22
  788. package/dist/test/state-scaling-e2e.test.d.ts.map +0 -1
  789. package/dist/test/state-scaling-e2e.test.js +0 -206
  790. package/dist/test/state-scaling-e2e.test.js.map +0 -1
  791. package/dist/test/state-scaling.test.d.ts +0 -12
  792. package/dist/test/state-scaling.test.d.ts.map +0 -1
  793. package/dist/test/state-scaling.test.js +0 -251
  794. package/dist/test/state-scaling.test.js.map +0 -1
  795. package/dist/test/stop-with-host-operations.test.d.ts +0 -20
  796. package/dist/test/stop-with-host-operations.test.d.ts.map +0 -1
  797. package/dist/test/stop-with-host-operations.test.js +0 -1174
  798. package/dist/test/stop-with-host-operations.test.js.map +0 -1
  799. package/dist/test/stop-with-work-in-flight.test.d.ts +0 -23
  800. package/dist/test/stop-with-work-in-flight.test.d.ts.map +0 -1
  801. package/dist/test/stop-with-work-in-flight.test.js +0 -784
  802. package/dist/test/stop-with-work-in-flight.test.js.map +0 -1
  803. package/dist/test/surgery-marks-receipt.test.d.ts +0 -2
  804. package/dist/test/surgery-marks-receipt.test.d.ts.map +0 -1
  805. package/dist/test/surgery-marks-receipt.test.js +0 -540
  806. package/dist/test/surgery-marks-receipt.test.js.map +0 -1
  807. package/dist/test/thinking-token-stamp.test.d.ts +0 -12
  808. package/dist/test/thinking-token-stamp.test.d.ts.map +0 -1
  809. package/dist/test/thinking-token-stamp.test.js +0 -129
  810. package/dist/test/thinking-token-stamp.test.js.map +0 -1
  811. package/dist/test/timezone.test.d.ts +0 -2
  812. package/dist/test/timezone.test.d.ts.map +0 -1
  813. package/dist/test/timezone.test.js +0 -18
  814. package/dist/test/timezone.test.js.map +0 -1
  815. package/dist/test/tool-batch-hook.test.d.ts +0 -8
  816. package/dist/test/tool-batch-hook.test.d.ts.map +0 -1
  817. package/dist/test/tool-batch-hook.test.js +0 -275
  818. package/dist/test/tool-batch-hook.test.js.map +0 -1
  819. package/dist/test/tool-policy.test.d.ts +0 -2
  820. package/dist/test/tool-policy.test.d.ts.map +0 -1
  821. package/dist/test/tool-policy.test.js +0 -51
  822. package/dist/test/tool-policy.test.js.map +0 -1
  823. package/dist/test/tool-presentation.test.d.ts +0 -2
  824. package/dist/test/tool-presentation.test.d.ts.map +0 -1
  825. package/dist/test/tool-presentation.test.js +0 -268
  826. package/dist/test/tool-presentation.test.js.map +0 -1
  827. package/dist/test/tool-result-content.test.d.ts +0 -2
  828. package/dist/test/tool-result-content.test.d.ts.map +0 -1
  829. package/dist/test/tool-result-content.test.js +0 -37
  830. package/dist/test/tool-result-content.test.js.map +0 -1
  831. package/dist/test/tool-result-guard.test.d.ts +0 -2
  832. package/dist/test/tool-result-guard.test.d.ts.map +0 -1
  833. package/dist/test/tool-result-guard.test.js +0 -3729
  834. package/dist/test/tool-result-guard.test.js.map +0 -1
  835. package/dist/test/tool-result-history.test.d.ts +0 -7
  836. package/dist/test/tool-result-history.test.d.ts.map +0 -1
  837. package/dist/test/tool-result-history.test.js +0 -156
  838. package/dist/test/tool-result-history.test.js.map +0 -1
  839. package/dist/test/tool-result-spill.test.d.ts +0 -13
  840. package/dist/test/tool-result-spill.test.d.ts.map +0 -1
  841. package/dist/test/tool-result-spill.test.js +0 -586
  842. package/dist/test/tool-result-spill.test.js.map +0 -1
  843. package/dist/test/tool-wrapper-prose-guard-integration.test.d.ts +0 -2
  844. package/dist/test/tool-wrapper-prose-guard-integration.test.d.ts.map +0 -1
  845. package/dist/test/tool-wrapper-prose-guard-integration.test.js +0 -485
  846. package/dist/test/tool-wrapper-prose-guard-integration.test.js.map +0 -1
  847. package/dist/test/tool-wrapper-prose-guard.test.d.ts +0 -2
  848. package/dist/test/tool-wrapper-prose-guard.test.d.ts.map +0 -1
  849. package/dist/test/tool-wrapper-prose-guard.test.js +0 -34
  850. package/dist/test/tool-wrapper-prose-guard.test.js.map +0 -1
  851. package/dist/test/tools-observe-parser-conformance.test.d.ts +0 -2
  852. package/dist/test/tools-observe-parser-conformance.test.d.ts.map +0 -1
  853. package/dist/test/tools-observe-parser-conformance.test.js +0 -129
  854. package/dist/test/tools-observe-parser-conformance.test.js.map +0 -1
  855. package/dist/test/trunk-channel-routing.test.d.ts +0 -19
  856. package/dist/test/trunk-channel-routing.test.d.ts.map +0 -1
  857. package/dist/test/trunk-channel-routing.test.js +0 -652
  858. package/dist/test/trunk-channel-routing.test.js.map +0 -1
  859. package/dist/test/tune-out-e2e.test.d.ts +0 -2
  860. package/dist/test/tune-out-e2e.test.d.ts.map +0 -1
  861. package/dist/test/tune-out-e2e.test.js +0 -142
  862. package/dist/test/tune-out-e2e.test.js.map +0 -1
  863. package/dist/test/tune-out-gate-composition.test.d.ts +0 -2
  864. package/dist/test/tune-out-gate-composition.test.d.ts.map +0 -1
  865. package/dist/test/tune-out-gate-composition.test.js +0 -221
  866. package/dist/test/tune-out-gate-composition.test.js.map +0 -1
  867. package/dist/test/tune-out-lifecycle.test.d.ts +0 -2
  868. package/dist/test/tune-out-lifecycle.test.d.ts.map +0 -1
  869. package/dist/test/tune-out-lifecycle.test.js +0 -121
  870. package/dist/test/tune-out-lifecycle.test.js.map +0 -1
  871. package/dist/test/turn-trigger-provenance.test.d.ts +0 -2
  872. package/dist/test/turn-trigger-provenance.test.d.ts.map +0 -1
  873. package/dist/test/turn-trigger-provenance.test.js +0 -137
  874. package/dist/test/turn-trigger-provenance.test.js.map +0 -1
  875. package/dist/test/unconvertible-tool-result.test.d.ts +0 -2
  876. package/dist/test/unconvertible-tool-result.test.d.ts.map +0 -1
  877. package/dist/test/unconvertible-tool-result.test.js +0 -358
  878. package/dist/test/unconvertible-tool-result.test.js.map +0 -1
  879. package/dist/test/unsent-compiles.test.d.ts +0 -2
  880. package/dist/test/unsent-compiles.test.d.ts.map +0 -1
  881. package/dist/test/unsent-compiles.test.js +0 -139
  882. package/dist/test/unsent-compiles.test.js.map +0 -1
  883. package/dist/test/usage-accounting.test.d.ts +0 -2
  884. package/dist/test/usage-accounting.test.d.ts.map +0 -1
  885. package/dist/test/usage-accounting.test.js +0 -13
  886. package/dist/test/usage-accounting.test.js.map +0 -1
  887. package/dist/test/usage-tracker.test.d.ts +0 -2
  888. package/dist/test/usage-tracker.test.d.ts.map +0 -1
  889. package/dist/test/usage-tracker.test.js +0 -129
  890. package/dist/test/usage-tracker.test.js.map +0 -1
  891. package/dist/test/utils-surface.test.d.ts +0 -2
  892. package/dist/test/utils-surface.test.d.ts.map +0 -1
  893. package/dist/test/utils-surface.test.js +0 -145
  894. package/dist/test/utils-surface.test.js.map +0 -1
  895. package/dist/test/workspace-branch-continuation.test.d.ts +0 -15
  896. package/dist/test/workspace-branch-continuation.test.d.ts.map +0 -1
  897. package/dist/test/workspace-branch-continuation.test.js +0 -183
  898. package/dist/test/workspace-branch-continuation.test.js.map +0 -1
  899. package/dist/test/workspace-materialize-freshness.test.d.ts +0 -16
  900. package/dist/test/workspace-materialize-freshness.test.d.ts.map +0 -1
  901. package/dist/test/workspace-materialize-freshness.test.js +0 -252
  902. package/dist/test/workspace-materialize-freshness.test.js.map +0 -1
  903. package/dist/test/workspace-path-containment.test.d.ts +0 -19
  904. package/dist/test/workspace-path-containment.test.d.ts.map +0 -1
  905. package/dist/test/workspace-path-containment.test.js +0 -91
  906. package/dist/test/workspace-path-containment.test.js.map +0 -1
  907. package/dist/test/workspace-read-file-from-disk.test.d.ts +0 -17
  908. package/dist/test/workspace-read-file-from-disk.test.d.ts.map +0 -1
  909. package/dist/test/workspace-read-file-from-disk.test.js +0 -174
  910. package/dist/test/workspace-read-file-from-disk.test.js.map +0 -1
  911. package/dist/test/workspace-read-image.test.d.ts +0 -2
  912. package/dist/test/workspace-read-image.test.d.ts.map +0 -1
  913. package/dist/test/workspace-read-image.test.js +0 -597
  914. package/dist/test/workspace-read-image.test.js.map +0 -1
  915. package/dist/test/workspace-read-text.test.d.ts +0 -2
  916. package/dist/test/workspace-read-text.test.d.ts.map +0 -1
  917. package/dist/test/workspace-read-text.test.js +0 -101
  918. package/dist/test/workspace-read-text.test.js.map +0 -1
  919. package/dist/test/workspace-restore-order.test.d.ts +0 -16
  920. package/dist/test/workspace-restore-order.test.d.ts.map +0 -1
  921. package/dist/test/workspace-restore-order.test.js +0 -140
  922. package/dist/test/workspace-restore-order.test.js.map +0 -1
  923. package/dist/test/workspace-three-way.test.d.ts +0 -12
  924. package/dist/test/workspace-three-way.test.d.ts.map +0 -1
  925. package/dist/test/workspace-three-way.test.js +0 -4094
  926. package/dist/test/workspace-three-way.test.js.map +0 -1
  927. package/dist/test/workspace-watcher.test.d.ts +0 -2
  928. package/dist/test/workspace-watcher.test.d.ts.map +0 -1
  929. package/dist/test/workspace-watcher.test.js +0 -281
  930. package/dist/test/workspace-watcher.test.js.map +0 -1
  931. package/dist/test/xml-round-persist.test.d.ts +0 -19
  932. package/dist/test/xml-round-persist.test.d.ts.map +0 -1
  933. package/dist/test/xml-round-persist.test.js +0 -235
  934. package/dist/test/xml-round-persist.test.js.map +0 -1
  935. package/dist/tsconfig.tsbuildinfo +0 -1
@@ -12,13 +12,16 @@
12
12
  * - Expose synthesized tools: channel_list, channel_open, channel_close, channel_publish
13
13
  * - Build channel context for beforeInference params
14
14
  */
15
- import { INLINE_WITHHELD_TEXT, isInlineContradiction, referenceStubOrNull } from './references.js';
15
+ import { convertBlock } from './convert-block.js';
16
+ import { ensureStateRegistered } from '../module-registry.js';
16
17
  import { expandCoreTags } from './tags.js';
17
18
  import { coalesceRejectionReason, EmptyContentError, validateCoalescedContent } from './push-coalescer.js';
18
- import { isVisiblyEmptyContent } from './visible-content.js';
19
+ import { isVisiblyEmptyConversion } from './visible-content.js';
19
20
  import { logDetail, logValue } from './log-value.js';
20
21
  import { RefusalLines } from './refusal-lines.js';
21
22
  import { CapabilityGrant } from './capability-grant.js';
23
+ import { McplRequestError } from './server-connection.js';
24
+ import { readSkipReplyWake } from './skip-reply-wake.js';
22
25
  // ============================================================================
23
26
  // Typing indicator interval (Discord typing lasts ~10s, so 7s keeps it alive)
24
27
  // ============================================================================
@@ -83,81 +86,6 @@ function shallowEqualRecord(a, b) {
83
86
  return true;
84
87
  }
85
88
  // ============================================================================
86
- // Content Conversion: McplContentBlock → membrane ContentBlock
87
- // ============================================================================
88
- /**
89
- * Convert a single MCPL wire-format content block to a membrane ContentBlock.
90
- */
91
- function convertBlock(block) {
92
- switch (block.type) {
93
- case 'text':
94
- // Text that isn't a string is no text, as the request sanitizer and
95
- // the visible-content check already read it.
96
- return { type: 'text', text: typeof block.text === 'string' ? block.text : '' };
97
- case 'image':
98
- if (isInlineContradiction(block)) {
99
- // RFC-005 vector 2: inline data claiming bulk disposition — fail
100
- // closed, withhold the data (checked BEFORE the data branch).
101
- return { type: 'text', text: INLINE_WITHHELD_TEXT };
102
- }
103
- if (isFilledString(block.uri) && block.disposition) {
104
- // RFC-005 uri-form media with a disposition claim: stub, do not
105
- // hand the URI to the provider or inline it.
106
- return { type: 'text', text: referenceStubOrNull(block, 'attachment on channel message') ?? '[reference]' };
107
- }
108
- if (isFilledString(block.data) && isFilledString(block.mimeType)) {
109
- return {
110
- type: 'image',
111
- source: { type: 'base64', data: block.data, mediaType: block.mimeType },
112
- };
113
- }
114
- if (isFilledString(block.uri)) {
115
- return {
116
- type: 'image',
117
- source: { type: 'url', url: block.uri },
118
- };
119
- }
120
- return { type: 'text', text: isFilledString(block.data) ? '[Image: no media type]' : '[Image: no data]' };
121
- case 'audio':
122
- if (isInlineContradiction(block)) {
123
- // RFC-005 vector 2: inline data claiming bulk disposition — fail
124
- // closed, withhold the data (checked BEFORE the data branch).
125
- return { type: 'text', text: INLINE_WITHHELD_TEXT };
126
- }
127
- if (isFilledString(block.uri) && block.disposition) {
128
- // RFC-005 uri-form media with a disposition claim: stub, do not
129
- // hand the URI to the provider or inline it.
130
- return { type: 'text', text: referenceStubOrNull(block, 'attachment on channel message') ?? '[reference]' };
131
- }
132
- if (isFilledString(block.data) && isFilledString(block.mimeType)) {
133
- return {
134
- type: 'audio',
135
- source: { type: 'base64', data: block.data, mediaType: block.mimeType },
136
- };
137
- }
138
- return { type: 'text', text: isFilledString(block.data) ? '[Audio: no media type]' : '[Audio: no data]' };
139
- case 'resource':
140
- // RFC-005: reference blocks become bounded stubs — never raw URIs
141
- // (a signed URL is a bearer credential that looks like a location).
142
- return { type: 'text', text: referenceStubOrNull(block, 'attachment on channel message') ?? '[reference]' };
143
- default: {
144
- // Unknown wire block types previously fell off the exhaustive switch
145
- // and propagated `undefined` into ContentBlock[]. Fail visibly. A type
146
- // that isn't a string is no type, and is never converted to one: an
147
- // object can throw when it is.
148
- const type = block.type;
149
- return { type: 'text', text: `[unrecognized content block: ${typeof type === 'string' ? type : 'untyped'}]` };
150
- }
151
- }
152
- }
153
- /** A string with something in it: the only data, mimeType or uri a block's
154
- * source is built from, and the only uri that makes it a reference. Anything
155
- * else a sender puts there leaves the block without it, so conversion never
156
- * throws and never copies a non-string. */
157
- function isFilledString(value) {
158
- return typeof value === 'string' && value !== '';
159
- }
160
- // ============================================================================
161
89
  // Channel Tool Definitions
162
90
  // ============================================================================
163
91
  const CHANNEL_TOOL_DEFINITIONS = [
@@ -168,9 +96,8 @@ const CHANNEL_TOOL_DEFINITIONS = [
168
96
  },
169
97
  {
170
98
  name: 'channel_open',
171
- description: 'Open a channel to start receiving its ordinary ongoing traffic. The MCPL ' +
172
- 'integration performs its own subscribe/join/attach operation. Optionally request ' +
173
- 'history preceding the message that invited you into the channel.',
99
+ description: 'Open a channel. What an open channel delivers to you depends on its MCPL server. ' +
100
+ 'Optionally request history preceding the message that invited you into the channel.',
174
101
  inputSchema: {
175
102
  type: 'object',
176
103
  properties: {
@@ -209,7 +136,8 @@ const CHANNEL_TOOL_DEFINITIONS = [
209
136
  },
210
137
  {
211
138
  name: 'channel_close',
212
- description: 'Close a channel to stop receiving messages',
139
+ description: 'Close a channel. Messages that address you still reach you; what else stops reaching you ' +
140
+ 'depends on its server.',
213
141
  inputSchema: {
214
142
  type: 'object',
215
143
  properties: {
@@ -283,14 +211,90 @@ const CHANNEL_TOOL_DEFINITIONS = [
283
211
  wake_in_seconds: {
284
212
  type: 'number',
285
213
  description: 'Optional self-wake: if nothing else wakes you first, you wake again after this ' +
286
- 'many seconds (1 = go again almost immediately; clamped to 1–3600). Any other ' +
287
- 'wake before then cancels it. Omit to stay idle until the next external wake.',
214
+ 'many seconds, from 1 to 3600; a larger number waits 3600 (1 = go again almost ' +
215
+ 'immediately). Any other wake before then cancels it. Omit to stay idle until the ' +
216
+ 'next external wake.',
288
217
  },
289
218
  },
290
219
  required: [],
291
220
  },
292
221
  },
293
222
  ];
223
+ // ============================================================================
224
+ // Constructor Options
225
+ // ============================================================================
226
+ /** Bound connector values for notices, logs and an outcome's reason. A
227
+ * PublishOutcome keeps the connector's structured data (`detail`) whole. */
228
+ export function connectorText(value) {
229
+ let text;
230
+ try {
231
+ text = typeof value === 'string' ? value : JSON.stringify(value) ?? String(value);
232
+ }
233
+ catch {
234
+ return '[unserializable connector value]';
235
+ }
236
+ const limit = 2000;
237
+ const suffix = '… [truncated]';
238
+ return text.length > limit ? text.slice(0, limit - suffix.length) + suffix : text;
239
+ }
240
+ /**
241
+ * What a channels/publish request that threw establishes. Only a request
242
+ * that never left the host proves nothing was posted. An error response may
243
+ * follow a partial post (a multi-part send whose later part failed), so it
244
+ * is unknown, with the connector's own words, bounded, and its data kept for
245
+ * the resident to judge. The publish executor and channel_publish both read
246
+ * a failed request this way.
247
+ */
248
+ function publishErrorOutcome(err, destination, at) {
249
+ const message = connectorText(err instanceof Error ? err.message : String(err));
250
+ const notSent = err instanceof McplRequestError && err.outcome === 'not-sent';
251
+ const detail = err instanceof McplRequestError ? err.data : undefined;
252
+ return {
253
+ status: notSent ? 'failed' : 'unknown',
254
+ destination,
255
+ reason: notSent ? message : `${message} (delivery uncertain)`,
256
+ ...(detail !== undefined ? { detail } : {}),
257
+ at,
258
+ };
259
+ }
260
+ /**
261
+ * What a channels/publish answer establishes. A final publish is a request,
262
+ * so success requires an explicit receipt; a missing or malformed one leaves
263
+ * delivery uncertain (anima-research/agent-framework#163's rule).
264
+ * `delivered: false` proves nothing went out only when the receipt names no
265
+ * message at all: a message id beside it, valid or malformed, contradicts it,
266
+ * since something may have been posted. The publish executor and
267
+ * channel_publish both read an answer this way.
268
+ */
269
+ function publishReceiptOutcome(result, destination, at) {
270
+ const receipt = (result ?? {});
271
+ const messageId = typeof receipt.messageId === 'string' && receipt.messageId ? receipt.messageId : undefined;
272
+ if (receipt.delivered === true) {
273
+ return { status: 'delivered', destination, ...(messageId ? { messageId } : {}), at };
274
+ }
275
+ if (receipt.delivered === false) {
276
+ if (receipt.messageId === undefined || receipt.messageId === null) {
277
+ return { status: 'failed', destination, reason: `server "${destination.serverId}" reported delivered:false`, at };
278
+ }
279
+ return {
280
+ status: 'unknown',
281
+ destination,
282
+ ...(messageId ? { messageId } : {}),
283
+ reason: messageId
284
+ ? `server "${destination.serverId}" reported delivered:false but named posted message ${connectorText(messageId)} (delivery uncertain)`
285
+ : `server "${destination.serverId}" reported delivered:false beside a malformed message id ` +
286
+ `${connectorText(receipt.messageId)} (contradictory receipt; delivery uncertain)`,
287
+ at,
288
+ };
289
+ }
290
+ return {
291
+ status: 'unknown',
292
+ destination,
293
+ ...(messageId ? { messageId } : {}),
294
+ reason: `server "${destination.serverId}" returned no valid delivery receipt (delivery uncertain)`,
295
+ at,
296
+ };
297
+ }
294
298
  /** The machine decision sources a module-origin channel_close may record.
295
299
  * Closed on purpose: honest provenance means a small, auditable vocabulary,
296
300
  * not arbitrary self-description. */
@@ -375,8 +379,22 @@ export class ChannelRegistry {
375
379
  legacyPolicies = new Map();
376
380
  migratedLegacyPolicies = new Set();
377
381
  handleCoalescedIncoming;
382
+ acceptInbound;
383
+ channelTools;
378
384
  constructor(serverRegistry, featureSetManager, pushEventFn, emitTraceFn, options) {
379
385
  this.handleCoalescedIncoming = options?.handleCoalescedIncoming;
386
+ this.acceptInbound = options?.acceptInbound;
387
+ this.channelTools = CHANNEL_TOOL_DEFINITIONS.map((tool) => {
388
+ if (tool.name !== 'skip_reply' || options?.eventGatePresent === true)
389
+ return tool;
390
+ const schema = tool.inputSchema;
391
+ const { wake_in_seconds: _wake, ...properties } = schema.properties;
392
+ return {
393
+ ...tool,
394
+ description: tool.description.replace(' To end this turn but come back on your own shortly, set wake_in_seconds.', ''),
395
+ inputSchema: { ...schema, properties },
396
+ };
397
+ });
380
398
  this.serverRegistry = serverRegistry;
381
399
  this.featureSetManager = featureSetManager;
382
400
  this.pushEventFn = pushEventFn;
@@ -677,8 +695,8 @@ export class ChannelRegistry {
677
695
  }
678
696
  if (message.tags)
679
697
  message.tags = expandCoreTags(message.tags);
680
- const convertedContent = message.content.map(convertBlock);
681
- if (!emptyAllowed && isVisiblyEmptyContent(convertedContent)) {
698
+ const convertedContent = message.content.map((block) => convertBlock(block, 'attachment on channel message', serverId));
699
+ if (!emptyAllowed && isVisiblyEmptyConversion(message.content, convertedContent)) {
682
700
  rejectEmpty();
683
701
  continue;
684
702
  }
@@ -705,7 +723,7 @@ export class ChannelRegistry {
705
723
  if (this.shouldTriggerInference) {
706
724
  // The text the agent's context gets, as the push lane's filter reads
707
725
  // it: the converted text blocks, a placeholder or reference stub
708
- // among them, and a text block's non-string text as empty text.
726
+ // among them, NON_STRING_TEXT_PLACEHOLDER included.
709
727
  const textContent = convertedContent
710
728
  .filter((b) => b.type === 'text')
711
729
  .map((b) => b.text)
@@ -734,6 +752,7 @@ export class ChannelRegistry {
734
752
  metadata: message.metadata,
735
753
  ...(message.tags ? { tags: message.tags } : {}),
736
754
  triggerInference,
755
+ acceptedAt: Date.now(),
737
756
  };
738
757
  if (coalesced) {
739
758
  // RFC-006 §14.3: a coalesced message is admitted like any other and
@@ -759,6 +778,12 @@ export class ChannelRegistry {
759
778
  }
760
779
  continue;
761
780
  }
781
+ // The source envelope is frozen here, at admission, before the message
782
+ // is queued or acknowledged: a rename or rebind while it waits in the
783
+ // queue cannot change where it says it came from.
784
+ const inboundSource = this.acceptInbound?.(event);
785
+ if (inboundSource)
786
+ event.inboundSource = inboundSource;
762
787
  // Push to the processing queue
763
788
  // Cast through unknown because McplChannelIncomingEvent matches the
764
789
  // CustomEvent `${string}:${string}` type pattern but lacks an index signature.
@@ -801,27 +826,19 @@ export class ChannelRegistry {
801
826
  // time a message reveals it (labels must show people, not ids).
802
827
  if (existing.descriptor.metadata?.lazyRegistered &&
803
828
  label && existing.descriptor.label === channelId) {
804
- existing.descriptor.label = label;
805
- if (extraMetadata) {
806
- existing.descriptor.metadata = { ...existing.descriptor.metadata, ...extraMetadata };
807
- }
829
+ const metadata = extraMetadata
830
+ ? { ...existing.descriptor.metadata, ...extraMetadata }
831
+ : existing.descriptor.metadata;
808
832
  // The channel now has a real label, not just the bare id — durable.
809
- this.appendLabelSighting(existing.descriptor.id, existing.descriptor.label, extractDmMeta(existing.descriptor.metadata));
833
+ // Recorded before the live descriptor takes it, since this branch's
834
+ // guard reads the descriptor: an append that throws leaves the
835
+ // placeholder, so the next push tries again.
836
+ this.appendLabelSighting(existing.descriptor.id, label, extractDmMeta(metadata));
837
+ existing.descriptor.label = label;
838
+ existing.descriptor.metadata = metadata;
810
839
  }
811
840
  return;
812
841
  }
813
- const key = `${serverId}:${channelId}`;
814
- this.channels.set(key, {
815
- serverId,
816
- descriptor: {
817
- id: channelId,
818
- type: serverId,
819
- label: label ?? channelId,
820
- direction: 'bidirectional',
821
- metadata: { lazyRegistered: true, ...(extraMetadata ?? {}) },
822
- },
823
- open: false,
824
- });
825
842
  // Only persist a REAL label durably. Falling back to the bare
826
843
  // channelId as a placeholder (no server-supplied label at all — e.g. a
827
844
  // Discord DM push missing both channelName and an author name,
@@ -831,11 +848,24 @@ export class ChannelRegistry {
831
848
  // label-less post-restart event takes — recording the placeholder here
832
849
  // would clobber the good label initializeLabelHistoryStore() just
833
850
  // replayed, defeating the entire point of the durable log. The live
834
- // descriptor above still carries the placeholder for in-process
851
+ // descriptor below still carries the placeholder for in-process
835
852
  // routing; only the durable write is skipped when there's no real
836
- // label to record.
853
+ // label to record. A real label is recorded before the entry exists:
854
+ // an append that throws registers nothing, so the next push tries again.
837
855
  if (label)
838
856
  this.appendLabelSighting(channelId, label, extractDmMeta(extraMetadata));
857
+ const key = `${serverId}:${channelId}`;
858
+ this.channels.set(key, {
859
+ serverId,
860
+ descriptor: {
861
+ id: channelId,
862
+ type: serverId,
863
+ label: label ?? channelId,
864
+ direction: 'bidirectional',
865
+ metadata: { lazyRegistered: true, ...(extraMetadata ?? {}) },
866
+ },
867
+ open: false,
868
+ });
839
869
  this.emitTraceFn({
840
870
  type: 'mcpl:channel-lazy-registered',
841
871
  serverId,
@@ -958,6 +988,12 @@ export class ChannelRegistry {
958
988
  getDescriptor(channelId) {
959
989
  return this.findChannelEntry(channelId)?.descriptor;
960
990
  }
991
+ /** The registered label of `channelId` on exactly `serverId` (no
992
+ * cross-server first match), or undefined when it has none. */
993
+ getChannelLabel(serverId, channelId) {
994
+ const label = this.channels.get(`${serverId}:${channelId}`)?.descriptor.label;
995
+ return typeof label === 'string' && label.length > 0 ? label : undefined;
996
+ }
961
997
  isChannelOpen(channelId) {
962
998
  return this.findChannelEntry(channelId)?.open === true;
963
999
  }
@@ -983,7 +1019,7 @@ export class ChannelRegistry {
983
1019
  * Get synthesized tool definitions for channel operations.
984
1020
  */
985
1021
  getChannelTools() {
986
- return CHANNEL_TOOL_DEFINITIONS;
1022
+ return this.channelTools;
987
1023
  }
988
1024
  /**
989
1025
  * Handle a call to one of the synthesized channel tools.
@@ -1112,14 +1148,7 @@ export class ChannelRegistry {
1112
1148
  initializeLifecycleStore() {
1113
1149
  if (!this.store)
1114
1150
  return;
1115
- try {
1116
- this.store.registerState({ id: CHANNEL_LIFECYCLE_LOG_ID, strategy: 'append_log' });
1117
- }
1118
- catch (error) {
1119
- if (!(error instanceof Error) || !error.message.includes('State already exists')) {
1120
- throw error;
1121
- }
1122
- }
1151
+ ensureStateRegistered(this.store, { id: CHANNEL_LIFECYCLE_LOG_ID, strategy: 'append_log' });
1123
1152
  const raw = this.store.getStateJson(CHANNEL_LIFECYCLE_LOG_ID);
1124
1153
  if (!Array.isArray(raw))
1125
1154
  return;
@@ -1157,6 +1186,15 @@ export class ChannelRegistry {
1157
1186
  }
1158
1187
  }
1159
1188
  }
1189
+ /**
1190
+ * Each writer appends its record here before it changes memory for it, so
1191
+ * an append that throws, as on a full disk, fails the operation with that
1192
+ * change unmade, and memory and the log still agree. A retry then records
1193
+ * the change rather than finding it in memory already, where
1194
+ * setDesiredState's same-state return would record nothing, and a restart
1195
+ * replays what memory held. appendLabelSighting keeps the same order for
1196
+ * the label history.
1197
+ */
1160
1198
  appendLifecycleEvent(event) {
1161
1199
  this.store?.appendToStateJson(CHANNEL_LIFECYCLE_LOG_ID, event);
1162
1200
  }
@@ -1173,14 +1211,7 @@ export class ChannelRegistry {
1173
1211
  initializeLabelHistoryStore() {
1174
1212
  if (!this.store)
1175
1213
  return;
1176
- try {
1177
- this.store.registerState({ id: CHANNEL_LABEL_HISTORY_LOG_ID, strategy: 'append_log' });
1178
- }
1179
- catch (error) {
1180
- if (!(error instanceof Error) || !error.message.includes('State already exists')) {
1181
- throw error;
1182
- }
1183
- }
1214
+ ensureStateRegistered(this.store, { id: CHANNEL_LABEL_HISTORY_LOG_ID, strategy: 'append_log' });
1184
1215
  const raw = this.store.getStateJson(CHANNEL_LABEL_HISTORY_LOG_ID);
1185
1216
  if (!Array.isArray(raw))
1186
1217
  return;
@@ -1260,6 +1291,16 @@ export class ChannelRegistry {
1260
1291
  const isDmUnchanged = isDm === undefined || this.dmClassified.get(channelId) === true;
1261
1292
  if (labelUnchanged && recipientIdUnchanged && recipientNameUnchanged && isDmUnchanged)
1262
1293
  return;
1294
+ // The log first, as for lifecycle events: an append that throws leaves
1295
+ // the history in memory as it was, so the next sighting records it.
1296
+ this.store?.appendToStateJson(CHANNEL_LABEL_HISTORY_LOG_ID, {
1297
+ channelId,
1298
+ label,
1299
+ ts: Date.now(),
1300
+ ...(recipientId ? { recipientId } : {}),
1301
+ ...(recipientName ? { recipientName } : {}),
1302
+ ...(isDm ? { isDm } : {}),
1303
+ });
1263
1304
  this.labelHistory.set(channelId, label);
1264
1305
  let seen = this.allLabelsSeen.get(channelId);
1265
1306
  if (!seen) {
@@ -1273,14 +1314,6 @@ export class ChannelRegistry {
1273
1314
  this.dmRecipientNames.set(channelId, recipientName);
1274
1315
  if (isDm)
1275
1316
  this.dmClassified.set(channelId, true);
1276
- this.store?.appendToStateJson(CHANNEL_LABEL_HISTORY_LOG_ID, {
1277
- channelId,
1278
- label,
1279
- ts: Date.now(),
1280
- ...(recipientId ? { recipientId } : {}),
1281
- ...(recipientName ? { recipientName } : {}),
1282
- ...(isDm ? { isDm } : {}),
1283
- });
1284
1317
  }
1285
1318
  /**
1286
1319
  * Look up a label spec against label *history* rather than the live
@@ -1498,7 +1531,6 @@ export class ChannelRegistry {
1498
1531
  const key = this.lifecycleKey(serverId, channelId);
1499
1532
  if (this.desiredStates.get(key)?.state === desired)
1500
1533
  return;
1501
- this.desiredStates.set(key, { state: desired, source });
1502
1534
  this.appendLifecycleEvent({
1503
1535
  kind: 'desired-state',
1504
1536
  serverId,
@@ -1507,6 +1539,7 @@ export class ChannelRegistry {
1507
1539
  source,
1508
1540
  timestamp: new Date().toISOString(),
1509
1541
  });
1542
+ this.desiredStates.set(key, { state: desired, source });
1510
1543
  }
1511
1544
  // ==========================================================================
1512
1545
  // Tune-out state (issue #77) — durable in the lifecycle log
@@ -1519,12 +1552,6 @@ export class ChannelRegistry {
1519
1552
  */
1520
1553
  enterTuneOut(serverId, channelId, params, source) {
1521
1554
  const key = this.lifecycleKey(serverId, channelId);
1522
- this.desiredStates.set(key, {
1523
- state: 'tuned-out',
1524
- source,
1525
- tuneOut: params,
1526
- wakeCount: 0,
1527
- });
1528
1555
  this.appendLifecycleEvent({
1529
1556
  kind: 'desired-state',
1530
1557
  serverId,
@@ -1534,6 +1561,12 @@ export class ChannelRegistry {
1534
1561
  source,
1535
1562
  timestamp: new Date().toISOString(),
1536
1563
  });
1564
+ this.desiredStates.set(key, {
1565
+ state: 'tuned-out',
1566
+ source,
1567
+ tuneOut: params,
1568
+ wakeCount: 0,
1569
+ });
1537
1570
  }
1538
1571
  /**
1539
1572
  * End the active tune-out, returning the channel to `nextState`.
@@ -1547,7 +1580,6 @@ export class ChannelRegistry {
1547
1580
  if (current?.state !== 'tuned-out' || !current.tuneOut)
1548
1581
  return null;
1549
1582
  const ended = { params: current.tuneOut, wakeCount: current.wakeCount ?? 0 };
1550
- this.desiredStates.set(key, { state: nextState, source });
1551
1583
  this.appendLifecycleEvent({
1552
1584
  kind: 'desired-state',
1553
1585
  serverId,
@@ -1556,6 +1588,7 @@ export class ChannelRegistry {
1556
1588
  source,
1557
1589
  timestamp: new Date().toISOString(),
1558
1590
  });
1591
+ this.desiredStates.set(key, { state: nextState, source });
1559
1592
  return ended;
1560
1593
  }
1561
1594
  /**
@@ -1570,16 +1603,17 @@ export class ChannelRegistry {
1570
1603
  const current = this.desiredStates.get(key);
1571
1604
  if (current?.state !== 'tuned-out' || !current.tuneOut)
1572
1605
  return null;
1573
- current.wakeCount = (current.wakeCount ?? 0) + 1;
1606
+ const wakeCount = (current.wakeCount ?? 0) + 1;
1574
1607
  this.appendLifecycleEvent({
1575
1608
  kind: 'tune-out-wake',
1576
1609
  serverId,
1577
1610
  channelId,
1578
1611
  epochId: current.tuneOut.epochId,
1579
- wakeCount: current.wakeCount,
1612
+ wakeCount,
1580
1613
  timestamp: new Date().toISOString(),
1581
1614
  });
1582
- return { params: current.tuneOut, wakeCount: current.wakeCount };
1615
+ current.wakeCount = wakeCount;
1616
+ return { params: current.tuneOut, wakeCount };
1583
1617
  }
1584
1618
  /** Active tune-out params + wake count for a channel, or null. */
1585
1619
  getTuneOutState(serverId, channelId) {
@@ -1603,19 +1637,13 @@ export class ChannelRegistry {
1603
1637
  readCoordinatorState(stateId) {
1604
1638
  if (!this.store)
1605
1639
  return null;
1606
- try {
1607
- this.store.registerState({ id: stateId, strategy: 'snapshot' });
1608
- }
1609
- catch { /* already registered */ }
1640
+ ensureStateRegistered(this.store, { id: stateId, strategy: 'snapshot' });
1610
1641
  return this.store.getStateJson(stateId);
1611
1642
  }
1612
1643
  writeCoordinatorState(stateId, value) {
1613
1644
  if (!this.store)
1614
1645
  return;
1615
- try {
1616
- this.store.registerState({ id: stateId, strategy: 'snapshot' });
1617
- }
1618
- catch { /* already registered */ }
1646
+ ensureStateRegistered(this.store, { id: stateId, strategy: 'snapshot' });
1619
1647
  this.store.setStateJson(stateId, value);
1620
1648
  }
1621
1649
  /**
@@ -1646,13 +1674,13 @@ export class ChannelRegistry {
1646
1674
  : 'closed';
1647
1675
  this.setDesiredState(serverId, channel.id, desired, 'legacy-recipe-migration');
1648
1676
  }
1649
- this.migratedLegacyPolicies.add(serverId);
1650
1677
  this.appendLifecycleEvent({
1651
1678
  kind: 'legacy-policy-migrated',
1652
1679
  serverId,
1653
1680
  source: Array.isArray(policy) ? 'allow-list' : policy,
1654
1681
  timestamp: new Date().toISOString(),
1655
1682
  });
1683
+ this.migratedLegacyPolicies.add(serverId);
1656
1684
  }
1657
1685
  /**
1658
1686
  * True when the server's recipe subscription policy wants this channel
@@ -1768,9 +1796,9 @@ export class ChannelRegistry {
1768
1796
  });
1769
1797
  }
1770
1798
  }
1771
- // Announce policy admissions to the agent — nothing may start flowing
1772
- // traffic into their window without them being told, and told how to
1773
- // opt out (channel_close; their decision outranks policy).
1799
+ // Announce policy admissions to the agent — no channel may open without
1800
+ // them being told, and told how to opt out (channel_close; their
1801
+ // decision outranks policy).
1774
1802
  if (policyOpened.length > 0) {
1775
1803
  try {
1776
1804
  this.onChannelAutoOpened?.({
@@ -2128,11 +2156,13 @@ export class ChannelRegistry {
2128
2156
  // A tuned-out channel is transport-open but attention-diverted; a plain
2129
2157
  // open would silently discard the epoch (and its pending backlog dump).
2130
2158
  // Cancelling is the tune-out coordinator's flow, reached via its own
2131
- // tool — refuse with the pointer rather than eat the state.
2159
+ // tool — refuse with the pointer rather than eat the state. As an error
2160
+ // result, the agent reads the pointer itself; `data` names the refusal
2161
+ // for an in-process caller.
2132
2162
  if (this.getDesiredState(entry.serverId, input.channelId) === 'tuned-out') {
2133
2163
  return {
2134
2164
  success: false,
2135
- isError: false,
2165
+ isError: true,
2136
2166
  error: `Channel ${input.channelId} is tuned out. Cancel the tune-out ` +
2137
2167
  `(tune_out with mode: 'cancel') to resume normal attention — ` +
2138
2168
  `cancelling delivers the diverted backlog.`,
@@ -2269,7 +2299,7 @@ export class ChannelRegistry {
2269
2299
  if (entry.open || this.getDesiredState(entry.serverId, input.channelId) === 'open') {
2270
2300
  return {
2271
2301
  success: false,
2272
- error: `Channel is already open: ${input.channelId}. Use channel_close to leave it.`,
2302
+ error: `Channel is already open: ${input.channelId}. Use channel_close to close it.`,
2273
2303
  isError: true,
2274
2304
  };
2275
2305
  }
@@ -2375,12 +2405,13 @@ export class ChannelRegistry {
2375
2405
  */
2376
2406
  handleToolSkipReply(input) {
2377
2407
  // The self-wake itself is armed by the framework (which owns the
2378
- // EventGate) BEFORE this dispatch; when the gate is absent the framework
2379
- // strips the field so this confirmation stays truthful.
2380
- const wakeSecs = Number(input.wake_in_seconds);
2381
- const selfWake = Number.isFinite(wakeSecs) && wakeSecs > 0
2382
- ? Math.max(1, Math.min(3600, Math.floor(wakeSecs)))
2383
- : undefined;
2408
+ // EventGate) BEFORE its dispatch reaches this handler, from the same
2409
+ // reading, and the framework refuses a wake the host can't set before
2410
+ // dispatching. A caller of this registry's handleChannelToolCall
2411
+ // (AgentFramework.channels) goes past both, so its note names a wake
2412
+ // nothing armed.
2413
+ const wake = readSkipReplyWake(input);
2414
+ const selfWake = wake.kind === 'wake' ? wake.seconds : undefined;
2384
2415
  return {
2385
2416
  success: true,
2386
2417
  // The note says "ended the turn" — make it TRUE. Without endTurn the
@@ -2466,7 +2497,158 @@ export class ChannelRegistry {
2466
2497
  const home = this.homeChannelResolver?.(conversationId);
2467
2498
  return home ?? this.activeChannelResolver?.(conversationId) ?? this.defaultPublishChannel ?? null;
2468
2499
  }
2469
- async routeSpeech(conversationId, text,
2500
+ /**
2501
+ * Resolve a publish target to exactly one registered channel: `serverId`
2502
+ * plus `channelId` when the caller has the server, otherwise a channel id
2503
+ * registered by exactly one server. A shared id is refused, never resolved
2504
+ * to whichever server registered it first.
2505
+ */
2506
+ resolveDestination(target) {
2507
+ const entry = this.findExactEntry(target);
2508
+ if ('error' in entry)
2509
+ return entry;
2510
+ return {
2511
+ destination: {
2512
+ serverId: entry.entry.serverId,
2513
+ channelId: entry.entry.descriptor.id,
2514
+ ...(entry.entry.descriptor.label ? { label: entry.entry.descriptor.label } : {}),
2515
+ },
2516
+ };
2517
+ }
2518
+ findExactEntry(target) {
2519
+ // A supplied selector is checked, never read as omission: an empty or
2520
+ // non-string serverId would otherwise widen to "any server".
2521
+ if (typeof target.channelId !== 'string' || !target.channelId) {
2522
+ return { error: 'the destination names no channel id' };
2523
+ }
2524
+ if (target.serverId !== undefined && (typeof target.serverId !== 'string' || !target.serverId)) {
2525
+ return { error: 'serverId must name a server (omit it to resolve the channel id alone)' };
2526
+ }
2527
+ const matches = [...this.channels.values()].filter((e) => e.descriptor.id === target.channelId && (!target.serverId || e.serverId === target.serverId));
2528
+ if (matches.length === 0) {
2529
+ return {
2530
+ error: target.serverId
2531
+ ? `no registered channel "${target.channelId}" on server "${target.serverId}"`
2532
+ : `no registered channel "${target.channelId}"`,
2533
+ };
2534
+ }
2535
+ if (matches.length > 1) {
2536
+ return {
2537
+ error: `channel id "${target.channelId}" is registered by more than one MCPL server; the destination must name its server`,
2538
+ };
2539
+ }
2540
+ return { entry: matches[0] };
2541
+ }
2542
+ /**
2543
+ * Publish `text` to one registered channel and report what the attempt
2544
+ * established (PublishOutcome). The delivery executor behind plain speech
2545
+ * (deliverSpeech / routeSpeech) and resident resends of held drafts.
2546
+ * channel_publish (and publishForAgent, which shares its handler) resolves
2547
+ * and sends on its own path, and reads its answer through the same
2548
+ * publishReceiptOutcome and publishErrorOutcome.
2549
+ *
2550
+ * Resolution is exact (resolveDestination): `serverId` plus `channelId`
2551
+ * when the caller has the server, otherwise the channel id must be
2552
+ * registered by exactly one server (a shared id is refused, never routed
2553
+ * through whichever server came first). An omitted `serverId` means "not
2554
+ * in use"; a supplied one must be a non-empty server id, and an empty or
2555
+ * non-string selector is refused rather than read as omission. It is not
2556
+ * possible to send into a closed channel: a closed but registered
2557
+ * destination is opened first (`openSource` names why), once its server
2558
+ * and that server's channels.publish grant are known to take the send, so
2559
+ * a refused send opens nothing; and a failed open sends nothing.
2560
+ *
2561
+ * Only the connector's `delivered: true` confirms a post. `failed` means
2562
+ * nothing was posted: the attempt stopped before the request was written,
2563
+ * or the connector answered `delivered: false` and named no message (no
2564
+ * `messageId`, or null). Everything else is `unknown`: once the request
2565
+ * has been handed to the transport, an error response, a timeout, a lost
2566
+ * connection, or a missing, malformed or contradictory receipt (such as
2567
+ * `delivered: false` beside a message id, valid or not) means the post may
2568
+ * or may not exist, and the caller must not treat it as safe to retry
2569
+ * blindly.
2570
+ */
2571
+ async publish(conversationId, text, target, openSource = 'opened-by-delivery') {
2572
+ const at = () => Date.now();
2573
+ const found = this.findExactEntry(target);
2574
+ if ('error' in found)
2575
+ return { status: 'failed', reason: found.error, at: at() };
2576
+ const entry = found.entry;
2577
+ const destination = {
2578
+ serverId: entry.serverId,
2579
+ channelId: entry.descriptor.id,
2580
+ ...(entry.descriptor.label ? { label: entry.descriptor.label } : {}),
2581
+ };
2582
+ // A send that would be refused is refused before anything opens: a
2583
+ // closed channel opens only for words that can go out.
2584
+ const server = this.serverRegistry.getServer(entry.serverId);
2585
+ if (!server) {
2586
+ return { status: 'failed', destination, reason: `server "${entry.serverId}" not found`, at: at() };
2587
+ }
2588
+ // §14.1: channels/publish requires channels.publish in the grant. The
2589
+ // host not sending is the enforcement.
2590
+ if (!CapabilityGrant.of(server).has('channels.publish')) {
2591
+ return {
2592
+ status: 'failed',
2593
+ destination,
2594
+ reason: `channels.publish not in "${entry.serverId}"'s effective grant (§14.1)`,
2595
+ at: at(),
2596
+ };
2597
+ }
2598
+ if (!entry.open) {
2599
+ try {
2600
+ await this.openChannelNow(entry, openSource);
2601
+ if (target.routed) {
2602
+ console.error(`[routeSpeech] ${conversationId}: locus ${logValue(entry.descriptor.id)} was closed — opened by delivery (speech implies engagement)`);
2603
+ }
2604
+ this.emitTraceFn({
2605
+ type: 'mcpl:channel-opened-by-send',
2606
+ serverId: entry.serverId,
2607
+ channelId: entry.descriptor.id,
2608
+ });
2609
+ if (openSource === 'opened-by-delivery') {
2610
+ try {
2611
+ this.onChannelAutoOpened?.({
2612
+ conversationId,
2613
+ serverId: entry.serverId,
2614
+ source: 'opened-by-delivery',
2615
+ channels: [{ channelId: entry.descriptor.id, label: entry.descriptor.label }],
2616
+ });
2617
+ }
2618
+ catch (err) {
2619
+ console.error('onChannelAutoOpened (delivery) failed:', err);
2620
+ }
2621
+ }
2622
+ }
2623
+ catch (err) {
2624
+ return {
2625
+ status: 'failed',
2626
+ destination,
2627
+ reason: `channel is closed and open failed: ${connectorText(err instanceof Error ? err.message : String(err))}`,
2628
+ at: at(),
2629
+ };
2630
+ }
2631
+ }
2632
+ let result;
2633
+ try {
2634
+ result = await server.sendChannelsPublish({
2635
+ conversationId,
2636
+ channelId: entry.descriptor.id,
2637
+ content: [{ type: 'text', text }],
2638
+ });
2639
+ }
2640
+ catch (err) {
2641
+ return publishErrorOutcome(err, destination, at());
2642
+ }
2643
+ return publishReceiptOutcome(result, destination, at());
2644
+ }
2645
+ /**
2646
+ * Plain speech for one turn segment: publish `text` to the turn's frozen
2647
+ * locus and report the PublishOutcome. A failure (or an uncertain outcome)
2648
+ * is surfaced as a trace and through onRouteFailure, so the agent learns
2649
+ * its words did not (or may not have) reached anyone.
2650
+ */
2651
+ async deliverSpeech(conversationId, text,
2470
2652
  /** The turn's FROZEN locus, snapshotted once by the caller (resolveLocus
2471
2653
  * at turn start) and passed to every segment of the turn. Mandatory:
2472
2654
  * there is deliberately no live-resolution fallback here — a late
@@ -2474,110 +2656,75 @@ export class ChannelRegistry {
2474
2656
  * stale global default and land the reply in the wrong channel (item-3,
2475
2657
  * PR #32, and the 2026-07-22 Sol DM misroute). Explicit `null` means
2476
2658
  * "this turn is pinned to no locus": fail loudly rather than guess. */
2477
- locusChannelId) {
2478
- // Surface a routing failure: emit a trace AND notify the host (which drops
2479
- // a `[discord-send-failed]` marker into chronicle) so the agent learns her
2480
- // reply never reached the human, instead of it vanishing silently.
2481
- const fail = (channelId, reason) => {
2482
- console.error(`[routeSpeech] ${conversationId}: ${reason} — speech NOT routed (${text.length} chars stay in chronicle)`);
2659
+ locusChannelId,
2660
+ /** `heldOnFailure`: the caller holds a `failed` delivery's words as a
2661
+ * draft with its own notice, so no failure marker is written for it.
2662
+ * An `unknown` outcome still gets its marker. */
2663
+ opts) {
2664
+ const fail = (channelId, reason, outcome) => {
2665
+ const status = outcome.status === 'unknown' ? 'unknown' : 'failed';
2666
+ const detail = outcome.detail !== undefined ? connectorText(outcome.detail) : undefined;
2667
+ const detailText = detail !== undefined ? `; connector detail: ${detail}` : '';
2668
+ console.error(`[routeSpeech] ${conversationId}: ${reason}${detailText} — speech ${status === 'unknown' ? 'delivery NOT confirmed' : 'NOT routed'} (${text.length} chars stay in chronicle)`);
2483
2669
  this.emitTraceFn({
2484
2670
  type: 'mcpl:speech-route-failed',
2485
2671
  conversationId,
2486
2672
  channelId: channelId ?? '',
2487
2673
  reason,
2488
2674
  textLen: text.length,
2675
+ outcome: status,
2676
+ ...(detail !== undefined ? { detail } : {}),
2489
2677
  });
2490
- this.onRouteFailure?.({ conversationId, channelId, reason, textLen: text.length });
2491
- return null;
2678
+ if (status === 'unknown' || !opts?.heldOnFailure) {
2679
+ this.onRouteFailure?.({ conversationId, channelId, reason, textLen: text.length, outcome: status, ...(detail !== undefined ? { detail } : {}) });
2680
+ }
2681
+ return outcome;
2492
2682
  };
2493
2683
  // Runtime backstop for JS callers the compiler can't see: an omitted
2494
2684
  // locus is a routing bug at the call site, never something to paper over
2495
2685
  // with a live re-resolution.
2496
2686
  if (locusChannelId === undefined) {
2497
- return fail(null, 'caller passed no locus (routing bug: every speech path must snapshot the turn locus)');
2687
+ const reason = 'caller passed no locus (routing bug: every speech path must snapshot the turn locus)';
2688
+ return fail(null, reason, { status: 'failed', reason, at: Date.now() });
2498
2689
  }
2499
- const channelId = locusChannelId;
2500
- if (!channelId) {
2690
+ if (!locusChannelId) {
2501
2691
  // The turn froze with no locus (no home, no triggering channel, no
2502
2692
  // global inbound ever seen) — the agent was told its prose stays in
2503
2693
  // the archive; honor that.
2504
- return fail(null, 'turn has no locus (no home/trigger channel; nothing to deliver into)');
2505
- }
2506
- const entry = this.findChannelEntry(channelId);
2507
- if (!entry) {
2508
- return fail(channelId, `no registered channel for locus "${channelId}"`);
2509
- }
2510
- // INVARIANT: it is not possible to send into a closed channel. Speech
2511
- // routed into a closed-but-registered locus (the canonical case: a DM
2512
- // that woke the agent — DMs register closed) OPENS the channel first,
2513
- // so typing indicators, reaction machinery, and inbound forwarding come
2514
- // alive with the reply. If the open fails, the speech does NOT go out:
2515
- // a half-alive delivery is worse than a loud marker.
2516
- if (!entry.open) {
2517
- try {
2518
- await this.openChannelNow(entry, 'opened-by-delivery');
2519
- console.error(`[routeSpeech] ${conversationId}: locus ${logValue(channelId)} was closed — opened by delivery (speech implies engagement)`);
2520
- this.emitTraceFn({
2521
- type: 'mcpl:channel-opened-by-send',
2522
- serverId: entry.serverId,
2523
- channelId,
2524
- });
2525
- try {
2526
- this.onChannelAutoOpened?.({
2527
- conversationId,
2528
- serverId: entry.serverId,
2529
- source: 'opened-by-delivery',
2530
- channels: [{ channelId, label: entry.descriptor.label }],
2531
- });
2532
- }
2533
- catch (err) {
2534
- console.error('onChannelAutoOpened (delivery) failed:', err);
2535
- }
2536
- }
2537
- catch (err) {
2538
- return fail(channelId, `locus channel is closed and open failed: ${err.message}`);
2539
- }
2694
+ const reason = 'turn has no locus (no home/trigger channel; nothing to deliver into)';
2695
+ return fail(null, reason, { status: 'failed', reason, at: Date.now() });
2540
2696
  }
2541
- const server = this.serverRegistry.getServer(entry.serverId);
2542
- if (!server) {
2543
- return fail(channelId, `server "${entry.serverId}" not found`);
2697
+ const outcome = await this.publish(conversationId, text, { channelId: locusChannelId, routed: true });
2698
+ const channelId = outcome.destination?.channelId ?? locusChannelId;
2699
+ if (outcome.status !== 'delivered') {
2700
+ return fail(channelId, outcome.reason ?? 'delivery not confirmed', outcome);
2544
2701
  }
2545
- // §14.1: channels/publish requires channels.publish in the grant. The
2546
- // host not sending is the enforcement — a send to an ungranted server
2547
- // would have it act on authority it was never told it has.
2548
- if (!CapabilityGrant.of(server).has('channels.publish')) {
2549
- return fail(channelId, `channels.publish not in "${entry.serverId}"'s effective grant (§14.1)`);
2550
- }
2551
- const publishParams = {
2552
- conversationId,
2553
- channelId,
2554
- content: [{ type: 'text', text }],
2555
- };
2556
- const result = await server.sendChannelsPublish(publishParams);
2557
- const delivered = result?.delivered ?? true;
2558
- // Surface the posted message's id (ChannelsPublishResult.messageId) so
2559
- // trace consumers can act on the just-posted message — e.g. a TTS-relay
2560
- // tap editing it down to the words actually voiced on interruption.
2561
- // Previously this was silently dropped here.
2562
- const messageId = result?.messageId;
2563
- // The server accepted the publish RPC but reported the message was not
2564
- // actually delivered (e.g. missing Send Messages permission). Previously
2565
- // this returned `{ delivered: true }`, masking the failure. Surface it.
2566
- if (delivered === false) {
2567
- return fail(channelId, `server "${entry.serverId}" reported delivered:false for "${channelId}"`);
2568
- }
2569
- console.error(`[routeSpeech] ${conversationId}: routed ${text.length} chars -> ${logValue(channelId)} (server=${entry.serverId}, delivered=${delivered})`);
2702
+ console.error(`[routeSpeech] ${conversationId}: routed ${text.length} chars -> ${logValue(channelId)} (server=${outcome.destination.serverId}, delivered=true)`);
2570
2703
  this.emitTraceFn({
2571
2704
  type: 'mcpl:speech-routed',
2572
2705
  conversationId,
2573
- serverId: entry.serverId,
2706
+ serverId: outcome.destination.serverId,
2574
2707
  channelId,
2575
- delivered,
2708
+ delivered: true,
2576
2709
  textLen: text.length,
2577
2710
  text,
2578
- ...(messageId !== undefined ? { messageId } : {}),
2711
+ // Surface the posted message's id (ChannelsPublishResult.messageId) so
2712
+ // trace consumers can act on the just-posted message — e.g. a TTS-relay
2713
+ // tap editing it down to the words actually voiced on interruption.
2714
+ ...(outcome.messageId !== undefined ? { messageId: outcome.messageId } : {}),
2579
2715
  });
2580
- return { delivered, channelId, ...(messageId !== undefined ? { messageId } : {}) };
2716
+ return outcome;
2717
+ }
2718
+ /** deliverSpeech, reduced to the confirmed delivery (null when there was none). */
2719
+ async routeSpeech(conversationId, text, locusChannelId) {
2720
+ const outcome = await this.deliverSpeech(conversationId, text, locusChannelId);
2721
+ if (outcome.status !== 'delivered')
2722
+ return null;
2723
+ return {
2724
+ delivered: true,
2725
+ channelId: outcome.destination.channelId,
2726
+ ...(outcome.messageId !== undefined ? { messageId: outcome.messageId } : {}),
2727
+ };
2581
2728
  }
2582
2729
  async handleToolPublish(input) {
2583
2730
  // Resolve content: accept both `content` and `text` (backward compat)
@@ -2614,32 +2761,46 @@ export class ChannelRegistry {
2614
2761
  isError: true,
2615
2762
  };
2616
2763
  }
2617
- try {
2618
- if (!CapabilityGrant.of(server).has('channels.publish')) {
2619
- return {
2620
- success: false,
2621
- error: `channels.publish not in "${server.id}"'s effective grant (§14.1)`,
2622
- isError: true,
2623
- };
2624
- }
2625
- const publishParams = {
2626
- conversationId: '', // Framework will fill this when wired
2627
- channelId,
2628
- content: [{ type: 'text', text: messageText }],
2629
- };
2630
- const result = await server.sendChannelsPublish(publishParams);
2631
- return {
2632
- success: true,
2633
- data: result ?? { delivered: true },
2634
- };
2635
- }
2636
- catch (err) {
2764
+ if (!CapabilityGrant.of(server).has('channels.publish')) {
2637
2765
  return {
2638
2766
  success: false,
2639
- error: `Failed to publish to channel: ${err.message}`,
2767
+ error: `channels.publish not in "${server.id}"'s effective grant (§14.1)`,
2640
2768
  isError: true,
2641
2769
  };
2642
2770
  }
2771
+ const publishParams = {
2772
+ conversationId: '', // Framework will fill this when wired
2773
+ channelId,
2774
+ content: [{ type: 'text', text: messageText }],
2775
+ };
2776
+ const destination = {
2777
+ serverId: entry.serverId,
2778
+ channelId: entry.descriptor.id,
2779
+ ...(entry.descriptor.label ? { label: entry.descriptor.label } : {}),
2780
+ };
2781
+ // The answer counts by the same rule as plain speech's: only the
2782
+ // connector's delivered:true confirms a post.
2783
+ let result;
2784
+ let outcome;
2785
+ try {
2786
+ result = await server.sendChannelsPublish(publishParams);
2787
+ outcome = publishReceiptOutcome(result, destination, Date.now());
2788
+ }
2789
+ catch (err) {
2790
+ outcome = publishErrorOutcome(err, destination, Date.now());
2791
+ }
2792
+ if (outcome.status === 'delivered')
2793
+ return { success: true, data: result };
2794
+ // The connector's data may say what a multi-part send already posted.
2795
+ const detail = outcome.status === 'unknown' && outcome.detail !== undefined ? ` Connector detail: ${connectorText(outcome.detail)}` : '';
2796
+ return {
2797
+ success: false,
2798
+ error: (outcome.status === 'failed'
2799
+ ? `Publish to ${channelId} failed: ${outcome.reason}. Nothing was posted.`
2800
+ : `Publish to ${channelId} wasn't confirmed: ${outcome.reason}. ` +
2801
+ 'It may or may not have been posted, so sending it again could post it twice.') + detail,
2802
+ isError: true,
2803
+ };
2643
2804
  }
2644
2805
  }
2645
2806
  //# sourceMappingURL=channel-registry.js.map