@animalabs/agent-framework 0.32.0 → 0.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (368) hide show
  1. package/README.md +340 -22
  2. package/dist/src/admission/admit.d.ts +18 -0
  3. package/dist/src/admission/admit.d.ts.map +1 -1
  4. package/dist/src/admission/admit.js +16 -3
  5. package/dist/src/admission/admit.js.map +1 -1
  6. package/dist/src/agent.d.ts +208 -80
  7. package/dist/src/agent.d.ts.map +1 -1
  8. package/dist/src/agent.js +345 -113
  9. package/dist/src/agent.js.map +1 -1
  10. package/dist/src/api/mcp-server-core.d.ts.map +1 -1
  11. package/dist/src/api/mcp-server-core.js +50 -12
  12. package/dist/src/api/mcp-server-core.js.map +1 -1
  13. package/dist/src/api/server.d.ts.map +1 -1
  14. package/dist/src/api/server.js +4 -20
  15. package/dist/src/api/server.js.map +1 -1
  16. package/dist/src/append-all.d.ts +5 -0
  17. package/dist/src/append-all.d.ts.map +1 -0
  18. package/dist/src/append-all.js +8 -0
  19. package/dist/src/append-all.js.map +1 -0
  20. package/dist/src/code-execution/isolate/scripts.d.ts +12 -8
  21. package/dist/src/code-execution/isolate/scripts.d.ts.map +1 -1
  22. package/dist/src/code-execution/isolate/scripts.js +24 -0
  23. package/dist/src/code-execution/isolate/scripts.js.map +1 -1
  24. package/dist/src/config-checks.d.ts +7 -0
  25. package/dist/src/config-checks.d.ts.map +1 -1
  26. package/dist/src/config-checks.js +14 -0
  27. package/dist/src/config-checks.js.map +1 -1
  28. package/dist/src/context-manager-errors.d.ts +25 -0
  29. package/dist/src/context-manager-errors.d.ts.map +1 -0
  30. package/dist/src/context-manager-errors.js +31 -0
  31. package/dist/src/context-manager-errors.js.map +1 -0
  32. package/dist/src/context-options.d.ts +70 -0
  33. package/dist/src/context-options.d.ts.map +1 -0
  34. package/dist/src/context-options.js +90 -0
  35. package/dist/src/context-options.js.map +1 -0
  36. package/dist/src/cut-off-round.js +4 -4
  37. package/dist/src/deferred-import.d.ts +93 -0
  38. package/dist/src/deferred-import.d.ts.map +1 -0
  39. package/dist/src/deferred-import.js +177 -0
  40. package/dist/src/deferred-import.js.map +1 -0
  41. package/dist/src/dendrite/audience.d.ts +223 -0
  42. package/dist/src/dendrite/audience.d.ts.map +1 -0
  43. package/dist/src/dendrite/audience.js +202 -0
  44. package/dist/src/dendrite/audience.js.map +1 -0
  45. package/dist/src/dendrite/index.d.ts +5 -3
  46. package/dist/src/dendrite/index.d.ts.map +1 -1
  47. package/dist/src/dendrite/index.js +2 -1
  48. package/dist/src/dendrite/index.js.map +1 -1
  49. package/dist/src/dendrite/presets.d.ts +10 -5
  50. package/dist/src/dendrite/presets.d.ts.map +1 -1
  51. package/dist/src/dendrite/presets.js +17 -5
  52. package/dist/src/dendrite/presets.js.map +1 -1
  53. package/dist/src/dendrite/registry.d.ts +62 -7
  54. package/dist/src/dendrite/registry.d.ts.map +1 -1
  55. package/dist/src/dendrite/registry.js +183 -12
  56. package/dist/src/dendrite/registry.js.map +1 -1
  57. package/dist/src/dendrite/types.d.ts +91 -8
  58. package/dist/src/dendrite/types.d.ts.map +1 -1
  59. package/dist/src/failure-text.d.ts +36 -0
  60. package/dist/src/failure-text.d.ts.map +1 -0
  61. package/dist/src/failure-text.js +89 -0
  62. package/dist/src/failure-text.js.map +1 -0
  63. package/dist/src/foreign-rounds.d.ts +69 -0
  64. package/dist/src/foreign-rounds.d.ts.map +1 -0
  65. package/dist/src/foreign-rounds.js +152 -0
  66. package/dist/src/foreign-rounds.js.map +1 -0
  67. package/dist/src/framework.d.ts +2064 -842
  68. package/dist/src/framework.d.ts.map +1 -1
  69. package/dist/src/framework.js +8586 -3739
  70. package/dist/src/framework.js.map +1 -1
  71. package/dist/src/gate/event-gate.d.ts +125 -21
  72. package/dist/src/gate/event-gate.d.ts.map +1 -1
  73. package/dist/src/gate/event-gate.js +487 -72
  74. package/dist/src/gate/event-gate.js.map +1 -1
  75. package/dist/src/gate/index.d.ts +1 -1
  76. package/dist/src/gate/index.d.ts.map +1 -1
  77. package/dist/src/gate/index.js.map +1 -1
  78. package/dist/src/gate/reply-judge.d.ts +4 -0
  79. package/dist/src/gate/reply-judge.d.ts.map +1 -1
  80. package/dist/src/gate/reply-judge.js +12 -3
  81. package/dist/src/gate/reply-judge.js.map +1 -1
  82. package/dist/src/gate/rule-scope.d.ts +30 -0
  83. package/dist/src/gate/rule-scope.d.ts.map +1 -0
  84. package/dist/src/gate/rule-scope.js +41 -0
  85. package/dist/src/gate/rule-scope.js.map +1 -0
  86. package/dist/src/gate/suppress-script-worker.d.ts +2 -0
  87. package/dist/src/gate/suppress-script-worker.d.ts.map +1 -0
  88. package/dist/src/gate/suppress-script-worker.js +103 -0
  89. package/dist/src/gate/suppress-script-worker.js.map +1 -0
  90. package/dist/src/gate/suppress-scripts.d.ts +105 -0
  91. package/dist/src/gate/suppress-scripts.d.ts.map +1 -0
  92. package/dist/src/gate/suppress-scripts.js +403 -0
  93. package/dist/src/gate/suppress-scripts.js.map +1 -0
  94. package/dist/src/gate/suppression-review.d.ts +143 -0
  95. package/dist/src/gate/suppression-review.d.ts.map +1 -0
  96. package/dist/src/gate/suppression-review.js +463 -0
  97. package/dist/src/gate/suppression-review.js.map +1 -0
  98. package/dist/src/gate/suppression-stats.d.ts +125 -0
  99. package/dist/src/gate/suppression-stats.d.ts.map +1 -0
  100. package/dist/src/gate/suppression-stats.js +214 -0
  101. package/dist/src/gate/suppression-stats.js.map +1 -0
  102. package/dist/src/gate/types.d.ts +142 -7
  103. package/dist/src/gate/types.d.ts.map +1 -1
  104. package/dist/src/gate/wake-onboarding.d.ts +119 -0
  105. package/dist/src/gate/wake-onboarding.d.ts.map +1 -0
  106. package/dist/src/gate/wake-onboarding.js +277 -0
  107. package/dist/src/gate/wake-onboarding.js.map +1 -0
  108. package/dist/src/heartbeat/heartbeat.js +1 -1
  109. package/dist/src/heartbeat/heartbeat.js.map +1 -1
  110. package/dist/src/held-writes.d.ts +31 -23
  111. package/dist/src/held-writes.d.ts.map +1 -1
  112. package/dist/src/held-writes.js +44 -59
  113. package/dist/src/held-writes.js.map +1 -1
  114. package/dist/src/index.d.ts +6 -2
  115. package/dist/src/index.d.ts.map +1 -1
  116. package/dist/src/index.js +4 -0
  117. package/dist/src/index.js.map +1 -1
  118. package/dist/src/inference-bounds.d.ts +2 -1
  119. package/dist/src/inference-bounds.d.ts.map +1 -1
  120. package/dist/src/inference-bounds.js +9 -6
  121. package/dist/src/inference-bounds.js.map +1 -1
  122. package/dist/src/jsonrpc-envelope.d.ts +69 -0
  123. package/dist/src/jsonrpc-envelope.d.ts.map +1 -0
  124. package/dist/src/jsonrpc-envelope.js +66 -0
  125. package/dist/src/jsonrpc-envelope.js.map +1 -0
  126. package/dist/src/mcpl/channel-registry.d.ts +188 -28
  127. package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
  128. package/dist/src/mcpl/channel-registry.js +426 -70
  129. package/dist/src/mcpl/channel-registry.js.map +1 -1
  130. package/dist/src/mcpl/checkpoint-manager.d.ts +2 -4
  131. package/dist/src/mcpl/checkpoint-manager.d.ts.map +1 -1
  132. package/dist/src/mcpl/checkpoint-manager.js.map +1 -1
  133. package/dist/src/mcpl/feature-set-manager.d.ts +2 -4
  134. package/dist/src/mcpl/feature-set-manager.d.ts.map +1 -1
  135. package/dist/src/mcpl/feature-set-manager.js.map +1 -1
  136. package/dist/src/mcpl/inbound-source.d.ts +2 -1
  137. package/dist/src/mcpl/inbound-source.d.ts.map +1 -1
  138. package/dist/src/mcpl/inbound-source.js +2 -1
  139. package/dist/src/mcpl/inbound-source.js.map +1 -1
  140. package/dist/src/mcpl/inference-router.d.ts +6 -6
  141. package/dist/src/mcpl/inference-router.d.ts.map +1 -1
  142. package/dist/src/mcpl/inference-router.js.map +1 -1
  143. package/dist/src/mcpl/modern-connection.d.ts +109 -15
  144. package/dist/src/mcpl/modern-connection.d.ts.map +1 -1
  145. package/dist/src/mcpl/modern-connection.js +593 -86
  146. package/dist/src/mcpl/modern-connection.js.map +1 -1
  147. package/dist/src/mcpl/protocol-family.d.ts +3 -1
  148. package/dist/src/mcpl/protocol-family.d.ts.map +1 -1
  149. package/dist/src/mcpl/protocol-family.js +15 -9
  150. package/dist/src/mcpl/protocol-family.js.map +1 -1
  151. package/dist/src/mcpl/push-coalescer.d.ts +132 -22
  152. package/dist/src/mcpl/push-coalescer.d.ts.map +1 -1
  153. package/dist/src/mcpl/push-coalescer.js +105 -15
  154. package/dist/src/mcpl/push-coalescer.js.map +1 -1
  155. package/dist/src/mcpl/push-handler.d.ts +9 -7
  156. package/dist/src/mcpl/push-handler.d.ts.map +1 -1
  157. package/dist/src/mcpl/push-handler.js.map +1 -1
  158. package/dist/src/mcpl/server-connection.d.ts +50 -28
  159. package/dist/src/mcpl/server-connection.d.ts.map +1 -1
  160. package/dist/src/mcpl/server-connection.js +165 -72
  161. package/dist/src/mcpl/server-connection.js.map +1 -1
  162. package/dist/src/mcpl/tool-classes.d.ts.map +1 -1
  163. package/dist/src/mcpl/tool-classes.js +3 -0
  164. package/dist/src/mcpl/tool-classes.js.map +1 -1
  165. package/dist/src/mcpl/tool-presence.d.ts.map +1 -1
  166. package/dist/src/mcpl/tool-presence.js +10 -6
  167. package/dist/src/mcpl/tool-presence.js.map +1 -1
  168. package/dist/src/mcpl/toolset-host.d.ts.map +1 -1
  169. package/dist/src/mcpl/toolset-host.js +7 -6
  170. package/dist/src/mcpl/toolset-host.js.map +1 -1
  171. package/dist/src/mcpl/toolsets-module.d.ts.map +1 -1
  172. package/dist/src/mcpl/toolsets-module.js +2 -1
  173. package/dist/src/mcpl/toolsets-module.js.map +1 -1
  174. package/dist/src/mcpl/types.d.ts +33 -6
  175. package/dist/src/mcpl/types.d.ts.map +1 -1
  176. package/dist/src/mcpl/types.js.map +1 -1
  177. package/dist/src/module-registry.d.ts +24 -1
  178. package/dist/src/module-registry.d.ts.map +1 -1
  179. package/dist/src/module-registry.js +68 -18
  180. package/dist/src/module-registry.js.map +1 -1
  181. package/dist/src/modules/discord/index.d.ts +45 -8
  182. package/dist/src/modules/discord/index.d.ts.map +1 -1
  183. package/dist/src/modules/discord/index.js +238 -87
  184. package/dist/src/modules/discord/index.js.map +1 -1
  185. package/dist/src/modules/health/index.js +2 -2
  186. package/dist/src/modules/health/index.js.map +1 -1
  187. package/dist/src/modules/history/index.d.ts +59 -0
  188. package/dist/src/modules/history/index.d.ts.map +1 -1
  189. package/dist/src/modules/history/index.js +432 -67
  190. package/dist/src/modules/history/index.js.map +1 -1
  191. package/dist/src/modules/history/semantic.d.ts +6 -5
  192. package/dist/src/modules/history/semantic.d.ts.map +1 -1
  193. package/dist/src/modules/history/semantic.js +18 -25
  194. package/dist/src/modules/history/semantic.js.map +1 -1
  195. package/dist/src/modules/workspace/disk-agreement.d.ts +1 -1
  196. package/dist/src/modules/workspace/disk-agreement.js +1 -1
  197. package/dist/src/modules/workspace/index.d.ts +28 -7
  198. package/dist/src/modules/workspace/index.d.ts.map +1 -1
  199. package/dist/src/modules/workspace/index.js +80 -25
  200. package/dist/src/modules/workspace/index.js.map +1 -1
  201. package/dist/src/modules/workspace/observe.d.ts.map +1 -1
  202. package/dist/src/modules/workspace/observe.js +2 -1
  203. package/dist/src/modules/workspace/observe.js.map +1 -1
  204. package/dist/src/modules/workspace/reconcile.d.ts.map +1 -1
  205. package/dist/src/modules/workspace/reconcile.js +3 -2
  206. package/dist/src/modules/workspace/reconcile.js.map +1 -1
  207. package/dist/src/notice-tags.d.ts +20 -9
  208. package/dist/src/notice-tags.d.ts.map +1 -1
  209. package/dist/src/notice-tags.js +20 -9
  210. package/dist/src/notice-tags.js.map +1 -1
  211. package/dist/src/operator-log.d.ts +36 -3
  212. package/dist/src/operator-log.d.ts.map +1 -1
  213. package/dist/src/operator-log.js +2 -2
  214. package/dist/src/operator-log.js.map +1 -1
  215. package/dist/src/presentation.d.ts +747 -0
  216. package/dist/src/presentation.d.ts.map +1 -0
  217. package/dist/src/presentation.js +1437 -0
  218. package/dist/src/presentation.js.map +1 -0
  219. package/dist/src/prose-drafts.d.ts +15 -11
  220. package/dist/src/prose-drafts.d.ts.map +1 -1
  221. package/dist/src/prose-drafts.js +16 -12
  222. package/dist/src/prose-drafts.js.map +1 -1
  223. package/dist/src/read-marks.d.ts +192 -0
  224. package/dist/src/read-marks.d.ts.map +1 -0
  225. package/dist/src/read-marks.js +242 -0
  226. package/dist/src/read-marks.js.map +1 -0
  227. package/dist/src/reasoning-loss.d.ts +5 -0
  228. package/dist/src/reasoning-loss.d.ts.map +1 -0
  229. package/dist/src/reasoning-loss.js +8 -0
  230. package/dist/src/reasoning-loss.js.map +1 -0
  231. package/dist/src/recovery/offline-branch.d.ts +91 -6
  232. package/dist/src/recovery/offline-branch.d.ts.map +1 -1
  233. package/dist/src/recovery/offline-branch.js +277 -32
  234. package/dist/src/recovery/offline-branch.js.map +1 -1
  235. package/dist/src/recovery/recover-cli.js +24 -4
  236. package/dist/src/recovery/recover-cli.js.map +1 -1
  237. package/dist/src/send-tools.d.ts +5 -9
  238. package/dist/src/send-tools.d.ts.map +1 -1
  239. package/dist/src/send-tools.js +40 -7
  240. package/dist/src/send-tools.js.map +1 -1
  241. package/dist/src/sent-rows.js +1 -1
  242. package/dist/src/stored-injections.d.ts +2 -2
  243. package/dist/src/stored-injections.js +2 -2
  244. package/dist/src/stored-removal.d.ts +17 -4
  245. package/dist/src/stored-removal.d.ts.map +1 -1
  246. package/dist/src/stored-removal.js +29 -5
  247. package/dist/src/stored-removal.js.map +1 -1
  248. package/dist/src/supplied-text.d.ts +1 -1
  249. package/dist/src/supplied-text.js +3 -3
  250. package/dist/src/supplied-text.js.map +1 -1
  251. package/dist/src/thinking-drops.d.ts +2 -0
  252. package/dist/src/thinking-drops.d.ts.map +1 -1
  253. package/dist/src/thinking-drops.js.map +1 -1
  254. package/dist/src/tool-presentation.d.ts.map +1 -1
  255. package/dist/src/tool-presentation.js +38 -9
  256. package/dist/src/tool-presentation.js.map +1 -1
  257. package/dist/src/tool-result-guard.d.ts +12 -1
  258. package/dist/src/tool-result-guard.d.ts.map +1 -1
  259. package/dist/src/tool-result-guard.js +42 -8
  260. package/dist/src/tool-result-guard.js.map +1 -1
  261. package/dist/src/tune-out/coordinator.d.ts +1170 -81
  262. package/dist/src/tune-out/coordinator.d.ts.map +1 -1
  263. package/dist/src/tune-out/coordinator.js +3732 -369
  264. package/dist/src/tune-out/coordinator.js.map +1 -1
  265. package/dist/src/tune-out/tools.d.ts +114 -17
  266. package/dist/src/tune-out/tools.d.ts.map +1 -1
  267. package/dist/src/tune-out/tools.js +89 -28
  268. package/dist/src/tune-out/tools.js.map +1 -1
  269. package/dist/src/tune-out/window-anchor.d.ts +143 -0
  270. package/dist/src/tune-out/window-anchor.d.ts.map +1 -0
  271. package/dist/src/tune-out/window-anchor.js +202 -0
  272. package/dist/src/tune-out/window-anchor.js.map +1 -0
  273. package/dist/src/types/agent.d.ts +121 -25
  274. package/dist/src/types/agent.d.ts.map +1 -1
  275. package/dist/src/types/events.d.ts +2 -0
  276. package/dist/src/types/events.d.ts.map +1 -1
  277. package/dist/src/types/framework.d.ts +72 -17
  278. package/dist/src/types/framework.d.ts.map +1 -1
  279. package/dist/src/types/inference-log.d.ts +1 -0
  280. package/dist/src/types/inference-log.d.ts.map +1 -1
  281. package/dist/src/types/module.d.ts +180 -69
  282. package/dist/src/types/module.d.ts.map +1 -1
  283. package/dist/src/types/trace.d.ts +573 -39
  284. package/dist/src/types/trace.d.ts.map +1 -1
  285. package/package.json +4 -4
  286. package/src/admission/admit.ts +32 -3
  287. package/src/agent.ts +392 -132
  288. package/src/api/mcp-server-core.ts +54 -17
  289. package/src/api/server.ts +4 -23
  290. package/src/append-all.ts +6 -0
  291. package/src/code-execution/isolate/scripts.ts +28 -3
  292. package/src/config-checks.ts +14 -0
  293. package/src/context-manager-errors.ts +37 -0
  294. package/src/context-options.ts +106 -0
  295. package/src/cut-off-round.ts +4 -4
  296. package/src/deferred-import.ts +239 -0
  297. package/src/dendrite/audience.ts +315 -0
  298. package/src/dendrite/index.ts +14 -2
  299. package/src/dendrite/presets.ts +18 -6
  300. package/src/dendrite/registry.ts +213 -14
  301. package/src/dendrite/types.ts +92 -8
  302. package/src/failure-text.ts +88 -0
  303. package/src/foreign-rounds.ts +199 -0
  304. package/src/framework.ts +8796 -3813
  305. package/src/gate/event-gate.ts +518 -91
  306. package/src/gate/index.ts +3 -0
  307. package/src/gate/reply-judge.ts +12 -3
  308. package/src/gate/rule-scope.ts +45 -0
  309. package/src/gate/suppress-script-worker.ts +89 -0
  310. package/src/gate/suppress-scripts.ts +414 -0
  311. package/src/gate/suppression-review.ts +517 -0
  312. package/src/gate/suppression-stats.ts +314 -0
  313. package/src/gate/types.ts +148 -7
  314. package/src/gate/wake-onboarding.ts +309 -0
  315. package/src/heartbeat/heartbeat.ts +1 -1
  316. package/src/held-writes.ts +49 -60
  317. package/src/index.ts +10 -2
  318. package/src/inference-bounds.ts +11 -6
  319. package/src/jsonrpc-envelope.ts +81 -0
  320. package/src/mcpl/channel-registry.ts +513 -116
  321. package/src/mcpl/checkpoint-manager.ts +3 -2
  322. package/src/mcpl/feature-set-manager.ts +2 -1
  323. package/src/mcpl/inbound-source.ts +2 -1
  324. package/src/mcpl/inference-router.ts +7 -4
  325. package/src/mcpl/modern-connection.ts +629 -91
  326. package/src/mcpl/protocol-family.ts +15 -9
  327. package/src/mcpl/push-coalescer.ts +193 -34
  328. package/src/mcpl/push-handler.ts +10 -5
  329. package/src/mcpl/server-connection.ts +169 -75
  330. package/src/mcpl/tool-classes.ts +3 -0
  331. package/src/mcpl/tool-presence.ts +10 -5
  332. package/src/mcpl/toolset-host.ts +7 -6
  333. package/src/mcpl/toolsets-module.ts +2 -1
  334. package/src/mcpl/types.ts +33 -6
  335. package/src/module-registry.ts +73 -17
  336. package/src/modules/discord/index.ts +230 -82
  337. package/src/modules/health/index.ts +2 -2
  338. package/src/modules/history/index.ts +439 -70
  339. package/src/modules/history/semantic.ts +18 -24
  340. package/src/modules/workspace/disk-agreement.ts +1 -1
  341. package/src/modules/workspace/index.ts +89 -26
  342. package/src/modules/workspace/observe.ts +2 -1
  343. package/src/modules/workspace/reconcile.ts +3 -2
  344. package/src/notice-tags.ts +21 -9
  345. package/src/operator-log.ts +36 -3
  346. package/src/presentation.ts +1678 -0
  347. package/src/prose-drafts.ts +16 -12
  348. package/src/read-marks.ts +328 -0
  349. package/src/reasoning-loss.ts +7 -0
  350. package/src/recovery/offline-branch.ts +350 -35
  351. package/src/recovery/recover-cli.ts +23 -4
  352. package/src/send-tools.ts +40 -7
  353. package/src/sent-rows.ts +1 -1
  354. package/src/stored-injections.ts +2 -2
  355. package/src/stored-removal.ts +31 -7
  356. package/src/supplied-text.ts +3 -3
  357. package/src/thinking-drops.ts +2 -0
  358. package/src/tool-presentation.ts +34 -9
  359. package/src/tool-result-guard.ts +41 -7
  360. package/src/tune-out/coordinator.ts +4121 -472
  361. package/src/tune-out/tools.ts +162 -44
  362. package/src/tune-out/window-anchor.ts +277 -0
  363. package/src/types/agent.ts +122 -25
  364. package/src/types/events.ts +2 -0
  365. package/src/types/framework.ts +73 -17
  366. package/src/types/inference-log.ts +1 -0
  367. package/src/types/module.ts +181 -68
  368. package/src/types/trace.ts +607 -43
