@animalabs/agent-framework 0.27.0 → 0.29.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 (344) hide show
  1. package/README.md +145 -41
  2. package/dist/src/agent.d.ts +29 -2
  3. package/dist/src/agent.d.ts.map +1 -1
  4. package/dist/src/agent.js +73 -12
  5. package/dist/src/agent.js.map +1 -1
  6. package/dist/src/api/mcp-server-core.d.ts.map +1 -1
  7. package/dist/src/api/mcp-server-core.js +3 -12
  8. package/dist/src/api/mcp-server-core.js.map +1 -1
  9. package/dist/src/api/server.d.ts.map +1 -1
  10. package/dist/src/api/server.js +11 -5
  11. package/dist/src/api/server.js.map +1 -1
  12. package/dist/src/auto-continue.d.ts +5 -2
  13. package/dist/src/auto-continue.d.ts.map +1 -1
  14. package/dist/src/auto-continue.js +9 -5
  15. package/dist/src/auto-continue.js.map +1 -1
  16. package/dist/src/code-execution/isolate/runner.d.ts +7 -5
  17. package/dist/src/code-execution/isolate/runner.d.ts.map +1 -1
  18. package/dist/src/code-execution/isolate/runner.js +7 -5
  19. package/dist/src/code-execution/isolate/runner.js.map +1 -1
  20. package/dist/src/code-execution/isolate/scripts.d.ts.map +1 -1
  21. package/dist/src/code-execution/isolate/scripts.js +3 -2
  22. package/dist/src/code-execution/isolate/scripts.js.map +1 -1
  23. package/dist/src/cut-off-round.d.ts +24 -0
  24. package/dist/src/cut-off-round.d.ts.map +1 -0
  25. package/dist/src/cut-off-round.js +87 -0
  26. package/dist/src/cut-off-round.js.map +1 -0
  27. package/dist/src/framework.d.ts +468 -125
  28. package/dist/src/framework.d.ts.map +1 -1
  29. package/dist/src/framework.js +3651 -1111
  30. package/dist/src/framework.js.map +1 -1
  31. package/dist/src/gate/event-gate.d.ts +133 -13
  32. package/dist/src/gate/event-gate.d.ts.map +1 -1
  33. package/dist/src/gate/event-gate.js +654 -59
  34. package/dist/src/gate/event-gate.js.map +1 -1
  35. package/dist/src/gate/index.d.ts +3 -2
  36. package/dist/src/gate/index.d.ts.map +1 -1
  37. package/dist/src/gate/index.js +2 -1
  38. package/dist/src/gate/index.js.map +1 -1
  39. package/dist/src/gate/reply-judge.d.ts +116 -0
  40. package/dist/src/gate/reply-judge.d.ts.map +1 -0
  41. package/dist/src/gate/reply-judge.js +467 -0
  42. package/dist/src/gate/reply-judge.js.map +1 -0
  43. package/dist/src/gate/types.d.ts +173 -2
  44. package/dist/src/gate/types.d.ts.map +1 -1
  45. package/dist/src/heartbeat/heartbeat.d.ts +202 -0
  46. package/dist/src/heartbeat/heartbeat.d.ts.map +1 -0
  47. package/dist/src/heartbeat/heartbeat.js +778 -0
  48. package/dist/src/heartbeat/heartbeat.js.map +1 -0
  49. package/dist/src/heartbeat/reminder-time.d.ts +5 -0
  50. package/dist/src/heartbeat/reminder-time.d.ts.map +1 -0
  51. package/dist/src/heartbeat/reminder-time.js +107 -0
  52. package/dist/src/heartbeat/reminder-time.js.map +1 -0
  53. package/dist/src/held-writes.d.ts +3 -3
  54. package/dist/src/held-writes.js +3 -3
  55. package/dist/src/host-presentation.d.ts +170 -0
  56. package/dist/src/host-presentation.d.ts.map +1 -0
  57. package/dist/src/host-presentation.js +561 -0
  58. package/dist/src/host-presentation.js.map +1 -0
  59. package/dist/src/index.d.ts +5 -1
  60. package/dist/src/index.d.ts.map +1 -1
  61. package/dist/src/index.js +3 -1
  62. package/dist/src/index.js.map +1 -1
  63. package/dist/src/line-reader.d.ts +4 -0
  64. package/dist/src/line-reader.d.ts.map +1 -0
  65. package/dist/src/line-reader.js +59 -0
  66. package/dist/src/line-reader.js.map +1 -0
  67. package/dist/src/mcpl/capability-mask.d.ts.map +1 -1
  68. package/dist/src/mcpl/capability-mask.js +3 -2
  69. package/dist/src/mcpl/capability-mask.js.map +1 -1
  70. package/dist/src/mcpl/channel-registry.d.ts +34 -6
  71. package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
  72. package/dist/src/mcpl/channel-registry.js +133 -54
  73. package/dist/src/mcpl/channel-registry.js.map +1 -1
  74. package/dist/src/mcpl/conversation-router.d.ts.map +1 -1
  75. package/dist/src/mcpl/conversation-router.js +2 -1
  76. package/dist/src/mcpl/conversation-router.js.map +1 -1
  77. package/dist/src/mcpl/convert-block.d.ts +1 -0
  78. package/dist/src/mcpl/convert-block.d.ts.map +1 -1
  79. package/dist/src/mcpl/convert-block.js +16 -4
  80. package/dist/src/mcpl/convert-block.js.map +1 -1
  81. package/dist/src/mcpl/hook-orchestrator.d.ts.map +1 -1
  82. package/dist/src/mcpl/hook-orchestrator.js +4 -3
  83. package/dist/src/mcpl/hook-orchestrator.js.map +1 -1
  84. package/dist/src/mcpl/inbound-source.d.ts +29 -11
  85. package/dist/src/mcpl/inbound-source.d.ts.map +1 -1
  86. package/dist/src/mcpl/inbound-source.js +43 -70
  87. package/dist/src/mcpl/inbound-source.js.map +1 -1
  88. package/dist/src/mcpl/modern-connection.d.ts.map +1 -1
  89. package/dist/src/mcpl/modern-connection.js +11 -7
  90. package/dist/src/mcpl/modern-connection.js.map +1 -1
  91. package/dist/src/mcpl/protocol-family.d.ts +3 -2
  92. package/dist/src/mcpl/protocol-family.d.ts.map +1 -1
  93. package/dist/src/mcpl/protocol-family.js +25 -3
  94. package/dist/src/mcpl/protocol-family.js.map +1 -1
  95. package/dist/src/mcpl/push-handler.js +2 -2
  96. package/dist/src/mcpl/push-handler.js.map +1 -1
  97. package/dist/src/mcpl/references.d.ts +12 -40
  98. package/dist/src/mcpl/references.d.ts.map +1 -1
  99. package/dist/src/mcpl/references.js +29 -23
  100. package/dist/src/mcpl/references.js.map +1 -1
  101. package/dist/src/mcpl/server-connection.d.ts +18 -8
  102. package/dist/src/mcpl/server-connection.d.ts.map +1 -1
  103. package/dist/src/mcpl/server-connection.js +70 -30
  104. package/dist/src/mcpl/server-connection.js.map +1 -1
  105. package/dist/src/mcpl/skip-reply-wake.d.ts +25 -0
  106. package/dist/src/mcpl/skip-reply-wake.d.ts.map +1 -1
  107. package/dist/src/mcpl/skip-reply-wake.js +25 -0
  108. package/dist/src/mcpl/skip-reply-wake.js.map +1 -1
  109. package/dist/src/mcpl/tags.d.ts +9 -2
  110. package/dist/src/mcpl/tags.d.ts.map +1 -1
  111. package/dist/src/mcpl/tags.js +12 -2
  112. package/dist/src/mcpl/tags.js.map +1 -1
  113. package/dist/src/mcpl/tool-presence.d.ts +66 -14
  114. package/dist/src/mcpl/tool-presence.d.ts.map +1 -1
  115. package/dist/src/mcpl/tool-presence.js +150 -80
  116. package/dist/src/mcpl/tool-presence.js.map +1 -1
  117. package/dist/src/mcpl/tool-signature.d.ts +10 -3
  118. package/dist/src/mcpl/tool-signature.d.ts.map +1 -1
  119. package/dist/src/mcpl/tool-signature.js +60 -30
  120. package/dist/src/mcpl/tool-signature.js.map +1 -1
  121. package/dist/src/mcpl/toolset-host.d.ts +88 -55
  122. package/dist/src/mcpl/toolset-host.d.ts.map +1 -1
  123. package/dist/src/mcpl/toolset-host.js +220 -111
  124. package/dist/src/mcpl/toolset-host.js.map +1 -1
  125. package/dist/src/mcpl/toolsets-module.d.ts +27 -35
  126. package/dist/src/mcpl/toolsets-module.d.ts.map +1 -1
  127. package/dist/src/mcpl/toolsets-module.js +313 -91
  128. package/dist/src/mcpl/toolsets-module.js.map +1 -1
  129. package/dist/src/mcpl/transport.d.ts +1 -1
  130. package/dist/src/mcpl/transport.d.ts.map +1 -1
  131. package/dist/src/mcpl/transport.js +16 -16
  132. package/dist/src/mcpl/transport.js.map +1 -1
  133. package/dist/src/mcpl/types.d.ts +31 -13
  134. package/dist/src/mcpl/types.d.ts.map +1 -1
  135. package/dist/src/mcpl/types.js.map +1 -1
  136. package/dist/src/module-registry.d.ts +10 -8
  137. package/dist/src/module-registry.d.ts.map +1 -1
  138. package/dist/src/module-registry.js +15 -9
  139. package/dist/src/module-registry.js.map +1 -1
  140. package/dist/src/modules/api/index.d.ts.map +1 -1
  141. package/dist/src/modules/api/index.js +4 -2
  142. package/dist/src/modules/api/index.js.map +1 -1
  143. package/dist/src/modules/discord/index.d.ts.map +1 -1
  144. package/dist/src/modules/discord/index.js +33 -25
  145. package/dist/src/modules/discord/index.js.map +1 -1
  146. package/dist/src/modules/history/index.d.ts.map +1 -1
  147. package/dist/src/modules/history/index.js +30 -17
  148. package/dist/src/modules/history/index.js.map +1 -1
  149. package/dist/src/modules/sender-name.d.ts +7 -0
  150. package/dist/src/modules/sender-name.d.ts.map +1 -0
  151. package/dist/src/modules/sender-name.js +10 -0
  152. package/dist/src/modules/sender-name.js.map +1 -0
  153. package/dist/src/modules/workspace/answers.d.ts +26 -0
  154. package/dist/src/modules/workspace/answers.d.ts.map +1 -0
  155. package/dist/src/modules/workspace/answers.js +138 -0
  156. package/dist/src/modules/workspace/answers.js.map +1 -0
  157. package/dist/src/modules/workspace/branch-intent.d.ts +5 -3
  158. package/dist/src/modules/workspace/branch-intent.d.ts.map +1 -1
  159. package/dist/src/modules/workspace/branch-intent.js +6 -2
  160. package/dist/src/modules/workspace/branch-intent.js.map +1 -1
  161. package/dist/src/modules/workspace/direct-write.d.ts +3 -0
  162. package/dist/src/modules/workspace/direct-write.d.ts.map +1 -1
  163. package/dist/src/modules/workspace/direct-write.js +59 -24
  164. package/dist/src/modules/workspace/direct-write.js.map +1 -1
  165. package/dist/src/modules/workspace/disk-agreement.d.ts +33 -11
  166. package/dist/src/modules/workspace/disk-agreement.d.ts.map +1 -1
  167. package/dist/src/modules/workspace/disk-agreement.js +48 -17
  168. package/dist/src/modules/workspace/disk-agreement.js.map +1 -1
  169. package/dist/src/modules/workspace/edit-text.d.ts +2 -1
  170. package/dist/src/modules/workspace/edit-text.d.ts.map +1 -1
  171. package/dist/src/modules/workspace/edit-text.js +4 -2
  172. package/dist/src/modules/workspace/edit-text.js.map +1 -1
  173. package/dist/src/modules/workspace/effects.d.ts +4 -2
  174. package/dist/src/modules/workspace/effects.d.ts.map +1 -1
  175. package/dist/src/modules/workspace/effects.js +67 -50
  176. package/dist/src/modules/workspace/effects.js.map +1 -1
  177. package/dist/src/modules/workspace/index.d.ts +63 -51
  178. package/dist/src/modules/workspace/index.d.ts.map +1 -1
  179. package/dist/src/modules/workspace/index.js +980 -547
  180. package/dist/src/modules/workspace/index.js.map +1 -1
  181. package/dist/src/modules/workspace/observe.d.ts +125 -82
  182. package/dist/src/modules/workspace/observe.d.ts.map +1 -1
  183. package/dist/src/modules/workspace/observe.js +465 -241
  184. package/dist/src/modules/workspace/observe.js.map +1 -1
  185. package/dist/src/modules/workspace/read-page.d.ts.map +1 -1
  186. package/dist/src/modules/workspace/read-page.js +7 -1
  187. package/dist/src/modules/workspace/read-page.js.map +1 -1
  188. package/dist/src/modules/workspace/reconcile.d.ts +7 -1
  189. package/dist/src/modules/workspace/reconcile.d.ts.map +1 -1
  190. package/dist/src/modules/workspace/reconcile.js +156 -50
  191. package/dist/src/modules/workspace/reconcile.js.map +1 -1
  192. package/dist/src/modules/workspace/result-text.d.ts +1 -0
  193. package/dist/src/modules/workspace/result-text.d.ts.map +1 -1
  194. package/dist/src/modules/workspace/result-text.js.map +1 -1
  195. package/dist/src/modules/workspace/sync.d.ts +9 -0
  196. package/dist/src/modules/workspace/sync.d.ts.map +1 -1
  197. package/dist/src/modules/workspace/sync.js +14 -0
  198. package/dist/src/modules/workspace/sync.js.map +1 -1
  199. package/dist/src/modules/workspace/types.d.ts +96 -43
  200. package/dist/src/modules/workspace/types.d.ts.map +1 -1
  201. package/dist/src/modules/workspace/types.js.map +1 -1
  202. package/dist/src/modules/workspace/watcher.d.ts.map +1 -1
  203. package/dist/src/modules/workspace/watcher.js +8 -3
  204. package/dist/src/modules/workspace/watcher.js.map +1 -1
  205. package/dist/src/notice-tags.d.ts +79 -0
  206. package/dist/src/notice-tags.d.ts.map +1 -0
  207. package/dist/src/notice-tags.js +83 -0
  208. package/dist/src/notice-tags.js.map +1 -0
  209. package/dist/src/prose-drafts.d.ts +4 -3
  210. package/dist/src/prose-drafts.d.ts.map +1 -1
  211. package/dist/src/prose-drafts.js +3 -2
  212. package/dist/src/prose-drafts.js.map +1 -1
  213. package/dist/src/reasoning-loss-notice.d.ts +23 -0
  214. package/dist/src/reasoning-loss-notice.d.ts.map +1 -0
  215. package/dist/src/reasoning-loss-notice.js +52 -0
  216. package/dist/src/reasoning-loss-notice.js.map +1 -0
  217. package/dist/src/reasoning-loss.d.ts +24 -0
  218. package/dist/src/reasoning-loss.d.ts.map +1 -0
  219. package/dist/src/reasoning-loss.js +102 -0
  220. package/dist/src/reasoning-loss.js.map +1 -0
  221. package/dist/src/send-tools.d.ts +3 -2
  222. package/dist/src/send-tools.d.ts.map +1 -1
  223. package/dist/src/send-tools.js +3 -2
  224. package/dist/src/send-tools.js.map +1 -1
  225. package/dist/src/sent-rows.js +1 -1
  226. package/dist/src/silent-heartbeat.d.ts +1 -53
  227. package/dist/src/silent-heartbeat.d.ts.map +1 -1
  228. package/dist/src/silent-heartbeat.js +56 -3
  229. package/dist/src/silent-heartbeat.js.map +1 -1
  230. package/dist/src/supplied-text.d.ts +35 -0
  231. package/dist/src/supplied-text.d.ts.map +1 -0
  232. package/dist/src/supplied-text.js +141 -0
  233. package/dist/src/supplied-text.js.map +1 -0
  234. package/dist/src/thinking-drops.d.ts +4 -11
  235. package/dist/src/thinking-drops.d.ts.map +1 -1
  236. package/dist/src/thinking-drops.js +7 -14
  237. package/dist/src/thinking-drops.js.map +1 -1
  238. package/dist/src/tool-args.d.ts +12 -0
  239. package/dist/src/tool-args.d.ts.map +1 -1
  240. package/dist/src/tool-args.js +39 -4
  241. package/dist/src/tool-args.js.map +1 -1
  242. package/dist/src/tool-image-ledger.d.ts.map +1 -1
  243. package/dist/src/tool-image-ledger.js +2 -1
  244. package/dist/src/tool-image-ledger.js.map +1 -1
  245. package/dist/src/tool-presentation.d.ts.map +1 -1
  246. package/dist/src/tool-presentation.js +5 -4
  247. package/dist/src/tool-presentation.js.map +1 -1
  248. package/dist/src/tool-result-guard.d.ts +8 -4
  249. package/dist/src/tool-result-guard.d.ts.map +1 -1
  250. package/dist/src/tool-result-guard.js +23 -11
  251. package/dist/src/tool-result-guard.js.map +1 -1
  252. package/dist/src/tune-out/coordinator.d.ts +3 -2
  253. package/dist/src/tune-out/coordinator.d.ts.map +1 -1
  254. package/dist/src/tune-out/coordinator.js +24 -26
  255. package/dist/src/tune-out/coordinator.js.map +1 -1
  256. package/dist/src/tune-out/tools.d.ts +4 -1
  257. package/dist/src/tune-out/tools.d.ts.map +1 -1
  258. package/dist/src/types/agent.d.ts +63 -18
  259. package/dist/src/types/agent.d.ts.map +1 -1
  260. package/dist/src/types/events.d.ts +18 -8
  261. package/dist/src/types/events.d.ts.map +1 -1
  262. package/dist/src/types/framework.d.ts +58 -0
  263. package/dist/src/types/framework.d.ts.map +1 -1
  264. package/dist/src/types/module.d.ts +27 -13
  265. package/dist/src/types/module.d.ts.map +1 -1
  266. package/dist/src/types/trace.d.ts +34 -1
  267. package/dist/src/types/trace.d.ts.map +1 -1
  268. package/package.json +3 -3
  269. package/src/agent.ts +76 -12
  270. package/src/api/mcp-server-core.ts +3 -14
  271. package/src/api/server.ts +11 -5
  272. package/src/auto-continue.ts +12 -5
  273. package/src/code-execution/isolate/runner.ts +7 -5
  274. package/src/code-execution/isolate/scripts.ts +3 -2
  275. package/src/cut-off-round.ts +98 -0
  276. package/src/framework.ts +3772 -1138
  277. package/src/gate/event-gate.ts +705 -60
  278. package/src/gate/index.ts +9 -1
  279. package/src/gate/reply-judge.ts +512 -0
  280. package/src/gate/types.ts +176 -3
  281. package/src/heartbeat/heartbeat.ts +843 -0
  282. package/src/heartbeat/reminder-time.ts +107 -0
  283. package/src/held-writes.ts +3 -3
  284. package/src/host-presentation.ts +605 -0
  285. package/src/index.ts +5 -1
  286. package/src/line-reader.ts +58 -0
  287. package/src/mcpl/capability-mask.ts +3 -2
  288. package/src/mcpl/channel-registry.ts +139 -53
  289. package/src/mcpl/conversation-router.ts +2 -1
  290. package/src/mcpl/convert-block.ts +17 -4
  291. package/src/mcpl/hook-orchestrator.ts +4 -3
  292. package/src/mcpl/inbound-source.ts +45 -70
  293. package/src/mcpl/modern-connection.ts +11 -7
  294. package/src/mcpl/protocol-family.ts +24 -3
  295. package/src/mcpl/push-handler.ts +2 -2
  296. package/src/mcpl/references.ts +31 -23
  297. package/src/mcpl/server-connection.ts +76 -34
  298. package/src/mcpl/skip-reply-wake.ts +35 -0
  299. package/src/mcpl/tags.ts +13 -2
  300. package/src/mcpl/tool-presence.ts +149 -82
  301. package/src/mcpl/tool-signature.ts +64 -32
  302. package/src/mcpl/toolset-host.ts +212 -110
  303. package/src/mcpl/toolsets-module.ts +277 -91
  304. package/src/mcpl/transport.ts +18 -14
  305. package/src/mcpl/types.ts +32 -13
  306. package/src/module-registry.ts +14 -9
  307. package/src/modules/api/index.ts +4 -2
  308. package/src/modules/discord/index.ts +37 -25
  309. package/src/modules/history/index.ts +30 -18
  310. package/src/modules/sender-name.ts +9 -0
  311. package/src/modules/workspace/answers.ts +151 -0
  312. package/src/modules/workspace/branch-intent.ts +10 -5
  313. package/src/modules/workspace/direct-write.ts +59 -23
  314. package/src/modules/workspace/disk-agreement.ts +52 -21
  315. package/src/modules/workspace/edit-text.ts +7 -5
  316. package/src/modules/workspace/effects.ts +69 -50
  317. package/src/modules/workspace/index.ts +966 -556
  318. package/src/modules/workspace/observe.ts +497 -242
  319. package/src/modules/workspace/read-page.ts +7 -1
  320. package/src/modules/workspace/reconcile.ts +184 -49
  321. package/src/modules/workspace/result-text.ts +2 -0
  322. package/src/modules/workspace/sync.ts +16 -0
  323. package/src/modules/workspace/types.ts +96 -43
  324. package/src/modules/workspace/watcher.ts +8 -3
  325. package/src/notice-tags.ts +84 -0
  326. package/src/prose-drafts.ts +4 -3
  327. package/src/reasoning-loss-notice.ts +64 -0
  328. package/src/reasoning-loss.ts +120 -0
  329. package/src/send-tools.ts +3 -2
  330. package/src/sent-rows.ts +1 -1
  331. package/src/silent-heartbeat.ts +4 -3
  332. package/src/supplied-text.ts +154 -0
  333. package/src/thinking-drops.ts +10 -16
  334. package/src/tool-args.ts +38 -4
  335. package/src/tool-image-ledger.ts +2 -1
  336. package/src/tool-presentation.ts +5 -4
  337. package/src/tool-result-guard.ts +26 -11
  338. package/src/tune-out/coordinator.ts +25 -27
  339. package/src/tune-out/tools.ts +4 -1
  340. package/src/types/agent.ts +63 -18
  341. package/src/types/events.ts +18 -8
  342. package/src/types/framework.ts +59 -0
  343. package/src/types/module.ts +28 -13
  344. package/src/types/trace.ts +36 -1