@@ -15,14 +15,14 @@
15
15
  * its creation time is the only monotonic signal). Both watermarks are
16
16
  * kept in the module's state, which follows the store's branches, so each
17
17
  * branch sends its own messages and summaries. A branch made at an earlier
18
- * point, as an undo makes one, mints summary ids its parent already used,
19
- * so a summary is keyed `sum:<id>@<created>`.
18
+ * point, as a rollback makes one, mints summary ids its parent already
19
+ * used, so a summary is keyed `sum:<id>@<created>`.
20
20
  *
21
21
  * What gets embedded per message: text blocks verbatim, plus the string
22
22
  * arguments of the agent's private-prose tools (think / journal / skip_reply
23
23
  * / private_note) labelled `[think] …` — that is the resident's own diary and
24
- * is exactly what "what did I think about X" should find. The message
25
- * argument of the send tools and edit_message, labelled by tool, such as
24
+ * is exactly what "what did I think about X" should find. The words of a
25
+ * speech tool's call (send-tools.ts), labelled by tool, such as
26
26
  * `[send_message] …`, since with prose routing disabled the resident speaks
27
27
  * through them.
28
28
  * tool_result payloads, other tool arguments, thinking blocks and media are
@@ -35,7 +35,7 @@
35
35
  import type { ContextManager, StoredMessage } from '@animalabs/context-manager';
36
36
  import type { ContentBlock } from '@animalabs/membrane';
37
37
  import { safeSlice } from '../../safe-slice.js';
38
- import { SEND_TOOLS, bareToolName } from '../../send-tools.js';
38
+ import { speechOf } from '../../send-tools.js';
39
39
  import { storedInjectionMarkOf } from '../../stored-injections.js';
40
40
 
41
41
  export interface SemanticIndexConfig {
@@ -137,12 +137,6 @@ export interface SearchResponse {
137
137
  }
138
138
 
139
139
  const PRIVATE_PROSE_TOOLS = new Set(['think', 'journal', 'skip_reply', 'private_note']);
140
- /**
141
- * Tools whose message argument is what the resident said: the send tools,
142
- * and edit_message, whose argument is the new text of a message it sent.
143
- * With prose routing disabled the resident speaks through these.
144
- */
145
- const SPEECH_TOOLS = new Set([...SEND_TOOLS, 'edit_message']);
146
140
 
147
141
  /**
148
142
  * The semantic index service's failure, said of the service alone: it didn't
@@ -302,8 +296,10 @@ function isHit(hit: unknown): boolean {
302
296
  return isObject(hit) && typeof (hit as { id?: unknown }).id === 'string';
303
297
  }
304
298
 
299
+ export const ERROR_MARK = ', error';
300
+
305
301
  /** Text to embed for one message, or '' when there is nothing worth indexing. */
306
- export function messageIndexText(msg: StoredMessage, includePrivateTools = true): string {
302
+ export function messageIndexText(msg: StoredMessage, includePrivateTools = true, failed: ReadonlySet<string> = new Set()): string {
307
303
  const parts: string[] = [];
308
304
  for (const block of msg.content as ContentBlock[]) {
309
305
  if (block.type === 'text' && typeof block.text === 'string') {
@@ -313,12 +309,9 @@ export function messageIndexText(msg: StoredMessage, includePrivateTools = true)
313
309
  for (const v of Object.values(input)) {
314
310
  if (typeof v === 'string' && v.trim().length > 0) parts.push(`[${block.name}] ${v}`);
315
311
  }
316
- } else if (block.type === 'tool_use' && SPEECH_TOOLS.has(bareToolName(block.name))) {
317
- // Only the message: the other arguments are ids, topics and names.
318
- // channel_publish still takes `text` from older callers.
319
- const input = (block as { input?: { content?: unknown; text?: unknown } }).input ?? {};
320
- const v = input.content ?? input.text;
321
- if (typeof v === 'string' && v.trim().length > 0) parts.push(`[${bareToolName(block.name)}] ${v}`);
312
+ } else if (block.type === 'tool_use') {
313
+ const said = speechOf(block.name, (block as { input?: unknown }).input);
314
+ if (said) parts.push(`[${said.tool}${failed.has(block.id) ? ERROR_MARK : ''}] ${said.words}`);
322
315
  }
323
316
  }
324
317
  return parts.join('\n').trim();
@@ -705,9 +698,10 @@ export class SemanticIndexer {
705
698
  if (budget <= 0) break;
706
699
  this.editedIds.delete(id);
707
700
  const m = this.cm.getMessage(id as never);
708
- // Not on the current branch (e.g. /undo after the edit): drop it,
709
- // never delete — /redo brings the message back and the time walk
710
- // will not revisit it. Search-time branch checks hide it meanwhile.
701
+ // Not on the current branch (e.g. a rollback after the edit): drop
702
+ // it, never delete — a switch back to the branch that holds it
703
+ // brings the message back and the time walk will not revisit it.
704
+ // Search-time branch checks hide it meanwhile.
711
705
  if (!m) continue;
712
706
  edited.push(id); budget--;
713
707
  const item = messageToItem(m, this.cfg);
@@ -886,14 +880,14 @@ export class SemanticIndexer {
886
880
  // The current branch may then have items this pass didn't send, and
887
881
  // old items a failed delete left are still to go.
888
882
  if (left || oldItemsOwed) report.more = true;
889
- this.consecutiveFailures = 0; this.lastError = named(notStats?.message ?? null, ...phaseErrors); this.lastSyncAt = Date.now();
883
+ this.consecutiveFailures = 0; this.lastError = named([notStats?.message ?? null, ...phaseErrors]); this.lastSyncAt = Date.now();
890
884
  return report;
891
885
  } catch (e) {
892
886
  this.consecutiveFailures++;
893
887
  const delay = Math.min(15 * 60_000, 5_000 * 2 ** Math.min(8, this.consecutiveFailures - 1));
894
888
  this.backoffUntil = Date.now() + delay;
895
889
  const failure = e instanceof Error ? e.message : String(e);
896
- this.lastError = named(failure, notStats?.message ?? null, ...phaseErrors);
890
+ this.lastError = named([failure, notStats?.message ?? null, ...phaseErrors]);
897
891
  this.warn(`sync failed (${this.consecutiveFailures}×, retry in ${Math.round(delay / 1000)}s): ${failure}`);
898
892
  report.more = true;
899
893
  return report;
@@ -902,6 +896,6 @@ export class SemanticIndexer {
902
896
  }
903
897
 
904
898
  /** Each failure a sync pass met, once, in the order given, for its lastError: null if none. */
905
- function named(...failures: (string | null)[]): string | null {
899
+ function named(failures: (string | null)[]): string | null {
906
900
  return [...new Set(failures.filter((f): f is string => f !== null))].join('; ') || null;
907
901
  }
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * P describes disk, and disk does not rewind with a branch switch, so P lives
7
7
  * in global chronicle records (RecordJournal) rather than branch state: after
8
- * an undo selects an older tree, P still says what disk holds, and a
8
+ * a rollback selects an older tree, P still says what disk holds, and a
9
9
  * difference reads as a store-side change, never as a disk edit. Branch-local
10
10
  * intent — tombstones, store origin, conflicts — lives in BranchIntents and
11
11
  * rewinds with the tree.
@@ -89,6 +89,7 @@ import {
89
89
  sameIdentity,
90
90
  stageContained,
91
91
  } from './direct-write.js';
92
+ import { appendAll } from '../../append-all.js';
92
93
 
93
94
  /** Default for how long the after-batch scan may hold the agent's next inference. */
94
95
  const AGENT_ACTION_SCAN_DEADLINE_MS = 20_000;
@@ -1052,6 +1053,12 @@ export class WorkspaceModule implements Module {
1052
1053
  /** Whether an agent's history holds a message, as the framework hands it over (useHistory). */
1053
1054
  private historyLookup: ((agentName: string, messageId: string) => boolean) | null = null;
1054
1055
 
1056
+ /** Whether an agent's window still holds what it did after a place in the record, as the framework hands it over (useWindow). */
1057
+ private windowLookup: ((agentName: string, afterSequence: number) => boolean) | null = null;
1058
+
1059
+ /** Whether a turn of an agent's is alive now, as the framework hands it over with the window lookup (useWindow). */
1060
+ private turnLookup: ((agentName: string) => boolean) | null = null;
1061
+
1055
1062
  constructor(config: WorkspaceConfig) {
1056
1063
  for (const mount of config.mounts) {
1057
1064
  const cap: unknown = mount.walkCap;
@@ -1228,8 +1235,13 @@ export class WorkspaceModule implements Module {
1228
1235
  carried.push(saved);
1229
1236
  continue;
1230
1237
  }
1238
+ // An entry an earlier release saved (no `v`) doesn't say whether a
1239
+ // turn made each write, and that release judged a position by the
1240
+ // branch alone: so is it judged here (outsideTurn), so its head
1241
+ // isn't taken for a later turn's.
1242
+ const fromEarlier = saved.v === undefined;
1231
1243
  restored.set(saved.mount, new Map(Object.entries(saved.agents).map(([agent, head]) =>
1232
- [agent, { branchId: head.branchId, after: head.after, notice: head.notice ?? null }])));
1244
+ [agent, { branchId: head.branchId, after: head.after, notice: head.notice ?? null, ...(head.outsideTurn || fromEarlier ? { outsideTurn: true as const } : {}) }])));
1233
1245
  }
1234
1246
  this.headsJournal = journal;
1235
1247
  this.loadedHeads = text;
@@ -1821,10 +1833,12 @@ export class WorkspaceModule implements Module {
1821
1833
  if (!this.headsJournal) return;
1822
1834
  const snapshot: DirectHeadsSnapshot = [
1823
1835
  ...this.carriedHeads,
1824
- ...[...this.directHeads].filter(([, heads]) => heads.size > 0).map(([name, heads]) => ({
1836
+ ...[...this.directHeads].filter(([, heads]) => heads.size > 0).map(([name, heads]): DirectHeadsEntry => ({
1825
1837
  mount: name,
1826
1838
  root: resolve(this.mounts.get(name)!.config.path),
1827
- agents: Object.fromEntries([...heads].map(([agent, { branchId, after, notice }]) => [agent, { branchId, after, ...(notice !== null ? { notice } : {}) }])),
1839
+ v: DIRECT_HEADS_VERSION,
1840
+ agents: Object.fromEntries([...heads].map(([agent, { branchId, after, notice, outsideTurn }]) =>
1841
+ [agent, { branchId, after, ...(notice !== null ? { notice } : {}), ...(outsideTurn ? { outsideTurn } : {}) }])),
1828
1842
  })),
1829
1843
  ];
1830
1844
  const text = canonicalHeads(snapshot);
@@ -4536,7 +4550,7 @@ export class WorkspaceModule implements Module {
4536
4550
  });
4537
4551
  continue;
4538
4552
  }
4539
- notes.push(...lookedIn);
4553
+ appendAll(notes, lookedIn);
4540
4554
  const plan = planTargetEdits(tool, target, stored.bytes, hints, maxSize, counts, problems);
4541
4555
  if (plan === null) continue;
4542
4556
  plans.push({
@@ -5088,7 +5102,10 @@ export class WorkspaceModule implements Module {
5088
5102
  * changed meanwhile, the head moved under the call, and P is set there,
5089
5103
  * so the next start judges the deletion by the branch its turn was on,
5090
5104
  * unless the history doesn't hold P already, whose notice is owed. A write no agent
5091
- * made tells no one. The store's reads here come after the write landed,
5105
+ * made tells no one. A write made while no turn of the agent's is alive (a
5106
+ * host's executeToolCall naming it) is marked so (`outsideTurn`): no round
5107
+ * of the agent's history made it, so the window can't say it was undone,
5108
+ * and only the branch's position decides. The store's reads here come after the write landed,
5092
5109
  * so one that throws is logged and P stays, as for a history that can't
5093
5110
  * be read, and the write still answers that it landed.
5094
5111
  */
@@ -5100,12 +5117,13 @@ export class WorkspaceModule implements Module {
5100
5117
  if (!heads) this.directHeads.set(mount.config.name, (heads = new Map()));
5101
5118
  const head = heads.get(agentName);
5102
5119
  const branchId = store.currentBranch().id;
5120
+ const outsideTurn = this.turnLookup?.(agentName) === false ? { outsideTurn: true as const } : {};
5103
5121
  if (since && since.branchId !== branchId) {
5104
- if (!head || this.historyHoldsWrites(agentName, head) === true) heads.set(agentName, { ...since, notice: null });
5122
+ if (!head || this.historyHoldsWrites(agentName, head) === true) heads.set(agentName, { ...since, notice: null, ...outsideTurn });
5105
5123
  return;
5106
5124
  }
5107
5125
  if (head && this.historyHoldsWrites(agentName, head) !== true) return;
5108
- heads.set(agentName, { branchId, after: store.currentSequence(), notice: null });
5126
+ heads.set(agentName, { branchId, after: store.currentSequence(), notice: null, ...outsideTurn });
5109
5127
  } catch (err) {
5110
5128
  console.error('[workspace] could not record a direct write\'s position:', err);
5111
5129
  }
@@ -5132,7 +5150,20 @@ export class WorkspaceModule implements Module {
5132
5150
  * leaves the next start to decide (headMoveNotice).
5133
5151
  */
5134
5152
  private historyHoldsWrites(agentName: string, head: DirectHead): boolean | null {
5135
- if (this.holdsPosition(head)) return true;
5153
+ if (this.holdsPosition(head)) {
5154
+ // The branch holds the write, but an undo on the agent's window (the
5155
+ // framework's presentation index) moves no branch: it takes the turn
5156
+ // that wrote out of the window, which the framework's lookup says. A
5157
+ // write made outside any turn of the agent's has no turn to take out.
5158
+ let held: boolean;
5159
+ try {
5160
+ held = head.outsideTurn === true || this.windowLookup?.(agentName, head.after) !== false;
5161
+ } catch (err) {
5162
+ console.error('[workspace] window lookup for the head-move notice failed:', err);
5163
+ return null;
5164
+ }
5165
+ if (held) return true;
5166
+ }
5136
5167
  if (head.notice === null) return false;
5137
5168
  try {
5138
5169
  return this.historyLookup?.(agentName, head.notice) === true;
@@ -5146,9 +5177,10 @@ export class WorkspaceModule implements Module {
5146
5177
  * Whether the store's current branch holds what came before a direct
5147
5178
  * write: it's the write's branch, or continues it with every fork point on
5148
5179
  * the way after `after`, the store's head when the write landed. A fork at
5149
- * exactly `after` doesn't: an undo forks at its turn's sequenceBefore,
5150
- * which is the head at the write when nothing was recorded in the turn
5151
- * before it. A missing branch or one without fork metadata holds nothing,
5180
+ * exactly `after` doesn't: a rollback cut there (to the row the write
5181
+ * followed) leaves the write out, as an undo's fork at its turn's
5182
+ * sequenceBefore did before #291 (an undo moves no branch since). A
5183
+ * missing branch or one without fork metadata holds nothing,
5152
5184
  * as for the materialize guard (isLinearContinuation).
5153
5185
  */
5154
5186
  private holdsPosition({ branchId, after }: DirectHead): boolean {
@@ -5201,14 +5233,31 @@ export class WorkspaceModule implements Module {
5201
5233
  }
5202
5234
 
5203
5235
  /**
5204
- * How the module asks whether an agent's history holds a message, as the
5205
- * framework judges its own notices (`cm.getMessage(id) !== null`): handed
5206
- * over once, when the module is added. Without it, no notice is held.
5236
+ * How the module asks whether an agent's history holds a message: its
5237
+ * record holds it, and, on a window the framework presents, no undo has
5238
+ * taken it out of the window. Handed over once, when the module is added.
5239
+ * Without it, no notice is held.
5207
5240
  */
5208
5241
  useHistory(lookup: (agentName: string, messageId: string) => boolean): void {
5209
5242
  this.historyLookup = lookup;
5210
5243
  }
5211
5244
 
5245
+ /**
5246
+ * How the module asks whether an agent's window still holds what the
5247
+ * agent did after a place in the record (`afterSequence`, the store's head
5248
+ * when it wrote a mount direct): false once an undo on its window took
5249
+ * that turn out, though the branch still holds the write. Handed over
5250
+ * once, by a framework with the presentation index. Without it, the
5251
+ * branch's position alone decides. `turnAlive` says whether a turn of the
5252
+ * agent's is alive at a write: one made outside any (a host's
5253
+ * executeToolCall naming the agent) has no turn in the window, so the
5254
+ * branch's position alone decides for it too.
5255
+ */
5256
+ useWindow(lookup: (agentName: string, afterSequence: number) => boolean, turnAlive?: (agentName: string) => boolean): void {
5257
+ this.windowLookup = lookup;
5258
+ this.turnLookup = turnAlive ?? null;
5259
+ }
5260
+
5212
5261
  private async handleDelete(input: DeleteInput, callerAgentName?: string): Promise<ToolResult> {
5213
5262
  const { mount, relativePath, path } = await this.parseFilePath(input.path).catch((error: unknown) => { throw notStored(error); });
5214
5263
  if (relativePath === '') return { success: false, error: didNothing('delete', namesRoot(input.path, mount.config.name)), isError: true };
@@ -5622,8 +5671,8 @@ export class WorkspaceModule implements Module {
5622
5671
  const found = mount.direct
5623
5672
  ? await this.textsFromDisk(mount, relativePath, root, start, kept, (text) => searched(text)())
5624
5673
  : await this.textsFromStore(mount, relativePath, start, kept, searched);
5625
- skipped.push(...found.skipped);
5626
- incomplete.push(...found.incomplete);
5674
+ appendAll(skipped, found.skipped);
5675
+ appendAll(incomplete, found.incomplete);
5627
5676
  }
5628
5677
 
5629
5678
  const answer: GrepAnswer = {
@@ -6250,10 +6299,11 @@ export class WorkspaceModule implements Module {
6250
6299
  mount.lastMaterializedBranchId = null;
6251
6300
  mount.lastMaterializedSeq = 0;
6252
6301
 
6253
- // force: this path only runs after a deliberate undo/redo/branch switch
6254
- // on the framework's own _config mount — restoring disk to the branch
6255
- // state IS the operator intent, so the freshness guard yields. named:
6256
- // the whole tree is that deliberate scope, entries without evidence too.
6302
+ // force: this path only runs after a deliberate branch switch, rollback
6303
+ // or suppression on the framework's own _config mount — restoring disk
6304
+ // to the branch state IS the operator intent, so the freshness guard
6305
+ // yields. named: the whole tree is that deliberate scope, entries
6306
+ // without evidence too.
6257
6307
  const pushed = await this.withMount(mount, () => {
6258
6308
  const branchId = store.currentBranch().id;
6259
6309
  return this.pushUnlocked(mount, store.treeList(mount.treeStateId).map((e) => e.path), { force: true, named: true, branchId });
@@ -6803,6 +6853,8 @@ interface DirectHead {
6803
6853
  branchId: string;
6804
6854
  after: number;
6805
6855
  notice: string | null;
6856
+ /** Set where P was written while no turn of the agent's was alive (recordDirectWrite), or read from a record an earlier release saved, which doesn't say (loadDirectHeads): the window isn't asked of it. */
6857
+ outsideTurn?: true;
6806
6858
  }
6807
6859
 
6808
6860
  /** A store position: a branch and its head. */
@@ -6811,11 +6863,20 @@ type DirectPosition = Pick<DirectHead, 'branchId' | 'after'>;
6811
6863
  /** The global record type directHeads is saved as: a checkpoint at a clean stop that changed it. */
6812
6864
  const DIRECT_HEADS_RECORD_TYPE = 'workspace/direct-heads';
6813
6865
 
6866
+ /**
6867
+ * The saved entries' version: an entry this release saves carries it, and
6868
+ * says of each position whether a turn of its agent's made it (`outsideTurn`
6869
+ * where none did). An entry an earlier release saved has none.
6870
+ */
6871
+ const DIRECT_HEADS_VERSION = 2;
6872
+
6814
6873
  /** One mount's positions at one root (resolved, as DiskAgreement keeps a root), by agent, with N only where it's set. */
6815
6874
  interface DirectHeadsEntry {
6816
6875
  mount: string;
6817
6876
  root: string;
6818
- agents: Record<string, { branchId: string; after: number; notice?: string }>;
6877
+ /** DIRECT_HEADS_VERSION, absent on an entry an earlier release saved. */
6878
+ v?: typeof DIRECT_HEADS_VERSION;
6879
+ agents: Record<string, { branchId: string; after: number; notice?: string; outsideTurn?: true }>;
6819
6880
  }
6820
6881
 
6821
6882
  /** directHeads as saved: an entry per mount and root its agents wrote direct under. */
@@ -6832,12 +6893,14 @@ function checkedHeads(value: unknown): DirectHeadsSnapshot {
6832
6893
  const isObject = (v: unknown): v is Record<string, unknown> => typeof v === 'object' && v !== null && !Array.isArray(v);
6833
6894
  if (!Array.isArray(value)) throw new Error("the record isn't of the shape saved");
6834
6895
  for (const saved of value as unknown[]) {
6835
- if (!isObject(saved) || typeof saved.mount !== 'string' || typeof saved.root !== 'string' || !isObject(saved.agents)) {
6896
+ if (!isObject(saved) || typeof saved.mount !== 'string' || typeof saved.root !== 'string' || !isObject(saved.agents)
6897
+ || (saved.v !== undefined && saved.v !== DIRECT_HEADS_VERSION)) {
6836
6898
  throw new Error(`an entry isn't of the shape saved: ${JSON.stringify(saved)?.slice(0, 200)}`);
6837
6899
  }
6838
6900
  for (const [agent, head] of Object.entries(saved.agents)) {
6839
6901
  if (!isObject(head) || typeof head.branchId !== 'string' || typeof head.after !== 'number'
6840
- || (head.notice !== undefined && typeof head.notice !== 'string')) {
6902
+ || (head.notice !== undefined && typeof head.notice !== 'string')
6903
+ || (head.outsideTurn !== undefined && head.outsideTurn !== true)) {
6841
6904
  throw new Error(`agent ${JSON.stringify(agent)}'s position on mount ${JSON.stringify(saved.mount)} isn't of the shape saved`);
6842
6905
  }
6843
6906
  }
@@ -6847,9 +6910,9 @@ function checkedHeads(value: unknown): DirectHeadsSnapshot {
6847
6910
 
6848
6911
  /** A saved record's content, whatever order its mounts and agents were written in, to tell whether a save would change it. */
6849
6912
  function canonicalHeads(snapshot: DirectHeadsSnapshot): string {
6850
- return JSON.stringify(snapshot.map(({ mount, root, agents }) => [mount, root, Object.keys(agents).sort().map((agent) => {
6851
- const { branchId, after, notice } = agents[agent]!;
6852
- return [agent, branchId, after, notice ?? null];
6913
+ return JSON.stringify(snapshot.map(({ mount, root, v, agents }) => [mount, root, v ?? null, Object.keys(agents).sort().map((agent) => {
6914
+ const { branchId, after, notice, outsideTurn } = agents[agent]!;
6915
+ return [agent, branchId, after, notice ?? null, outsideTurn === true];
6853
6916
  })]).sort((a, b) => {
6854
6917
  const [x, y] = [JSON.stringify(a.slice(0, 2)), JSON.stringify(b.slice(0, 2))];
6855
6918
  return x < y ? -1 : x > y ? 1 : 0;
@@ -48,6 +48,7 @@ import type { FileHandle } from 'node:fs/promises';
48
48
  import { basename, dirname, isAbsolute, join, posix, relative, resolve, sep } from 'node:path';
49
49
  import { onlyDeviceDiffers, sameRootIdentity, type Fingerprint, type RootIdentity } from './disk-agreement.js';
50
50
  import { OUTSIDE_STEP, UNFOLLOWED_STEP, errnoClause, errnoCode, systemWords } from './answers.js';
51
+ import { appendAll } from '../../append-all.js';
51
52
 
52
53
  export interface MountView {
53
54
  /**
@@ -2391,7 +2392,7 @@ export async function walkScope(
2391
2392
  for (const d of subdirs) walk.dirs.add(d);
2392
2393
  for (const [p, why] of others) walk.others.set(p, why);
2393
2394
  for (const p of otherFiles) walk.otherFiles.add(p);
2394
- walk.incomplete.push(...regions);
2395
+ appendAll(walk.incomplete, regions);
2395
2396
  walk.complete.add(rel);
2396
2397
  const listing = { leaves, subdirs, ...dir.identity() };
2397
2398
  listings.set(rel, listing);
@@ -94,6 +94,7 @@ import {
94
94
  } from './observe.js';
95
95
  import { EffectFailed, type Expect, callFailed, chainOf, chmodContained, narrowedTo, syncDirectories, unlinkContained, writeContained } from './effects.js';
96
96
  import { OUTSIDE_STEP, RESOLVED_OUTSIDE_STEP, UNFOLLOWED_STEP, errnoClause, errnoWords } from './answers.js';
97
+ import { appendAll } from '../../append-all.js';
97
98
 
98
99
  export type EntryState =
99
100
  | 'synced'
@@ -1150,8 +1151,8 @@ export async function reconcilePass(
1150
1151
  return result;
1151
1152
  }
1152
1153
  const { walk, facts } = gathered;
1153
- result.dirs.push(...gathered.dirs);
1154
- result.incomplete.push(...gathered.incomplete);
1154
+ appendAll(result.dirs, gathered.dirs);
1155
+ appendAll(result.incomplete, gathered.incomplete);
1155
1156
 
1156
1157
  // Decide and apply — synchronously, so nothing interleaves.
1157
1158
  const branchId = store.currentBranch().id;
@@ -5,13 +5,19 @@
5
5
  * `[tag: …]` or `[tag …]`: text the framework didn't write is marked
6
6
  * wherever it would open with one of these (supplied-text.ts). A toolset's
7
7
  * `[server/toolset:instance]` label is built from its server's id and names
8
- * instead.
8
+ * instead, and so is a line of another agent's round as an agent that watches
9
+ * its slot is sent it (foreign-rounds.ts, #291): a bracket of the
10
+ * framework's around the tool's name, which the other agent supplied, and
11
+ * the call's input or the result's outcome. The line is marked as one text,
12
+ * so an opening of one of these tags is marked wherever it forms across it,
13
+ * the name included, while the framework's own words and placeholders in it
14
+ * stay unmarked.
9
15
  */
10
16
  export const NOTICE_TAG = {
11
17
  turnInterrupted: 'turn-interrupted',
12
18
  closedChannel: 'closed channel',
13
19
  tunedOut: 'tuned out',
14
- refusalRewind: 'refusal-rewind',
20
+ refusalRewind: 'turns-set-aside',
15
21
  drafts: 'drafts',
16
22
  delivered: 'delivered',
17
23
  routing: 'routing',
@@ -39,6 +45,8 @@ export const NOTICE_TAG = {
39
45
  channelInvitation: 'Channel invitation',
40
46
  system: 'system',
41
47
  toolsets: 'toolsets',
48
+ wakeOnboarding: 'wake onboarding',
49
+ suppressionReview: 'suppression review',
42
50
  heartbeat: 'heartbeat',
43
51
  silentHeartbeat: 'silent heartbeat',
44
52
  heartbeatTick: 'heartbeat tick',
@@ -64,22 +72,26 @@ export const NOTICE_TAG = {
64
72
  truncated: 'truncated',
65
73
  cutToFit: 'cut to fit',
66
74
  blockNotShown: 'block not shown',
75
+ noText: 'no text',
67
76
  } as const;
68
77
 
78
+ export const FORMER_NOTICE_TAGS = ['refusal-rewind'] as const;
79
+
69
80
  /**
70
- * The bracket openings context-manager 0.23.0 and 0.23.1 write into an
71
- * agent's context outside a tool result or read back from it, marked as the
72
- * framework's own are. Check them against each context-manager release the
73
- * framework takes.
81
+ * The bracket openings context-manager 0.25.1 writes into an agent's context
82
+ * outside a tool result or read back from it, the same as 0.23.1 and 0.25.0
83
+ * write, marked as the framework's own are. Its `[truncated — original was`
84
+ * isn't here: NOTICE_TAG.truncated marks it. Check them against each
85
+ * context-manager release the framework takes.
74
86
  */
75
87
  export const CONTEXT_MANAGER_TAGS = [
76
88
  'content omitted', 'image not shown', 'Operator note', 'Recall', 'tool call omitted', 'tool result moved', 'Topic Transition',
77
89
  ] as const;
78
90
 
79
91
  /**
80
- * The bracket openings membrane 0.8.0 writes into an agent's request outside
81
- * a tool result, marked as the framework's own are. Check them against each
82
- * membrane release the framework takes.
92
+ * The bracket openings membrane 0.8.0 and 0.9.0 write into an agent's request
93
+ * outside a tool result, marked as the framework's own are. Check them against
94
+ * each membrane release the framework takes.
83
95
  */
84
96
  export const MEMBRANE_TAGS = [
85
97
  'Audio', 'continuing', 'Document', 'duplicate tool_result for', 'Image', 'orphan tool_result for', 'Start', 'Tool Result', 'Video',
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * Operator action log — a durable, append-only JSONL record of every
3
3
  * operator-initiated mutation of a live resident: branch rollbacks, message
4
- * suppressions, undo/redo/hide, unstick/nudge, runtime-settings changes,
5
- * host quiesce/resume. One file per store, next to the chronicle
4
+ * suppressions, branch checkouts (switchBranch), undo/redo/hide,
5
+ * unstick/nudge, runtime-settings changes, host quiesce/resume. One file per store, next to the chronicle
6
6
  * (`<storePath>/operator-actions.jsonl`), so it travels with backups and
7
7
  * survives host restarts the way `repair-receipts.jsonl` and
8
8
  * `watchdog-wedge.jsonl` do.
@@ -32,7 +32,7 @@ export interface OperatorRequester {
32
32
  export interface OperatorLogEntry {
33
33
  /** ISO-8601 wall-clock time of the record. */
34
34
  at: string;
35
- /** Action kind, e.g. 'rollback', 'suppress', 'undo', 'hide', 'quiesce'. */
35
+ /** Action kind, e.g. 'rollback', 'suppress', 'checkout', 'undo-turn', 'hide', 'quiesce'. */
36
36
  kind: string;
37
37
  /** Agent the action targeted (absent for host-wide actions). */
38
38
  agent?: string;
@@ -167,6 +167,39 @@ export interface SurgeryMarksPreview {
167
167
  messagesRemoved: number;
168
168
  /** Removed messages that carry a Discord address at all. */
169
169
  addressable: number;
170
+ /**
171
+ * Of the messages removed, how many no live agent is shown (#291): no
172
+ * window holds them (stored and never presented to an agent, or taken out
173
+ * of every window since), or only windows whose view leaves them out (a
174
+ * row a tune-out holds, which a window written down from the record
175
+ * holds). Their marks tell Discord of messages no agent was being shown.
176
+ * A message that may be in a window that couldn't be read isn't counted,
177
+ * and is logged. Set only when the agent's context is presented.
178
+ */
179
+ neverPresented?: number;
180
+ /**
181
+ * For a rollback on a presented window: the rows after the target in the
182
+ * agent's window that the branch cut keeps in the record (stored before
183
+ * the write that presented the target, presented after it). They leave
184
+ * the window as arrived and not presented, and enter it again at the
185
+ * agent's next turn start, after what its window holds then; nothing at
186
+ * rest presents them before it (rollbackToMessage). An own row of the
187
+ * agent's among them re-enters at the surgery's release. The hold is in
188
+ * memory, so a restart before then presents them at its pass at rest.
189
+ * Not removed, so not counted in `messagesRemoved`, and not marked. Set
190
+ * only then.
191
+ */
192
+ returnedToArrivals?: number;
193
+ /**
194
+ * For a rollback on a presented window: the rows after the target in the
195
+ * agent's window that the write presenting the target presented too (a
196
+ * batch). The cut is at that write, so they stay in the window after the
197
+ * target. Not removed, so not counted in `messagesRemoved`, and not
198
+ * marked: a suppression, or, for those with a Discord message id, a hide
199
+ * by it, takes them out.
200
+ * Set only then.
201
+ */
202
+ keptInWindowAfterTarget?: number;
170
203
  emoji: string;
171
204
  scopes: Record<'addressed' | 'all', {
172
205
  count: number;