@@ -14,8 +14,9 @@ export type SameRoundThinkTextPolicySource =
14
14
  export interface AutoContinueRun {
15
15
  /** How the agent stops, as the row puts it ("call skip_reply"). */
16
16
  stop: string;
17
- /** The turn before ended in words that were held, not sent, because it
18
- * had already sent with a send tool. */
17
+ /** The turn before ended in words some or all of which were held, not
18
+ * sent, because a send in it may already have posted where they were
19
+ * going. */
19
20
  heldAfterSend?: boolean;
20
21
  /** Set by the scheduler: the continuation is the turn's only cause. */
21
22
  sole?: boolean;
@@ -54,13 +55,15 @@ export interface AgentConfig {
54
55
  * Enforced at dispatch for registered agent callers; omitted means 'all'.
55
56
  * - 'all': all available tools
56
57
  * - string[]: exact tool names, including module--utility names for utilities.
57
- * Utilities aren't tools of their own: an agent's model and its scripts are
58
- * offered them only through 'utils', whose run checks the utility's own
59
- * name. An agent that should use a utility lists both 'utils' and
60
- * 'module--utility'. The name alone passes the dispatch check for any call
61
- * by that name, whether the host makes it with executeToolCall on the
62
- * agent's behalf or the model or a script makes it without being offered
63
- * it. The slot is hidden when no utility is permitted.
58
+ * Utilities and the host's other rarely-used tools are in the host's
59
+ * built-in toolset ("settings"), out of the tool list: the model reaches
60
+ * them with toolsets--open {toolset:"settings"} and toolsets--act, each
61
+ * checked under the tool's own name. An agent that should use a utility
62
+ * from its model lists 'toolsets--open', 'toolsets--act' and
63
+ * 'module--utility' (an agent without the two meta-tools keeps every other
64
+ * tool in its list, but no utility). The name alone passes the dispatch
65
+ * check for any call by that name, whether the host makes it with
66
+ * executeToolCall on the agent's behalf or the model or a script makes it.
64
67
  * Trusted module calls are exempt. Genuinely unidentified public callers,
65
68
  * including unknown legacy names, remain unrestricted. Framework-created
66
69
  * identities have tool authority only while registered.
@@ -254,7 +257,18 @@ export interface AgentConfig {
254
257
  * that the record doesn't account for raises the
255
258
  * `thinking-binding-loss` ops alert, once per incident and again if a
256
259
  * call drops more. The provider reports drops only on a request that
257
- * carries the drop control; without it, such a block is refused.
260
+ * carries the drop control; without it, such a block is refused;
261
+ * - the agent is told, in a `[reasoning] <agent>:` system notice of kind
262
+ * `reasoning-loss` stored for it as the framework's other notices are,
263
+ * when a committing compile leaves out a stored reply's reasoning at a
264
+ * change of the request's head, at a branch's first compile, or in a
265
+ * fold or other change to an earlier message that takes a reply of the
266
+ * current turn, and, with `dropBlock` set too, when the provider drops
267
+ * blocks it can place as the agent's stored replies or the stream's
268
+ * rounds, once per incident and again when a call drops more. The
269
+ * framework hears compiles through `Agent.onThinkingStrip` from the
270
+ * agent's first stream on, unless a host has set its own, so an agent
271
+ * driven only through the direct API is never told.
258
272
  * The record and the notes
259
273
  * vouch for requests as agent-framework hands them to membrane, so a
260
274
  * membrane `beforeRequest` hook that changes a request must change every
@@ -546,10 +560,18 @@ export interface InferenceRequest {
546
560
  * agent while a turn was alive: a coalesced render placed in its queue
547
561
  * (wakeToRead), or a message, notice or event whose wake was queued with
548
562
  * it. Once a request that carried the write was answered and, for a wake
549
- * that carries a channel, the agent has since published into that
550
- * channel having read it, or once the write is in neither the agent's
551
- * queue nor its store's current branch, the wake starts no turn. */
563
+ * that carries a channel and isn't marked `ambient`, the agent has since
564
+ * published into that channel having read it, or once the write is in
565
+ * neither the agent's queue nor its store's current branch, the wake
566
+ * starts no turn. */
552
567
  readsDeferredWrite?: string;
568
+ /** Host-owned: this wake's sole cause is this message, stored in its
569
+ * agent's store as it arrived, not deferred (its row's id). Once a
570
+ * request that carried the message was answered and, for a wake that
571
+ * carries a channel and isn't marked `ambient`, the agent has since
572
+ * published into that channel having read it, or once the message isn't
573
+ * on its store's current branch, the wake starts no turn. */
574
+ readsStoredMessage?: string;
553
575
  agentName: string;
554
576
  reason: string;
555
577
  source: string;
@@ -560,8 +582,9 @@ export interface InferenceRequest {
560
582
  * the turn's auto-published plain-text speech here so a single TRUNK agent
561
583
  * replies in the channel it is answering — not the process-global most-recent-
562
584
  * inbound locus, which a concurrent message elsewhere can hijack (item-3
563
- * redux). Undefined for non-channel wakes (heartbeat, timers, module events),
564
- * which correctly fall back to the global default channel, except an
585
+ * redux). Undefined for non-channel wakes (heartbeat, timers, module events).
586
+ * A heartbeat's turn takes no channel at all, and holds its plain speech as
587
+ * drafts; any other falls back to the global default channel, except an
565
588
  * ephemeral run's (a subagent's), which takes no global fallback.
566
589
  */
567
590
  channelId?: string;
@@ -584,6 +607,17 @@ export interface InferenceRequest {
584
607
  * it starts. Hosts don't set it.
585
608
  */
586
609
  autoContinueRun?: AutoContinueRun;
610
+ /**
611
+ * Framework-set: whether this wake's turn is a heartbeat's, which has no
612
+ * channel and holds its plain speech as drafts. True on a wake that
613
+ * continues a heartbeat's turn with no channel of its own (an autoContinue
614
+ * continuation, a bounce's resend wake, a ` !` continuation, and a re-arm,
615
+ * which copies its trigger), and on a merged batch whose causes include a
616
+ * heartbeat's wake and name no channel; false on a merged batch with none,
617
+ * so the batch's first request doesn't decide it. Unset, a wake is a
618
+ * heartbeat's when its `source` is `heartbeat`. Hosts don't set it.
619
+ */
620
+ heartbeatTurn?: boolean;
587
621
  /**
588
622
  * True when the triggering message explicitly addressed the agent (mention,
589
623
  * reply-to-bot, DM — `chat:addressed` in MCPL RFC-001 terms). When a wake
@@ -597,11 +631,22 @@ export interface InferenceRequest {
597
631
  * (`chat:ambient`). A coalesced push's wake carries it only to read a
598
632
  * render, and only when every notice the render stands for was. Such a
599
633
  * message asked nothing of the agent, so a wake for it that carries
600
- * `readsDeferredWrite` is dropped once a request that carried the message
601
- * was answered, with no publish asked of the agent. A message with neither
602
- * tag is in doubt, and is judged as an addressed one.
634
+ * `readsDeferredWrite` or `readsStoredMessage` is dropped once a request
635
+ * that carried the message was answered, with no publish asked of the
636
+ * agent. A message with neither tag is in doubt, and is judged as an
637
+ * addressed one.
603
638
  */
604
639
  ambient?: true;
640
+ /**
641
+ * Host-owned: true when the triggering message's server marked it a
642
+ * `chat:system` notice (RFC-001 rev 3): an event about the place, such as
643
+ * a join or the weather changing, not something anyone said. Such a wake
644
+ * names no channel for its turn's plain speech, though it carries
645
+ * `channelId`: a turn it starts alone resolves its locus as a heartbeat's
646
+ * does. Like an ambient one, a wake to read it is done once read. Never
647
+ * set on a coalesced render's wake, which may fold messages too.
648
+ */
649
+ systemNotice?: true;
605
650
  /**
606
651
  * Who spoke the message that triggered this inference, as an adapter-
607
652
  * namespaced opaque id (`<serverId>:user:<authorId>`) — never a display
@@ -211,14 +211,17 @@ export interface ToolResult {
211
211
  /** Whether this was an error (for LLM) */
212
212
  isError?: boolean;
213
213
  /**
214
- * The dispatcher refused the call before it opened, RFC-007's refusal, so
215
- * nothing ran and the call certainly had no effect. Only the dispatcher's
216
- * path, the model's calls and a script's, sets it: the caller may not use
217
- * the tool (allowedTools), a `skip_reply` wake was refused, the call's MCPL
218
- * server is absent or still connecting, the host's policy for that server
219
- * denies the tool, or a fork reached outside its channel. RFC-007's
220
- * lifecycle refuses the call from the same place, so observers see no
221
- * events for it. A check made after the call opened, such as a module's
214
+ * The call was refused before it opened, RFC-007's refusal, so nothing ran
215
+ * and the call certainly had no effect. The dispatcher's path, the model's
216
+ * calls and a script's, sets it: the caller may not use the tool
217
+ * (allowedTools), a `skip_reply` wake was refused, the call's MCPL server is
218
+ * absent or still connecting, the host's policy for that server denies the
219
+ * tool, or a fork reached outside its channel. RFC-007's lifecycle refuses
220
+ * the call from the same place, so observers see no events for it. The
221
+ * framework also sets it on the result it stores for each call in the last
222
+ * round of a response the output limit cut off: such a call was never
223
+ * dispatched or opened, and its result goes into the context with the reply,
224
+ * not through a tool-result event. A check made after the call opened, such as a module's
222
225
  * answer for a name it has no tool for or arguments that don't fit a
223
226
  * schema, is a failure whose text says nothing was done, as is an MCPL
224
227
  * request that couldn't be written. A programmatic call (`executeToolCall`,
@@ -270,6 +273,13 @@ export interface ToolCall {
270
273
  name: string;
271
274
  /** Tool input */
272
275
  input: unknown;
276
+ /**
277
+ * membrane's marker (ToolUseContent.unparseableInput), present when `input`
278
+ * isn't the model's arguments. The framework refuses such a call without
279
+ * running it, except one whose text is JSON `null`, which runs as a call
280
+ * with no arguments.
281
+ */
282
+ unparseableInput?: string;
273
283
  /** The agent that made this tool call. Set by the framework dispatch layer. */
274
284
  callerAgentName?: string;
275
285
  /**
@@ -218,6 +218,50 @@ export interface FrameworkConfig {
218
218
  */
219
219
  providerHold?: ProviderHoldHook;
220
220
 
221
+ /**
222
+ * Delays before a turn whose retries ran out is sent again, in ms (default
223
+ * `[120000, 480000, 1920000]`: 2, 8 and 32 minutes), or `false` never to.
224
+ * When a persistent agent's turn ends exhausted on a transient failure (a
225
+ * server error, an overload, a rate limit, a network failure, or a timeout
226
+ * membrane marks retryable and not as a deadline it reports as run out, such
227
+ * as a 408 or a socket's ETIMEDOUT), its trigger is queued again after the
228
+ * first delay, as a wake of its own. It opens where the exhausted turn's
229
+ * plain speech was going: its locus, where a message mid-turn may have moved
230
+ * it, else its trigger channel. Carrying that channel, it ranks as addressed
231
+ * in a merged wake's choice of channel, so a newer ambient wake from
232
+ * elsewhere doesn't take it; an autoContinue continuation's still yields its
233
+ * channel to any wake's, as it does on main; a continuation's, such as a
234
+ * budget restart's, names no author. A re-arm that would have to guess a
235
+ * channel isn't sent again: one whose turn was woken for a channel id that
236
+ * names no one registered channel and never found one, and whose request
237
+ * names none of its own. A failure that states a wait is held for that wait
238
+ * first, as any turn's is, and a deadline ends the turn as before, whether
239
+ * the host set it or membrane marks one as run out: the runtime's or
240
+ * undici's on a sent request, the Anthropic adapter's watchdogs, or the
241
+ * Anthropic SDK's timeout, which covers its connect timeout too. Until one
242
+ * of the re-armed turn's rounds has run or had its tool calls cut off, its
243
+ * failure gets no retries from the error policy: on another transient
244
+ * failure the next delay follows, until the list runs out, and a failure of
245
+ * any other kind ends the re-arming. A wake for the agent while it waits
246
+ * starts its turn at once, with the re-armed trigger merged in. That turn is
247
+ * the wake's: the error policy retries its failures. A completed turn starts
248
+ * the count again, and so does a message said to the agent: not a system
249
+ * message or notice; not an edit, reaction or deletion, unless an edit is
250
+ * the first version of a message the agent sees; not a message its own view
251
+ * leaves out, such as one a tune-out holds from it; and not the agent's own
252
+ * schedule, the heartbeat's tick or reminder, a self-wake timer it set, or a
253
+ * script's wake. A notice a module or an MCPL server stores as a message
254
+ * counts. A message in the residents' shared slot counts for each resident
255
+ * that reads it. Any other wake leaves the count going on. A re-armed turn's
256
+ * transient failure writes no `[inference-failed]` marker unless a round of
257
+ * it ran or had its tool calls cut off; any other failure of it writes one.
258
+ * Each counts toward the hard-down streak. Ephemeral runs and conversation
259
+ * forks are never re-armed. The wait and the count are kept in memory:
260
+ * `stop()` drops them, and so does a restart. The wait isn't a turn, so
261
+ * `abortInference()` doesn't end it.
262
+ */
263
+ exhaustedTurnRearmMs?: number[] | false;
264
+
221
265
  /** Interval for periodic store sync in milliseconds (default: 1000ms, 0 to disable) */
222
266
  syncIntervalMs?: number;
223
267
 
@@ -299,6 +343,21 @@ export interface FrameworkConfig {
299
343
 
300
344
  /** EventGate config. If omitted, all events trigger inference (unchanged default). */
301
345
  gate?: GateOptions;
346
+ /**
347
+ * The heartbeat: the agent's own periodic check-in and reminders, kept by
348
+ * the framework (src/heartbeat/heartbeat.ts), with the tools
349
+ * `heartbeat--heartbeat_status`, `heartbeat--heartbeat_configure`,
350
+ * `heartbeat--heartbeat_trigger`, `heartbeat--reminder_add`,
351
+ * `heartbeat--reminder_list` and `heartbeat--reminder_cancel`. `true` turns it
352
+ * on with its defaults; `false`, null or leaving it out leaves it off. Its
353
+ * wakes go to the gate as heartbeat-mcpl's pushes did, from the server id
354
+ * `heartbeat`, so the agent's rules decide them and a sleep lets them
355
+ * through. It replaces the heartbeat-mcpl server, which is refused beside it
356
+ * (by its id, a heartbeat tool prefix, or its command), at create and at a
357
+ * runtime connect: both would wake the agent. `importFrom` brings that
358
+ * server's schedule and reminders along.
359
+ */
360
+ heartbeat?: boolean | null | import('../heartbeat/heartbeat.js').HeartbeatOptions;
302
361
 
303
362
  /**
304
363
  * Liveness watchdog: fail hard (and let the supervisor restart) if the main
@@ -72,10 +72,11 @@ export type ModuleMessage = StoredMessage & {
72
72
  * True on a message a tune-out holds from the residents: one that arrived
73
73
  * in a tuned-out channel, stamped `metadata.tuneOut` as it came in. The
74
74
  * store keeps it, but no resident is shown the row itself: no resident's
75
- * compiled view includes it, during the tune-out or after it, and a tool
76
- * boundary of a turn alive when it arrived stores it without injecting it
77
- * into the live turn. The subconscious reads it. Its text can still reach
78
- * a resident in rows of their own, which aren't marked, such as the
75
+ * compiled view includes it, during the tune-out or after it, and a
76
+ * resident's tool boundary of a turn alive when it arrived stores it
77
+ * without injecting it into the live turn. The subconscious reads it. Its
78
+ * text can still reach a resident in rows of their own, which aren't
79
+ * marked, such as the
79
80
  * cancel's `<tuned-out-backlog>` row, with the text of the tune-out's newest
80
81
  * messages, up to `backlogCap` of them and as many as fit in one of the
81
82
  * residents' messages, the stored ones first and then those still held;
@@ -142,16 +143,27 @@ export interface Module {
142
143
 
143
144
  /**
144
145
  * Utilities: agent-invocable operations that deliberately do NOT get a
145
- * first-class tool slot. Every tool schema taxes every inference; a
146
- * capability used twice a month shouldn't. Utilities are listed, described,
147
- * and invoked through the framework's single `utils` tool instead — same
148
- * ToolDefinition shape, same un-prefixed names, and dispatch arrives at the
149
- * SAME handleToolCall as getTools() output, so a tool migrates between
150
- * surfaces by moving its definition from one list to the other and nothing
151
- * else. Optional; omitting it means the module contributes no utilities.
146
+ * slot in the tool list. Every tool schema taxes every inference; a
147
+ * capability used twice a month shouldn't. Utilities belong to the host's
148
+ * built-in toolset ("settings"): an agent sees them with
149
+ * `toolsets--look {toolset:"settings"}` and calls them with
150
+ * `toolsets--act` once it has opened it. Same ToolDefinition shape, same
151
+ * un-prefixed names, and dispatch arrives at the SAME handleToolCall as
152
+ * getTools() output. Optional; omitting it means the module contributes no
153
+ * utilities.
152
154
  */
153
155
  getUtilities?(): ToolDefinition[];
154
156
 
157
+ /**
158
+ * Where one of this module's tools (a getTools() name, unprefixed) is
159
+ * presented: in the agent's tool list (`'header'`, the default), or in the
160
+ * host's built-in toolset (`'builtin'`), out of the tool list, opened with
161
+ * `toolsets--open {toolset:"settings"}` and called with `toolsets--act`.
162
+ * For tools an agent uses rarely: settings, administration, status reads.
163
+ * Optional; omitting it keeps every tool in the tool list.
164
+ */
165
+ toolPlacement?(toolName: string): 'header' | 'builtin' | undefined;
166
+
155
167
  /**
156
168
  * Handle a tool call.
157
169
  * Tool name is without module prefix.
@@ -232,13 +244,16 @@ export interface AgentSettingsExtension {
232
244
  properties: Record<string, unknown>;
233
245
  /** The setting keys this extension owns (must match `properties` keys). */
234
246
  keys: string[];
235
- /** Current values for the extension's keys. */
247
+ /** Current values for the extension's keys. A refused agent_settings call
248
+ * names what changed by comparing every field this returns, before the
249
+ * call and at its refusal. */
236
250
  get(agentName: string): Record<string, unknown>;
237
251
  /** Apply a partial update (only this extension's keys present) and return
238
252
  * the new values. Throw to surface a validation error to the agent. */
239
253
  update(agentName: string, patch: Record<string, unknown>): Record<string, unknown>;
240
254
  /** Restore the listed keys (or all when omitted) to defaults and return the
241
- * new values. Optional — extensions without reset semantics are skipped. */
255
+ * new values. Optional: without it, a reset of every setting skips the
256
+ * extension, and a reset that names one of its keys is refused. */
242
257
  reset?(agentName: string, keys?: string[]): Record<string, unknown>;
243
258
  }
244
259
 
@@ -114,6 +114,23 @@ export type TraceEvent =
114
114
  /** Bounded like `error`. */
115
115
  stack?: string;
116
116
  })
117
+ | (TraceEventBase & {
118
+ /**
119
+ * A turn waiting out its error policy's delay before a retry says so:
120
+ * as the wait begins, with when it is due to end, and again every 60
121
+ * seconds while it lasts, while its agent is the one registered under
122
+ * its name, and never after the wait ends (its time coming, a stop, or
123
+ * an abort). The failure being retried is the `inference:failed` just
124
+ * before it. A host watching for agents gone quiet can tell a waiting
125
+ * one from a stuck one by it.
126
+ */
127
+ type: 'inference:waiting';
128
+ agentName: string;
129
+ /** When the wait is due to end (epoch ms): it counts down by its
130
+ * timers, so a stalled event loop can end it later. Absent for a wait
131
+ * too long for a date. */
132
+ until?: number;
133
+ })
117
134
  | (TraceEventBase & {
118
135
  type: 'inference:exhausted';
119
136
  agentName: string;
@@ -472,6 +489,24 @@ export type TraceEvent =
472
489
  policyName: string;
473
490
  eventCount: number;
474
491
  })
492
+ | (TraceEventBase & {
493
+ /** The reply judge's verdict on a `judge` rule's batch. `verdict`:
494
+ * `reply` or `wait` as the judge answered, `error` when it failed,
495
+ * timed out or answered nothing usable; `woke` is whether the batch
496
+ * then woke the agent (an error does by the host's onError).
497
+ * The judge's reason is in the agent's gate_status, not here: it's
498
+ * written from the agent's context. */
499
+ type: 'gate:judge-verdict';
500
+ policyName: string;
501
+ verdict: 'reply' | 'wait' | 'error';
502
+ woke: boolean;
503
+ eventCount: number;
504
+ durationMs: number;
505
+ model?: string;
506
+ inputTokens?: number;
507
+ cacheReadTokens?: number;
508
+ outputTokens?: number;
509
+ })
475
510
  | (TraceEventBase & {
476
511
  /** A batched wake's turn started without its `[Gate: …]` line (the
477
512
  * gate hands the line to the wake when its message is the newest at
@@ -836,7 +871,7 @@ export type TraceEvent =
836
871
  parkedAdmissions?: number;
837
872
  /** True when undrained turns were force-cancelled (abandon). */
838
873
  abandoned?: boolean;
839
- /** Agents whose turn the abandon had not ended when its grace ran out: a token held with no stream and no check ahead (a puppet tool turn, a store surgery's reservation, a turn finishing its last delivery), or a turn that hadn't reached its next check, the tool-result guard's wait for its speech included. A turn whose stream the abandon cancelled while it was still streaming isn't listed, even one still running when the grace ran out. */
874
+ /** Agents whose turn the abandon had not ended when its grace ran out: a token held with no stream and no check ahead (a puppet tool turn, a store surgery's reservation, a turn finishing its last delivery), or a turn that hadn't reached its next check, the tool-result guard's wait for its speech included, or a turn whose stream's cancel threw with no check ahead, so that its stream goes on. A turn whose stream the abandon cancelled while it was still streaming isn't listed, even one still running when the grace ran out. */
840
875
  unabandonable?: string[];
841
876
  })
842
877
  | (TraceEventBase & {