@animalabs/agent-framework 0.28.0 → 0.30.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 (289) hide show
  1. package/README.md +88 -25
  2. package/dist/src/admission/admit.d.ts +90 -0
  3. package/dist/src/admission/admit.d.ts.map +1 -0
  4. package/dist/src/admission/admit.js +43 -0
  5. package/dist/src/admission/admit.js.map +1 -0
  6. package/dist/src/agent.d.ts +21 -0
  7. package/dist/src/agent.d.ts.map +1 -1
  8. package/dist/src/agent.js +47 -7
  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 +3 -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 +7 -3
  15. package/dist/src/api/server.js.map +1 -1
  16. package/dist/src/author-presentation.d.ts +50 -0
  17. package/dist/src/author-presentation.d.ts.map +1 -0
  18. package/dist/src/author-presentation.js +58 -0
  19. package/dist/src/author-presentation.js.map +1 -0
  20. package/dist/src/auto-continue.d.ts +2 -0
  21. package/dist/src/auto-continue.d.ts.map +1 -1
  22. package/dist/src/auto-continue.js +5 -2
  23. package/dist/src/auto-continue.js.map +1 -1
  24. package/dist/src/code-execution/isolate/runner.d.ts +7 -5
  25. package/dist/src/code-execution/isolate/runner.d.ts.map +1 -1
  26. package/dist/src/code-execution/isolate/runner.js +7 -5
  27. package/dist/src/code-execution/isolate/runner.js.map +1 -1
  28. package/dist/src/code-execution/isolate/scripts.d.ts.map +1 -1
  29. package/dist/src/code-execution/isolate/scripts.js +3 -2
  30. package/dist/src/code-execution/isolate/scripts.js.map +1 -1
  31. package/dist/src/dendrite/index.d.ts +6 -0
  32. package/dist/src/dendrite/index.d.ts.map +1 -0
  33. package/dist/src/dendrite/index.js +3 -0
  34. package/dist/src/dendrite/index.js.map +1 -0
  35. package/dist/src/dendrite/presets.d.ts +60 -0
  36. package/dist/src/dendrite/presets.d.ts.map +1 -0
  37. package/dist/src/dendrite/presets.js +117 -0
  38. package/dist/src/dendrite/presets.js.map +1 -0
  39. package/dist/src/dendrite/registry.d.ts +260 -0
  40. package/dist/src/dendrite/registry.d.ts.map +1 -0
  41. package/dist/src/dendrite/registry.js +742 -0
  42. package/dist/src/dendrite/registry.js.map +1 -0
  43. package/dist/src/dendrite/types.d.ts +392 -0
  44. package/dist/src/dendrite/types.d.ts.map +1 -0
  45. package/dist/src/dendrite/types.js +24 -0
  46. package/dist/src/dendrite/types.js.map +1 -0
  47. package/dist/src/framework.d.ts +846 -67
  48. package/dist/src/framework.d.ts.map +1 -1
  49. package/dist/src/framework.js +4213 -924
  50. package/dist/src/framework.js.map +1 -1
  51. package/dist/src/gate/event-gate.d.ts +46 -14
  52. package/dist/src/gate/event-gate.d.ts.map +1 -1
  53. package/dist/src/gate/event-gate.js +143 -53
  54. package/dist/src/gate/event-gate.js.map +1 -1
  55. package/dist/src/gate/index.d.ts +1 -1
  56. package/dist/src/gate/index.d.ts.map +1 -1
  57. package/dist/src/gate/index.js +1 -1
  58. package/dist/src/gate/index.js.map +1 -1
  59. package/dist/src/gate/types.d.ts +12 -2
  60. package/dist/src/gate/types.d.ts.map +1 -1
  61. package/dist/src/heartbeat/heartbeat.d.ts +18 -0
  62. package/dist/src/heartbeat/heartbeat.d.ts.map +1 -1
  63. package/dist/src/heartbeat/heartbeat.js +34 -8
  64. package/dist/src/heartbeat/heartbeat.js.map +1 -1
  65. package/dist/src/held-writes.d.ts +3 -3
  66. package/dist/src/held-writes.js +3 -3
  67. package/dist/src/host-presentation.d.ts +174 -0
  68. package/dist/src/host-presentation.d.ts.map +1 -0
  69. package/dist/src/host-presentation.js +565 -0
  70. package/dist/src/host-presentation.js.map +1 -0
  71. package/dist/src/index.d.ts +7 -4
  72. package/dist/src/index.d.ts.map +1 -1
  73. package/dist/src/index.js +7 -2
  74. package/dist/src/index.js.map +1 -1
  75. package/dist/src/line-reader.d.ts +4 -0
  76. package/dist/src/line-reader.d.ts.map +1 -0
  77. package/dist/src/line-reader.js +59 -0
  78. package/dist/src/line-reader.js.map +1 -0
  79. package/dist/src/mcpl/channel-registry.d.ts +118 -15
  80. package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
  81. package/dist/src/mcpl/channel-registry.js +266 -110
  82. package/dist/src/mcpl/channel-registry.js.map +1 -1
  83. package/dist/src/mcpl/conversation-router.d.ts.map +1 -1
  84. package/dist/src/mcpl/conversation-router.js +2 -1
  85. package/dist/src/mcpl/conversation-router.js.map +1 -1
  86. package/dist/src/mcpl/convert-block.d.ts +1 -0
  87. package/dist/src/mcpl/convert-block.d.ts.map +1 -1
  88. package/dist/src/mcpl/convert-block.js +16 -4
  89. package/dist/src/mcpl/convert-block.js.map +1 -1
  90. package/dist/src/mcpl/hook-orchestrator.d.ts.map +1 -1
  91. package/dist/src/mcpl/hook-orchestrator.js +4 -3
  92. package/dist/src/mcpl/hook-orchestrator.js.map +1 -1
  93. package/dist/src/mcpl/inbound-source.d.ts +3 -1
  94. package/dist/src/mcpl/inbound-source.d.ts.map +1 -1
  95. package/dist/src/mcpl/inbound-source.js +3 -1
  96. package/dist/src/mcpl/inbound-source.js.map +1 -1
  97. package/dist/src/mcpl/modern-connection.d.ts.map +1 -1
  98. package/dist/src/mcpl/modern-connection.js +11 -7
  99. package/dist/src/mcpl/modern-connection.js.map +1 -1
  100. package/dist/src/mcpl/protocol-family.d.ts +3 -2
  101. package/dist/src/mcpl/protocol-family.d.ts.map +1 -1
  102. package/dist/src/mcpl/protocol-family.js +25 -3
  103. package/dist/src/mcpl/protocol-family.js.map +1 -1
  104. package/dist/src/mcpl/push-coalescer.d.ts +9 -0
  105. package/dist/src/mcpl/push-coalescer.d.ts.map +1 -1
  106. package/dist/src/mcpl/push-coalescer.js +21 -0
  107. package/dist/src/mcpl/push-coalescer.js.map +1 -1
  108. package/dist/src/mcpl/push-handler.js +2 -2
  109. package/dist/src/mcpl/push-handler.js.map +1 -1
  110. package/dist/src/mcpl/references.d.ts +12 -40
  111. package/dist/src/mcpl/references.d.ts.map +1 -1
  112. package/dist/src/mcpl/references.js +29 -23
  113. package/dist/src/mcpl/references.js.map +1 -1
  114. package/dist/src/mcpl/server-connection.d.ts.map +1 -1
  115. package/dist/src/mcpl/server-connection.js +20 -20
  116. package/dist/src/mcpl/server-connection.js.map +1 -1
  117. package/dist/src/mcpl/skip-reply-wake.d.ts +25 -0
  118. package/dist/src/mcpl/skip-reply-wake.d.ts.map +1 -1
  119. package/dist/src/mcpl/skip-reply-wake.js +25 -0
  120. package/dist/src/mcpl/skip-reply-wake.js.map +1 -1
  121. package/dist/src/mcpl/tool-presence.d.ts.map +1 -1
  122. package/dist/src/mcpl/tool-presence.js +18 -17
  123. package/dist/src/mcpl/tool-presence.js.map +1 -1
  124. package/dist/src/mcpl/tool-signature.d.ts.map +1 -1
  125. package/dist/src/mcpl/tool-signature.js +17 -16
  126. package/dist/src/mcpl/tool-signature.js.map +1 -1
  127. package/dist/src/mcpl/toolset-host.d.ts +8 -26
  128. package/dist/src/mcpl/toolset-host.d.ts.map +1 -1
  129. package/dist/src/mcpl/toolset-host.js +16 -6
  130. package/dist/src/mcpl/toolset-host.js.map +1 -1
  131. package/dist/src/mcpl/toolsets-module.d.ts +14 -25
  132. package/dist/src/mcpl/toolsets-module.d.ts.map +1 -1
  133. package/dist/src/mcpl/toolsets-module.js +187 -50
  134. package/dist/src/mcpl/toolsets-module.js.map +1 -1
  135. package/dist/src/mcpl/transport.d.ts +1 -1
  136. package/dist/src/mcpl/transport.d.ts.map +1 -1
  137. package/dist/src/mcpl/transport.js +16 -16
  138. package/dist/src/mcpl/transport.js.map +1 -1
  139. package/dist/src/mcpl/types.d.ts +28 -12
  140. package/dist/src/mcpl/types.d.ts.map +1 -1
  141. package/dist/src/mcpl/types.js.map +1 -1
  142. package/dist/src/module-registry.d.ts +6 -7
  143. package/dist/src/module-registry.d.ts.map +1 -1
  144. package/dist/src/module-registry.js +6 -7
  145. package/dist/src/module-registry.js.map +1 -1
  146. package/dist/src/modules/api/index.d.ts.map +1 -1
  147. package/dist/src/modules/api/index.js +4 -2
  148. package/dist/src/modules/api/index.js.map +1 -1
  149. package/dist/src/modules/discord/index.d.ts.map +1 -1
  150. package/dist/src/modules/discord/index.js +33 -25
  151. package/dist/src/modules/discord/index.js.map +1 -1
  152. package/dist/src/modules/history/index.js +8 -6
  153. package/dist/src/modules/history/index.js.map +1 -1
  154. package/dist/src/modules/sender-name.d.ts +7 -0
  155. package/dist/src/modules/sender-name.d.ts.map +1 -0
  156. package/dist/src/modules/sender-name.js +10 -0
  157. package/dist/src/modules/sender-name.js.map +1 -0
  158. package/dist/src/modules/workspace/answers.d.ts +5 -1
  159. package/dist/src/modules/workspace/answers.d.ts.map +1 -1
  160. package/dist/src/modules/workspace/answers.js +16 -1
  161. package/dist/src/modules/workspace/answers.js.map +1 -1
  162. package/dist/src/modules/workspace/direct-write.d.ts.map +1 -1
  163. package/dist/src/modules/workspace/direct-write.js +6 -4
  164. package/dist/src/modules/workspace/direct-write.js.map +1 -1
  165. package/dist/src/modules/workspace/effects.d.ts +4 -2
  166. package/dist/src/modules/workspace/effects.d.ts.map +1 -1
  167. package/dist/src/modules/workspace/effects.js +50 -40
  168. package/dist/src/modules/workspace/effects.js.map +1 -1
  169. package/dist/src/modules/workspace/index.d.ts +1 -0
  170. package/dist/src/modules/workspace/index.d.ts.map +1 -1
  171. package/dist/src/modules/workspace/index.js +66 -36
  172. package/dist/src/modules/workspace/index.js.map +1 -1
  173. package/dist/src/modules/workspace/observe.d.ts +51 -20
  174. package/dist/src/modules/workspace/observe.d.ts.map +1 -1
  175. package/dist/src/modules/workspace/observe.js +120 -82
  176. package/dist/src/modules/workspace/observe.js.map +1 -1
  177. package/dist/src/modules/workspace/reconcile.d.ts +7 -1
  178. package/dist/src/modules/workspace/reconcile.d.ts.map +1 -1
  179. package/dist/src/modules/workspace/reconcile.js +133 -37
  180. package/dist/src/modules/workspace/reconcile.js.map +1 -1
  181. package/dist/src/notice-tags.d.ts +81 -0
  182. package/dist/src/notice-tags.d.ts.map +1 -0
  183. package/dist/src/notice-tags.js +85 -0
  184. package/dist/src/notice-tags.js.map +1 -0
  185. package/dist/src/reasoning-loss-notice.d.ts.map +1 -1
  186. package/dist/src/reasoning-loss-notice.js +5 -3
  187. package/dist/src/reasoning-loss-notice.js.map +1 -1
  188. package/dist/src/silent-heartbeat.d.ts +5 -55
  189. package/dist/src/silent-heartbeat.d.ts.map +1 -1
  190. package/dist/src/silent-heartbeat.js +63 -7
  191. package/dist/src/silent-heartbeat.js.map +1 -1
  192. package/dist/src/stored-injections.d.ts +4 -0
  193. package/dist/src/stored-injections.d.ts.map +1 -1
  194. package/dist/src/stored-injections.js +6 -0
  195. package/dist/src/stored-injections.js.map +1 -1
  196. package/dist/src/supplied-text.d.ts +35 -0
  197. package/dist/src/supplied-text.d.ts.map +1 -0
  198. package/dist/src/supplied-text.js +141 -0
  199. package/dist/src/supplied-text.js.map +1 -0
  200. package/dist/src/tool-args.d.ts.map +1 -1
  201. package/dist/src/tool-args.js +9 -8
  202. package/dist/src/tool-args.js.map +1 -1
  203. package/dist/src/tool-image-ledger.d.ts.map +1 -1
  204. package/dist/src/tool-image-ledger.js +2 -1
  205. package/dist/src/tool-image-ledger.js.map +1 -1
  206. package/dist/src/tool-presentation.d.ts.map +1 -1
  207. package/dist/src/tool-presentation.js +5 -4
  208. package/dist/src/tool-presentation.js.map +1 -1
  209. package/dist/src/tune-out/coordinator.d.ts +382 -11
  210. package/dist/src/tune-out/coordinator.d.ts.map +1 -1
  211. package/dist/src/tune-out/coordinator.js +1100 -119
  212. package/dist/src/tune-out/coordinator.js.map +1 -1
  213. package/dist/src/tune-out/tools.d.ts +101 -5
  214. package/dist/src/tune-out/tools.d.ts.map +1 -1
  215. package/dist/src/tune-out/tools.js +55 -18
  216. package/dist/src/tune-out/tools.js.map +1 -1
  217. package/dist/src/types/agent.d.ts +48 -9
  218. package/dist/src/types/agent.d.ts.map +1 -1
  219. package/dist/src/types/framework.d.ts +142 -0
  220. package/dist/src/types/framework.d.ts.map +1 -1
  221. package/dist/src/types/module.d.ts +22 -11
  222. package/dist/src/types/module.d.ts.map +1 -1
  223. package/dist/src/types/trace.d.ts +136 -0
  224. package/dist/src/types/trace.d.ts.map +1 -1
  225. package/package.json +3 -3
  226. package/src/admission/admit.ts +113 -0
  227. package/src/agent.ts +52 -7
  228. package/src/api/mcp-server-core.ts +3 -14
  229. package/src/api/server.ts +7 -3
  230. package/src/author-presentation.ts +81 -0
  231. package/src/auto-continue.ts +8 -2
  232. package/src/code-execution/isolate/runner.ts +7 -5
  233. package/src/code-execution/isolate/scripts.ts +3 -2
  234. package/src/dendrite/index.ts +32 -0
  235. package/src/dendrite/presets.ts +149 -0
  236. package/src/dendrite/registry.ts +808 -0
  237. package/src/dendrite/types.ts +397 -0
  238. package/src/framework.ts +4362 -852
  239. package/src/gate/event-gate.ts +159 -52
  240. package/src/gate/index.ts +1 -1
  241. package/src/gate/types.ts +12 -2
  242. package/src/heartbeat/heartbeat.ts +48 -9
  243. package/src/held-writes.ts +3 -3
  244. package/src/host-presentation.ts +612 -0
  245. package/src/index.ts +17 -4
  246. package/src/line-reader.ts +58 -0
  247. package/src/mcpl/channel-registry.ts +306 -111
  248. package/src/mcpl/conversation-router.ts +2 -1
  249. package/src/mcpl/convert-block.ts +17 -4
  250. package/src/mcpl/hook-orchestrator.ts +4 -3
  251. package/src/mcpl/inbound-source.ts +3 -1
  252. package/src/mcpl/modern-connection.ts +11 -7
  253. package/src/mcpl/protocol-family.ts +24 -3
  254. package/src/mcpl/push-coalescer.ts +19 -0
  255. package/src/mcpl/push-handler.ts +2 -2
  256. package/src/mcpl/references.ts +31 -23
  257. package/src/mcpl/server-connection.ts +20 -18
  258. package/src/mcpl/skip-reply-wake.ts +35 -0
  259. package/src/mcpl/tool-presence.ts +18 -17
  260. package/src/mcpl/tool-signature.ts +17 -16
  261. package/src/mcpl/toolset-host.ts +18 -6
  262. package/src/mcpl/toolsets-module.ts +149 -50
  263. package/src/mcpl/transport.ts +18 -14
  264. package/src/mcpl/types.ts +29 -12
  265. package/src/module-registry.ts +6 -7
  266. package/src/modules/api/index.ts +4 -2
  267. package/src/modules/discord/index.ts +37 -25
  268. package/src/modules/history/index.ts +8 -6
  269. package/src/modules/sender-name.ts +9 -0
  270. package/src/modules/workspace/answers.ts +20 -2
  271. package/src/modules/workspace/direct-write.ts +4 -3
  272. package/src/modules/workspace/effects.ts +50 -40
  273. package/src/modules/workspace/index.ts +58 -34
  274. package/src/modules/workspace/observe.ts +139 -88
  275. package/src/modules/workspace/reconcile.ts +159 -36
  276. package/src/notice-tags.ts +86 -0
  277. package/src/reasoning-loss-notice.ts +5 -3
  278. package/src/silent-heartbeat.ts +11 -7
  279. package/src/stored-injections.ts +7 -0
  280. package/src/supplied-text.ts +154 -0
  281. package/src/tool-args.ts +9 -8
  282. package/src/tool-image-ledger.ts +2 -1
  283. package/src/tool-presentation.ts +5 -4
  284. package/src/tune-out/coordinator.ts +1252 -123
  285. package/src/tune-out/tools.ts +152 -11
  286. package/src/types/agent.ts +51 -9
  287. package/src/types/framework.ts +146 -0
  288. package/src/types/module.ts +23 -11
  289. package/src/types/trace.ts +150 -0
@@ -1,15 +1,24 @@
1
1
  import { type PresentationSnapshot } from "./tool-presentation.js";
2
2
  import { JsStore } from '@animalabs/chronicle';
3
- import type { Membrane, NormalizedRequest } from '@animalabs/membrane';
3
+ import type { Membrane, ContentBlock, NormalizedRequest } from '@animalabs/membrane';
4
4
  import { type RetrySettings } from '@animalabs/membrane/retry';
5
5
  import { ContextManager } from '@animalabs/context-manager';
6
- import type { TokenBudget } from '@animalabs/context-manager';
6
+ import type { MessageMetadata, TokenBudget } from '@animalabs/context-manager';
7
7
  import type { FrameworkConfig, ErrorPolicy, ErrorAction, TraceEventListener, InferenceLogQuery, InferenceLogQueryResult, InferenceLogEntryWithId, ProcessLogQuery, ProcessLogQueryResult, ProcessLogEntryWithId, ProcessEvent, ToolCall, ToolResult, AgentConfig, InferenceRequest, Module, ContextMaintenanceSnapshot, AgentRuntimeSettingsPatch, AgentRuntimeSettingsSnapshot, SameRoundThinkTextPolicy } from './types/index.js';
8
8
  import { Agent, type RenderStats } from './agent.js';
9
9
  import { type ToolClass, type ToolClassSource } from './mcpl/tool-classes.js';
10
10
  import { ChannelRegistry } from './mcpl/channel-registry.js';
11
11
  import { ConversationRouter } from './mcpl/conversation-router.js';
12
+ import type { ActivationRecord, AgentEndReason, AgentRecord, AgentSpec, EndOutcome, HeldMail, PolicyEpoch } from './dendrite/index.js';
13
+ /**
14
+ * The framework's own tools that belong to the host's built-in toolset
15
+ * ("settings", host-presentation.ts) rather than the tool list: the ones an
16
+ * agent reaches for rarely. Modules place theirs with Module.toolPlacement,
17
+ * and every module utility is there too.
18
+ */
19
+ export declare const BUILTIN_TOOLSET_TOOLS: ReadonlySet<string>;
12
20
  import type { SessionUsageSnapshot } from './usage/types.js';
21
+ import type { ContextStrategy } from '@animalabs/context-manager';
13
22
  import { type DiscordAwarenessView, type DiscordAwarenessCancelReceipt, type DiscordAwarenessMarks, type DiscordAwarenessRetractReceipt } from './recovery/discord-awareness-outbox.js';
14
23
  import { type SurgeryMarkerReceipt, type SurgeryMarksPreview, type OperatorLogEntry, type OperatorLogInput, type OperatorRequester } from './operator-log.js';
15
24
  /**
@@ -204,6 +213,85 @@ export declare class DefaultErrorPolicy implements ErrorPolicy {
204
213
  constructor(settings?: RetrySettings);
205
214
  onInferenceError(error: Error, _agentName: string, attempt: number): ErrorAction;
206
215
  }
216
+ /**
217
+ * The admission record on a stored message: it was held from the residents
218
+ * by a policy epoch (`metadata.tuneOut = { epochId }`). ONE predicate for
219
+ * "held from the resident", read by the compiled-view filter and by the
220
+ * mid-turn injection alike (#232 H1), so the window and the wire agree.
221
+ */
222
+ export declare const heldFromResidents: (metadata: Record<string, unknown> | undefined) => boolean;
223
+ /** Options for {@link AgentFramework.deriveAgent}. */
224
+ export interface DeriveAgentOptions {
225
+ /** The new agent's name. Single-use within this framework's lifetime. */
226
+ name: string;
227
+ /** The live agent whose context and configuration are inherited. */
228
+ from: string;
229
+ /** How context is inherited. Default `'shared'`. */
230
+ mode?: 'shared' | 'copy';
231
+ /** `'shared'` only. Default `'reuse'`. */
232
+ solve?: 'reuse' | 'fresh';
233
+ /**
234
+ * `'shared'` only. Also inherit the parent's refusal ledger (what it
235
+ * declined to compress). Default false; set for a fork that stands in
236
+ * for the parent's attention. Recorded as `inherit.refusals`.
237
+ */
238
+ inheritRefusals?: boolean;
239
+ /**
240
+ * A fresh strategy instance for the child. Strategy instances hold state
241
+ * and are never shared; to reuse the parent's rendering it must be the
242
+ * same class with compatible configuration. Default: passthrough.
243
+ */
244
+ strategy?: ContextStrategy;
245
+ /** Identity and settings overrides. Everything not named is the parent's. */
246
+ config?: Partial<Omit<AgentConfig, 'name' | 'strategy'>>;
247
+ /**
248
+ * The parent's tool round in flight, if any. While a tool call runs, the
249
+ * assistant turn that made it is not in the parent's store yet. By
250
+ * default the child's branch gets that turn verbatim (as its own, like
251
+ * the rest of the inheritance) followed by a tool-result message: results
252
+ * the parent has already received as they are; the call that derived the
253
+ * child with `madeBy.result`, or a note saying it did; and any other call
254
+ * still running with a note that its result was not available. So a fork
255
+ * sees the call that made it and never meets a dangling `tool_use`.
256
+ * `madeBy` defaults to the only open call when there is exactly one.
257
+ * `include: false` leaves the round out, and the child starts from the
258
+ * last stored message before it.
259
+ */
260
+ pendingRound?: {
261
+ include?: boolean;
262
+ madeBy?: {
263
+ toolUseId: string;
264
+ result: string;
265
+ };
266
+ /** Results, from the child's side, for other calls still open, by tool-use id. */
267
+ results?: Record<string, string>;
268
+ };
269
+ /** Ordinary messages appended to the child before it runs. */
270
+ framing?: Array<{
271
+ participant: string;
272
+ content: ContentBlock[];
273
+ metadata?: MessageMetadata;
274
+ }>;
275
+ /** Who spawned it. Default: `from`. */
276
+ spawnedBy?: string;
277
+ /** Where its completion returns. */
278
+ resultTo?: import('./dendrite/index.js').ResultRoute;
279
+ /** What happens to it when its spawner ends. Default `'orphan'`. */
280
+ onParentEnd?: import('./dendrite/index.js').ParentEndPolicy;
281
+ deadlineMs?: number;
282
+ idleTimeoutMs?: number;
283
+ maxTurns?: number;
284
+ /** Preset label for discovery. Default `'task-fork'`. */
285
+ kind?: string;
286
+ metadata?: Record<string, unknown>;
287
+ }
288
+ /** Rejection delivered to the caller awaiting a bounded run that was ended from outside. */
289
+ export declare class AgentStoppedError extends Error {
290
+ readonly agentName: string;
291
+ readonly reason: AgentEndReason;
292
+ readonly by?: string | undefined;
293
+ constructor(agentName: string, reason: AgentEndReason, by?: string | undefined, detail?: string);
294
+ }
207
295
  export interface ReinitAlertText {
208
296
  opening: string;
209
297
  message: string;
@@ -382,6 +470,13 @@ export declare class AgentFramework {
382
470
  private quiesceReason?;
383
471
  private quiescedAt?;
384
472
  private traceListeners;
473
+ /** Traces emitted before start() — registry restore, interrupted work,
474
+ * resumed epochs — replayed to listeners that attach afterwards, since a
475
+ * host attaches its sinks after create() returns. Dropped at start().
476
+ * It keeps the first 1,000, the start of the stream, and counts the rest
477
+ * (earlyTracesDropped), which a replay ends by naming. */
478
+ private earlyTraces;
479
+ private earlyTracesDropped;
385
480
  private syncIntervalMs;
386
481
  private syncTimer;
387
482
  private maintenanceIntervalMs;
@@ -435,8 +530,9 @@ export declare class AgentFramework {
435
530
  private midTurnInputSignals;
436
531
  /** Last outbound locus announced to each agent as a durable `[routing]`
437
532
  * window message. Announce-on-change only: steady state emits nothing
438
- * (KV-safe, no per-turn chatter). In-memory — after a process restart the
439
- * first turn's locus is announced once to re-establish the baseline. */
533
+ * (KV-safe, no per-turn chatter). Kept in the store as well
534
+ * (rememberAnnouncedLocus), so a restart compares with what the agent was
535
+ * last told rather than with nothing. */
440
536
  private lastAnnouncedLocus;
441
537
  /** Every resident's held drafts: plain speech that was suppressed, bounced
442
538
  * or left without a destination, never published except by their
@@ -520,13 +616,18 @@ export declare class AgentFramework {
520
616
  private usedEphemeralAgentNames;
521
617
  /** One-shot generation tickets minted by createEphemeralAgent. */
522
618
  private ephemeralCandidates;
619
+ /**
620
+ * Derived agent → the agent whose tool presentation it shows. A derived
621
+ * agent that inherits its parent's tools must advertise the identical
622
+ * tool block (it is the front of the shared request prefix), including
623
+ * the parent's resident-edited visibility and descriptions.
624
+ */
625
+ private toolSurfaceOwners;
523
626
  /** Every agent createEphemeralAgent made, for as long as the object lives:
524
627
  * its usage counts in the usage record's one shared ephemeral entry. Kept
525
628
  * by the object, not the run's record (ephemeralRuns), which its cleanup
526
629
  * drops before a cancelled stream may count its last usage. */
527
630
  private ephemeralAgents;
528
- /** Warn only once per Agent instance after utilities are registered. */
529
- private emptyUtilityPermissionWarnings;
530
631
  /** Physical ephemeral frames deliberately disposed by their run watchdog/caller.
531
632
  * The name is single-generation, so these frames still own their terminal
532
633
  * typing/outgoing close even after runEphemeralToCompletion deregisters them. */
@@ -535,6 +636,10 @@ export declare class AgentFramework {
535
636
  * completes (inference:completed), not when a call answers mid-turn.
536
637
  * Drives hard-down escalation — see noteInferenceExhausted. */
537
638
  private consecutiveInferenceFailures;
639
+ private turnRearmMs;
640
+ private turnRearms;
641
+ private exhaustingRearms;
642
+ private statedWaitRuns;
538
643
  /** N consecutive failed inferences ⇒ the agent is treated as hard-down and
539
644
  * escalated loudly to stderr. */
540
645
  private readonly inferenceFailureEscalationThreshold;
@@ -586,8 +691,25 @@ export declare class AgentFramework {
586
691
  private subconsciousStrategy;
587
692
  /** Its config (speak_in_channel gate, voice block provenance). */
588
693
  private subconsciousConfig;
589
- /** Tune-out coordinator (issue #77); non-null iff subconscious + channels. */
694
+ /** Tune-out coordinator (issue #77); non-null iff a reader is configured + channels. */
590
695
  private tuneOutCoordinator;
696
+ /** Residents are offered `tune_out` (a reader is configured, or `tuneOut.enabled`). */
697
+ private tuneOutOffered;
698
+ /**
699
+ * The reply anchor a coalesced delivery would set, parked until the
700
+ * acceptance is acknowledged to the server (handleCoalescedIncoming): an
701
+ * acceptance whose commit fails after its delivery moves no anchor, and the
702
+ * retry the receipt answers, which delivers nothing again, commits the one
703
+ * its first attempt parked. Keyed by server and event id; bounded.
704
+ */
705
+ private parkedAnchors;
706
+ /** `tuneOut.announce`: the excepted channel hears the all-except scope open and close. */
707
+ private tuneOutAnnounce;
708
+ /** `speech.locus`: where prose goes when nothing names a destination (see FrameworkConfig). */
709
+ private speechLocus;
710
+ /** `subconscious.reader: 'forks'`: the reader is a succession of forks (Dendrite). */
711
+ private readerForks;
712
+ private readerForkCounter;
591
713
  /** Agents an abandon could not cancel (token held, no stream) — surfaced
592
714
  * in HostModeStatus until the next quiesce/resume. */
593
715
  private lastUnabandonable;
@@ -605,6 +727,24 @@ export declare class AgentFramework {
605
727
  /** True once the cap has been met in the current run, so its line is
606
728
  * logged once a run, whatever began the run. */
607
729
  private deferredWritesCapLogged;
730
+ /** The agent registry and its ended log, as recovery files beside the store
731
+ * (nissa's #546 finding 3): Chronicle state follows the store's branch, and
732
+ * an undo or an operator's surgery must not erase a result held for
733
+ * delivery or the record of work that ran. The file wins where it exists;
734
+ * the branch-local state is read only for stores that predate it. */
735
+ private agentRegistryPath;
736
+ private agentRegistryEndedPath;
737
+ /** The ended log as the recovery file keeps it: the newest records, bounded. */
738
+ private endedRecovery;
739
+ /** The branch-local ended log by name (its newest entry for each), and how far it is indexed (findEndedAgentRecord). */
740
+ private readonly endedLogIndex;
741
+ /** The ended log's entries by the namespace their context holds (the latest for each). */
742
+ private readonly endedLogNamespaceIndex;
743
+ /** Namespaces this process opened for an ephemeral agent's context, by owner: candidates not yet registered included. */
744
+ private readonly namespaceOwners;
745
+ private endedLogIndexed;
746
+ /** The last indexed entry's mark, so a log that changed under the index is seen. */
747
+ private endedLogTail;
608
748
  /** Branch-independent recovery files (see FrameworkConfig.hostModePath /
609
749
  * deferredWritesPath). Undefined → branch-local slot fallback. */
610
750
  private hostModePath;
@@ -734,12 +874,27 @@ export declare class AgentFramework {
734
874
  private coalescingSnapshotDirty;
735
875
  private coalescingRecentReceipts;
736
876
  /**
737
- * Agents that read the residents' shared un-namespaced message slot: every
738
- * ordinary resident (their context managers are not isolated) and the
739
- * subconscious (isolated, but merging that slot read-only). A message in
740
- * that slot is unread only if NONE of them has compiled past it. Forks and
741
- * ephemeral agents have isolated slots and are their own only readers.
742
- */
877
+ * Dendrite agent registry — every agent this framework runs, with its
878
+ * roles, lifetime and relationships. `agents` stays the map of live Agent
879
+ * OBJECTS (the generation identity streams are checked against); the
880
+ * registry is what says what each of them is for. Selection sites read
881
+ * roles from here instead of excluding kinds by hand.
882
+ */
883
+ private readonly registry;
884
+ /** Tell the first adoption candidate when task work is orphaned (config.dendrite.announceOrphans). */
885
+ private announceOrphans;
886
+ /**
887
+ * After this many derivations of one kind from one agent, that agent hears
888
+ * a count line every so many instead of a line per fork
889
+ * (config.dendrite.collapseDerivationNoticesAfter; 0 = never collapse).
890
+ */
891
+ private collapseDerivationNoticesAfter;
892
+ /** The host's say over each derivation, ephemeral spawn and resume (config.dendrite.beforeDerive). */
893
+ private beforeDerive?;
894
+ /** What a source is told of a derivation (config.dendrite.derivationNotice); absent, the default line. */
895
+ private derivationNoticeHook?;
896
+ /** Per source agent, per kind: how many derivations, since when, and at which count the last note went. */
897
+ private derivationTallies;
743
898
  private readonly sharedSlotAgents;
744
899
  /** The batched-wake lines already written (placeWakeLines), so every agent a
745
900
  * wake was for, and every later start of it, writes each at most once. */
@@ -748,6 +903,7 @@ export declare class AgentFramework {
748
903
  * in the round counted by their share of the bound: such a round is
749
904
  * stored by its share whether or not it fits (buildStoredToolResultContent). */
750
905
  private readonly toolRoundsByShare;
906
+ /** Group commit: one fsync per event-loop turn, shared by every waiter. */
751
907
  /** The windows of forks and runs deregistered while the host was quiesced,
752
908
  * by agent name (releaseWindowNowOrAfterResume); resume() releases them
753
909
  * (runReleasesAfterResume), or stop() passes on what they left, unread or
@@ -756,8 +912,10 @@ export declare class AgentFramework {
756
912
  private readonly releasesAfterResume;
757
913
  private readonly managerReleases;
758
914
  private readonly releasedByCleanup;
915
+ private readonly resumesPending;
759
916
  private readonly openManagers;
760
917
  private readonly openManagerRefs;
918
+ private readonly storeSees;
761
919
  private readonly collectedManagers;
762
920
  /** The coalescing commit in flight, if any (see commitCoalescingDurable). */
763
921
  private coalescingCommit;
@@ -768,19 +926,13 @@ export declare class AgentFramework {
768
926
  private conversationRouter;
769
927
  /** Agent configs by name — fork agents are built from the template's config. */
770
928
  private agentConfigs;
771
- /**
772
- * Fork agent → its home channel. Permanent (unlike router bindings, which
773
- * expire): publish/injection scoping must survive unbinding so the closure
774
- * turn still lands in the right channel.
775
- */
776
- private conversationAgentHomes;
777
929
  /** Forks being spawned, by channel id, each until its spawn settles (see
778
930
  * routeConversation). The promise never rejects. */
779
931
  private readonly conversationSpawns;
780
932
  /** Last idle-TTL sweep timestamp. */
781
933
  private lastConversationSweep;
782
934
  /** Forks whose TTL closure turn has been queued — disposed (removed from
783
- * agents/agentConfigs/conversationAgentHomes) when their stream ends. */
935
+ * agents/agentConfigs and ended in the registry) when their stream ends. */
784
936
  private closingConversationAgents;
785
937
  private codeExecution;
786
938
  private scriptToolWaiters;
@@ -882,10 +1034,15 @@ export declare class AgentFramework {
882
1034
  /** Host capabilities advertised during the MCP handshake — stored so servers
883
1035
  * can be connected at runtime (connectMcplServer) after initialization. */
884
1036
  private mcplHostCapabilities;
885
- /** MCPL RFC-014: every toolHints server's tool presence, for the
1037
+ /** MCPL RFC-014: every hinted server's tool presence, for the
886
1038
  * `toolsets` module's meta-tools and reminders. Made when the first
887
- * server configured with `toolHints: true` is set up; null until then. */
1039
+ * server with tool hints (any not configured `toolHints: false`) is set
1040
+ * up; null until then. */
888
1041
  private toolsetHub;
1042
+ /** The host's own toolsets: the built-in "settings" and MCPL server tabs. */
1043
+ private hostPresentation;
1044
+ /** MCPL servers kept disconnected as closed tabs, with the configuration an open connects them with. */
1045
+ private closedTabConfigMap?;
889
1046
  /** Inference routing policy from FrameworkConfig — stored so the MCPL
890
1047
  * subsystem can be lazily initialized by connectMcplServer when the
891
1048
  * framework started with zero configured servers. */
@@ -1118,8 +1275,32 @@ export declare class AgentFramework {
1118
1275
  * them beside the gate's own timers, so it can weigh what waiting costs.
1119
1276
  */
1120
1277
  private upcomingWakesFor;
1278
+ /**
1279
+ * The heartbeat's ticks and reminders for `agentName`, soonest first, which
1280
+ * the agent's rules decide as they decide a heartbeat push: one the rules
1281
+ * would hold back is only a "maybe" (`certain` false). Each is probed as
1282
+ * the event its delivery is judged by (deliverHeartbeat): a silent tick as
1283
+ * silent, with the text it will bring, so a rule on the content or the
1284
+ * silent flag decides the probe as it will decide the wake. None for an
1285
+ * agent the heartbeat doesn't wake. `whose` words them for the judge ("its
1286
+ * heartbeat") or for the agent ("your heartbeat").
1287
+ */
1288
+ private heartbeatWakesFor;
1289
+ /**
1290
+ * The heartbeat's wake due before a self-wake due at `selfWakeAt` (ms), for
1291
+ * the skip_reply that armed it: the soonest of its ticks and reminders that
1292
+ * the agent's rules, as they stand, let wake it. The confirmation says when
1293
+ * it's due, not that it will wake the agent (skipReplyNote), so a probe
1294
+ * that can't foresee the gate at the wake's time (a gate.js, a rate limit's
1295
+ * tokens then) leaves it true. A failure here costs only that line: the
1296
+ * self-wake is armed already, and the confirmation goes out without it.
1297
+ */
1298
+ private heartbeatWakeBefore;
1121
1299
  /** The agents the heartbeat wakes: the residents, not conversation forks,
1122
- * ephemeral runs or the subconscious, which keep windows of their own. */
1300
+ * ephemeral runs or the subconscious, which keep windows of their own.
1301
+ * Read from the registry by role, as an untargeted push's recipients are
1302
+ * (the heartbeat's wakes were heartbeat-mcpl's pushes): the agents whose
1303
+ * spec takes untargeted inbound, in registration order. */
1123
1304
  private heartbeatTargets;
1124
1305
  /**
1125
1306
  * The event a heartbeat wake is to the gate: a push from the server id
@@ -1209,6 +1390,7 @@ export declare class AgentFramework {
1209
1390
  * inference on it. True = extended in place (held requests stay held). */
1210
1391
  private extendHostProviderHold;
1211
1392
  private holdProviderAcceleration;
1393
+ private rearmExhaustedTurn;
1212
1394
  /**
1213
1395
  * A provider's stated wait on a turn that doesn't own provider admission:
1214
1396
  * a conversation agent's or an ephemeral run's. Left to the error policy,
@@ -1258,6 +1440,9 @@ export declare class AgentFramework {
1258
1440
  * ops alert.
1259
1441
  */
1260
1442
  private recordProviderWait;
1443
+ private noteStatedWaitRun;
1444
+ private alertStatedWaitRun;
1445
+ private endStatedWaitRun;
1261
1446
  /**
1262
1447
  * Hold this agent's primary turns for a provider wait on its model. The
1263
1448
  * requests are kept and released together, into one fresh compile, when
@@ -1365,7 +1550,9 @@ export declare class AgentFramework {
1365
1550
  /**
1366
1551
  * Add a trace event listener for observability.
1367
1552
  */
1368
- onTrace(listener: TraceEventListener): () => void;
1553
+ onTrace(listener: TraceEventListener, options?: {
1554
+ replay?: boolean;
1555
+ }): () => void;
1369
1556
  /**
1370
1557
  * Public accessor for the MCPL channel registry.
1371
1558
  * Null when no MCPL servers are configured.
@@ -1612,7 +1799,6 @@ export declare class AgentFramework {
1612
1799
  private buildThinkTool;
1613
1800
  /** agent_settings tool definition with module extension fields merged in. */
1614
1801
  private buildAgentSettingsTool;
1615
- private warnEmptyUtilityPermissions;
1616
1802
  private getToolsForAgent;
1617
1803
  /** Available is independent of presentation visibility; execution callers keep this surface. */
1618
1804
  private availableToolsForPresentation;
@@ -1744,8 +1930,10 @@ export declare class AgentFramework {
1744
1930
  * CURRENT settings — maintenance may have moved the folded floor and the
1745
1931
  * branch generation, so verdicts are computed at resume time, never reused.
1746
1932
  * Throws ResumeBlockedError (with all failing verdicts) unless `force`.
1747
- * Unavailable previews warn and pass — refusing to resume because the
1748
- * strategy cannot preview would hold hosts hostage to a diagnostic.
1933
+ * Unavailable previews pass, with a warning naming the reason unless it is
1934
+ * `no_preview_support`, a strategy with nothing to preview — refusing to
1935
+ * resume because the strategy cannot preview would hold hosts hostage to a
1936
+ * diagnostic.
1749
1937
  */
1750
1938
  resume(opts?: {
1751
1939
  force?: boolean;
@@ -1993,7 +2181,13 @@ export declare class AgentFramework {
1993
2181
  * see `AutobiographicalStrategy.previewContext` and
1994
2182
  * `Agent.compileWithInjections`.
1995
2183
  *
1996
- * Returns null when the agent's strategy has no fold plan (non-adaptive).
2184
+ * Returns null when the agent's strategy has nothing to preview: one without
2185
+ * `previewContext`, or a non-adaptive `AutobiographicalStrategy` whose select
2186
+ * fits the budget, built from the framework's own copy of context-manager.
2187
+ * Built from another copy, such a strategy throws its `previewContext
2188
+ * requires adaptiveResolution` error here instead, since the manager
2189
+ * recognises only its own copy's `NoFoldPlanToPreviewError`. Over the
2190
+ * budget, a non-adaptive strategy's preview is an infeasible one.
1997
2191
  */
1998
2192
  previewContextSettings(agentName: string, budgetTokens: number, overrides?: Record<string, unknown>, opts?: {
1999
2193
  render?: boolean;
@@ -2014,9 +2208,9 @@ export declare class AgentFramework {
2014
2208
  *
2015
2209
  * Never throws for preview-layer reasons: strategy without previewContext,
2016
2210
  * preview overlap, stale branch generation, the hierarchical (non-
2017
- * adaptive) path, and a context manager that refuses its queries (its
2018
- * strategy's initialization pending or failed) all come back as
2019
- * `{available: false, reason}`. Unknown agent still throws, matching the
2211
+ * adaptive) path within its budget, and a context manager that refuses its
2212
+ * queries (its strategy's initialization pending or failed) all come back
2213
+ * as `{available: false, reason}`. Unknown agent still throws, matching the
2020
2214
  * sibling accessors, and so does a patch whose values the agent refuses,
2021
2215
  * whatever its context manager's state. Whether the strategy takes live
2022
2216
  * tail and pace settings is the manager's to say, so while it refuses, a
@@ -2201,11 +2395,334 @@ export declare class AgentFramework {
2201
2395
  * ContextManager, before the store. Until then the ContextManager stays
2202
2396
  * open.
2203
2397
  */
2204
- createEphemeralAgent(config: AgentConfig): Promise<{
2398
+ createEphemeralAgent(config: AgentConfig,
2399
+ /**
2400
+ * How the registry should describe this agent. Omitted: an independent
2401
+ * fresh worker with no spawner and no result route, which is what every
2402
+ * caller of this method got before the registry existed. Supplying a
2403
+ * spec (see the presets in `dendrite/`) declares who spawned it, where
2404
+ * its result goes and what it inherited, so lifecycle rules — orphan
2405
+ * notice, reparenting, held results — apply to it.
2406
+ */
2407
+ spec?: Omit<AgentSpec, 'name'>): Promise<{
2408
+ agent: Agent;
2409
+ contextManager: ContextManager;
2410
+ cleanup: () => void;
2411
+ }>;
2412
+ /**
2413
+ * Derive a new agent from a live one: the parent's context at a
2414
+ * checkpoint, a private continuation, and — unless overridden — the
2415
+ * parent's whole configuration (model, thinking, cache TTL, provider
2416
+ * params, prompt, tools). The parent keeps running.
2417
+ *
2418
+ * The returned agent is a bounded job, driven with
2419
+ * `runEphemeralToCompletion` exactly like one from `createEphemeralAgent`.
2420
+ *
2421
+ * **Inheritance.** `mode: 'shared'` (the default) gives the child the
2422
+ * parent's messages and fold state through shared storage: nothing is
2423
+ * copied, the child folds with the parent's memory tree, and neither can
2424
+ * alter what the other reads. It needs branch-bound store handles and is
2425
+ * refused, not silently downgraded, where they are missing. `mode: 'copy'`
2426
+ * is the historical mechanism — the parent's compiled context re-added as
2427
+ * the child's own messages — and works everywhere.
2428
+ *
2429
+ * **Rendering.** With `solve: 'reuse'` (the default) and nothing
2430
+ * overridden, the child's first request is the parent's request plus the
2431
+ * child's framing: the same system prompt and tool block, the parent's
2432
+ * turns presented as the child's own, and a cache marker on the end of
2433
+ * the parent's request so the prefix it wrote is read back. `solve:
2434
+ * 'fresh'` deliberately re-solves, e.g. at another budget; so does any
2435
+ * override that changes what is rendered. Those are operating choices —
2436
+ * the presentation changes and the provider cache misses.
2437
+ *
2438
+ * **Framing** is ordinary messages appended to the child before it runs:
2439
+ * the task, and whatever tells it which stream it is. The parent's turn
2440
+ * in flight is not in its store yet (see `getPendingAssistantRound`), so
2441
+ * a fork made from inside a tool call starts from the message before the
2442
+ * turn that made it.
2443
+ *
2444
+ * Context isolation is not process or filesystem isolation: parent and
2445
+ * child share tools, any shell and the workspace.
2446
+ */
2447
+ deriveAgent(options: DeriveAgentOptions): Promise<{
2448
+ agent: Agent;
2449
+ contextManager: ContextManager;
2450
+ cleanup: () => void;
2451
+ }>;
2452
+ private discardEphemeralCandidate;
2453
+ /**
2454
+ * The default wording for the call that derived a child: who it is, what
2455
+ * kind, and how long — the fields the consent event names, so the fork
2456
+ * never has to infer its own lifetime from context (Linn, 10-09).
2457
+ */
2458
+ private derivedNote;
2459
+ /**
2460
+ * The parent's in-flight tool round, reproduced on the child's branch so
2461
+ * the child sees the call that made it (see `DeriveAgentOptions.pendingRound`).
2462
+ */
2463
+ private framePendingRound;
2464
+ /**
2465
+ * The assistant turn an agent has produced but not yet stored: its tool
2466
+ * calls and any text before them, held until every tool result is in so
2467
+ * the pair lands adjacently. A host deriving an agent from inside one of
2468
+ * those tool calls can reproduce the turn in the child's framing.
2469
+ */
2470
+ getPendingAssistantRound(agentName: string): ContentBlock[] | undefined;
2471
+ /**
2472
+ * Bring an ended bounded job back as a new incarnation of the same
2473
+ * identity, on the context it left: an isolated agent's own namespace, or
2474
+ * a derived agent's own branch. Nothing is re-derived and nothing is
2475
+ * re-seeded — the agent continues from its last stored message, which is
2476
+ * the end of its last complete round (a round whose tool results never
2477
+ * all arrived was never stored).
2478
+ *
2479
+ * Use it for a job that was stopped, failed, or was interrupted by a
2480
+ * restart. Configuration is not persisted with an agent, so the caller
2481
+ * supplies it again; the role mapping a derived agent used is restored
2482
+ * from its record unless the config sets one. Relationships are kept
2483
+ * where the other agent still exists; a job whose spawner or result
2484
+ * recipient is gone resumes without that edge and can be reparented.
2485
+ *
2486
+ * External effects are not replayed and not undone: a tool the previous
2487
+ * incarnation ran before it ended has had its effect, and a call it never
2488
+ * received a result for may be made again by the model. Drive the result
2489
+ * with `runEphemeralToCompletion`.
2490
+ */
2491
+ resumeAgent(name: string, config: Omit<AgentConfig, 'name'>): Promise<{
2205
2492
  agent: Agent;
2206
2493
  contextManager: ContextManager;
2207
2494
  cleanup: () => void;
2208
2495
  }>;
2496
+ /**
2497
+ * A context to read an agent's history from, without changing the live
2498
+ * system.
2499
+ *
2500
+ * - A live agent: a snapshot derived from its context — at the head, or
2501
+ * at `atSequence` for an earlier state. The snapshot is its own branch;
2502
+ * the agent keeps running and is not affected by anything done to it.
2503
+ * - An ended agent: the context it left, reopened where it lives.
2504
+ *
2505
+ * The returned manager uses a passthrough strategy: it shows what is
2506
+ * stored, raw. An ended agent's context is the real one — treat it as
2507
+ * read-only unless you mean to change what a later resume starts from.
2508
+ */
2509
+ inspectAgentContext(name: string, options?: {
2510
+ atSequence?: number;
2511
+ }): Promise<ContextManager>;
2512
+ /** Open the context an ended agent left, wherever it lives. */
2513
+ private reopenAgentContext;
2514
+ /** Open a derived agent's context on a branch of its own (see deriveAgent). */
2515
+ private deriveSharedContext;
2516
+ /** Flat list of registered agents with their roles, lifetime and relationships. */
2517
+ listAgents(options?: {
2518
+ includeEnded?: boolean;
2519
+ }): AgentRecord[];
2520
+ /** One agent's record: the live one, else its most recent ended one. */
2521
+ getAgentRecord(name: string): AgentRecord | null;
2522
+ /** The agent that owns default delivery, or null before any is declared. */
2523
+ getPrimaryAgentName(): string | null;
2524
+ /**
2525
+ * Activations in flight, each with the agent that owns the work. Derived
2526
+ * from the live turn state, so it cannot disagree with what is running.
2527
+ */
2528
+ listActivations(): ActivationRecord[];
2529
+ /**
2530
+ * Policy epochs currently in force (tune-out holds), read from the
2531
+ * coordinator's own durable state — not mirrored. An epoch is neither an
2532
+ * agent nor a task: ending one leaves both running.
2533
+ */
2534
+ listPolicyEpochs(): PolicyEpoch[];
2535
+ /**
2536
+ * Cancel an agent's activation in flight, leaving the agent registered.
2537
+ * For a bounded job, whose lifetime is that one run, this ends the job.
2538
+ * Returns false when nothing was running.
2539
+ */
2540
+ cancelActivation(name: string, options?: {
2541
+ by?: string;
2542
+ reason?: string;
2543
+ }): boolean;
2544
+ /**
2545
+ * End an agent: cancel its run, remove it from the framework, and settle
2546
+ * what it spawned — attention tenants end with it; task work is orphaned,
2547
+ * notified and offered for reparenting, and keeps running.
2548
+ *
2549
+ * The default-delivery owner cannot be stopped (the framework needs
2550
+ * exactly one); cancel its activation instead. A persistent agent stopped
2551
+ * here is declared by configuration and returns at the next boot.
2552
+ */
2553
+ stopAgent(name: string, options?: {
2554
+ by?: string;
2555
+ reason?: string;
2556
+ }): EndOutcome;
2557
+ /**
2558
+ * Give an agent a new parent. Clears its orphan state; a result route
2559
+ * whose recipient is gone follows the new parent, and the mail it already
2560
+ * produced for the lost recipient, results and messages, is delivered to
2561
+ * the new one.
2562
+ */
2563
+ reparentAgent(name: string, newParent: string, options?: {
2564
+ by?: string;
2565
+ }): AgentRecord;
2566
+ /**
2567
+ * An explicit message from one agent to another: the sender's verbatim
2568
+ * content, in the recipient's context under the SENDER's name, with the
2569
+ * sender's identity and incarnation and the causal chain in metadata.
2570
+ * Never an unmarked insertion into the recipient's own voice.
2571
+ */
2572
+ sendAgentMessage(from: string, to: string, content: ContentBlock[], options?: {
2573
+ causedBy?: string[];
2574
+ wake?: boolean;
2575
+ }): {
2576
+ mailId: string;
2577
+ delivered: boolean;
2578
+ };
2579
+ /**
2580
+ * Return a bounded job's result along the agent's declared result route.
2581
+ * The result is recorded durably before delivery is attempted, so it is
2582
+ * neither lost nor delivered twice across a restart; if the recipient is
2583
+ * gone it is held as attributed mail until the agent is reparented.
2584
+ *
2585
+ * May be called after the agent's run has ended — its record stays
2586
+ * inspectable. Refused for a `tool-result` route: there the awaiting
2587
+ * caller already holds the result and delivers it itself.
2588
+ */
2589
+ deliverAgentResult(from: string, content: ContentBlock[], options?: {
2590
+ causedBy?: string[];
2591
+ }): {
2592
+ mailId: string;
2593
+ delivered: boolean;
2594
+ to: string;
2595
+ };
2596
+ /** Communications not yet handed to their recipient, and why. */
2597
+ listHeldMail(filter?: {
2598
+ to?: string;
2599
+ from?: string;
2600
+ }): HeldMail[];
2601
+ /**
2602
+ * Try to hand one held item to its recipient. True when the message is in
2603
+ * (or queued for) the recipient's context; false when it stays held
2604
+ * because nobody can receive it. The held copy is released by
2605
+ * `addMessage` at the moment the message enters the store.
2606
+ */
2607
+ private attemptMailDelivery;
2608
+ /**
2609
+ * An ended orphan's result held for a recipient that is gone: its first
2610
+ * adoption candidate is told it exists and how it arrives, since nothing
2611
+ * else would surface it (reparentAgent delivers it).
2612
+ */
2613
+ private tellResultHeld;
2614
+ /** A host-framed lifecycle fact in an agent's context. Never voiced as anyone. */
2615
+ private lifecycleNotice;
2616
+ /**
2617
+ * The creation ("consent") event: names what kind of agent this is, what
2618
+ * ends it and what happens to it when its spawner ends. A derived agent's
2619
+ * creation is also told to the agent it was derived from (#270, Linn:
2620
+ * "told when the body changes" as a property, not a courtesy): one
2621
+ * host-framed line in the source's context, built from the same facts as
2622
+ * the trace, with no wake; a host's derivationNotice can replace the line
2623
+ * or send none. Both derivation paths announce after the
2624
+ * fork's branch or copy exists, so a fork never inherits the notice about
2625
+ * itself; a source that has ended is told nothing (lifecycleNotice).
2626
+ */
2627
+ private announceAgentCreated;
2628
+ /** The derivation notice's text, addressed to the agent `from` the record was derived. */
2629
+ private derivationNotice;
2630
+ /** What a derived agent is, to the agent it was derived from: "a task-fork on your weights, …; …; …". */
2631
+ private derivationDescription;
2632
+ /**
2633
+ * Remove an ended agent's live object from the framework. A bounded run
2634
+ * is ended through its awaiting caller (whose teardown owns the
2635
+ * name-keyed state); any other agent is torn down here.
2636
+ */
2637
+ private teardownEndedAgent;
2638
+ /**
2639
+ * Everything the process holds for a live, non-ephemeral agent that has
2640
+ * ended, released once, on every path an agent ends by — stopAgent, the
2641
+ * idle reap of a conversation fork, an end that cascades from a parent's
2642
+ * (nissa's #546 finding 5: a stop that skipped the window release dropped a
2643
+ * write queued for the agent at the next flush, and a failure notice it
2644
+ * never read reached no one). The window release delivers what the agent
2645
+ * never read to the primary, now or after a resume, as the idle reap did.
2646
+ */
2647
+ private releaseAgentRuntime;
2648
+ /**
2649
+ * Carry out what the registry decided when an agent ended: tear down the
2650
+ * attention tenants that end with it, and tell each orphan — and the
2651
+ * first agent that could adopt it — what happened.
2652
+ */
2653
+ private settleEndedAgent;
2654
+ /** An agent whose spawner has ended, and its first adoption candidate, are told; the trace says so. */
2655
+ private announceOrphaned;
2656
+ /** The registry's snapshot: the recovery file first (atomic, fsynced; it
2657
+ * wins at the next boot), then the branch-local state, kept for inspection
2658
+ * and for stores read by older code. Either write failing fails the call
2659
+ * that changed the registry (nissa's #546 finding 2): a change that isn't
2660
+ * durable isn't a success. */
2661
+ private persistAgentRegistry;
2662
+ /** An ended record: appended to the branch-local log, and the recovery
2663
+ * file rewritten with the newest records (as many as a restart reads). */
2664
+ private appendEndedAgentRecord;
2665
+ /**
2666
+ * A requested change was put back in the registry's memory: the recovery
2667
+ * files, each written before the branch-local store, are rewritten from it
2668
+ * (the snapshot's and the ended log's), so neither keeps the change the
2669
+ * caller was told failed. The branch-local snapshot needs no rewrite: it is
2670
+ * the last write a change makes, so a change that failed never reached it.
2671
+ * The branch-local ended log is append-only, so an end appended before the
2672
+ * failure stays there. It is read at boot only where no ended recovery
2673
+ * file exists (or the rewrite of that file failed too); the restore then
2674
+ * drops a bounded agent it lists as ended for the reason recorded, with no
2675
+ * restart notice to its recipient, while a persistent agent waits to be
2676
+ * re-declared as it would anyway. A rewrite that fails is reported, the
2677
+ * next is still made, and the caller's own error goes on.
2678
+ */
2679
+ private rewriteAgentRegistryAfterRollback;
2680
+ /**
2681
+ * An ended record past the registry's memory, from the branch-local ended
2682
+ * log. A scan of the whole log takes tens of milliseconds at a few thousand
2683
+ * ends, and a name nobody used (a tool call's typo) is a miss, so the log is
2684
+ * indexed by name once, at the first lookup, and each later lookup indexes
2685
+ * only what was appended since. A log that changed under the index (a
2686
+ * branch switch) is indexed again: one that shrank, one whose last indexed
2687
+ * entry is no longer the one indexed, or one whose entry no longer carries
2688
+ * the name indexed for it.
2689
+ */
2690
+ private findEndedAgentRecord;
2691
+ /**
2692
+ * The ended log's latest record whose own context a namespace holds. A
2693
+ * shared fork's record names its parent's namespace, where it owns only a
2694
+ * branch, so it is indexed by name alone.
2695
+ */
2696
+ private findInEndedLog;
2697
+ /** Another agent whose context a namespace holds: opened in this process, in the registry, or in the ended log. */
2698
+ private namespaceHolder;
2699
+ /** The ended log's recovery file, rewritten as the newest records (as many as a restart reads). */
2700
+ private rewriteEndedRecovery;
2701
+ /**
2702
+ * Load the previous process's registry. Returns the bounded work it
2703
+ * interrupted. A registry that can't be read, or that reads as anything
2704
+ * but a version-1 registry, refuses the start and names the state (nissa's
2705
+ * #546 finding 1, main's rule for the framework's own state): taken as
2706
+ * empty, the results it holds for delivery and the records of the work it
2707
+ * ran would be overwritten by this boot's first registration.
2708
+ */
2709
+ private restoreAgentRegistry;
2710
+ /**
2711
+ * Boot reconciliation, once configuration has declared its agents.
2712
+ * Restart behaviour follows from lifetime: persistent agents were just
2713
+ * re-created; everything else that was live was interrupted, and the
2714
+ * recipient of an interrupted job's result is told so. Results held from
2715
+ * before the restart are delivered now, exactly once.
2716
+ */
2717
+ private reconcileAgentRegistry;
2718
+ /**
2719
+ * Deliver held mail that hasn't landed. Its copy may have reached the
2720
+ * recipient's store in the same sync that the release missed, and then it
2721
+ * is released instead; and a write the deferred queue still holds for it
2722
+ * lands at the next flush and releases it then (releaseLandedMail). Either
2723
+ * way a second delivery would put it in the window twice under one mail id.
2724
+ */
2725
+ private deliverHeldMail;
2209
2726
  private createDeferred;
2210
2727
  /** Liveness ping for an active ephemeral run (no-op otherwise). */
2211
2728
  private touchEphemeralRun;
@@ -2263,6 +2780,8 @@ export declare class AgentFramework {
2263
2780
  /** Tune-out (issue #77): divert a channel to your subconscious. Present
2264
2781
  * only when the subconscious resident is configured. */
2265
2782
  private static readonly TUNE_OUT_TOOL;
2783
+ /** `focus`: the resident-facing alias for `tune_out` with scope "all-except" (#232 decision 2). */
2784
+ private static readonly FOCUS_TOOL;
2266
2785
  /** Synthesized sleep/wake tool definitions (present when a gate is wired). */
2267
2786
  private static readonly SLEEP_TOOLS;
2268
2787
  /** Synthesized wake-rule tools: add/remove a gate.json policy at runtime.
@@ -2823,6 +3342,28 @@ export declare class AgentFramework {
2823
3342
  * into the resident's window, which accumulates there.
2824
3343
  */
2825
3344
  private createSubconsciousAgent;
3345
+ /**
3346
+ * `subconscious.reader: 'forks'`: no persistent agent. The coordinator
3347
+ * asks for a fork per invocation (see invokeReaderFork); the config is
3348
+ * kept for the voice block, the speech switch and the strategy factory.
3349
+ */
3350
+ private configureReaderForks;
3351
+ /**
3352
+ * One reader invocation: derive a fork of the resident at its head with
3353
+ * the resident's refusals, hand it the held traffic since the last look
3354
+ * as ordinary framing, and run it. It reports through `deliver_summary`
3355
+ * (attributed mail), may cancel the hold, and ends when its turn ends.
3356
+ */
3357
+ private invokeReaderFork;
3358
+ /**
3359
+ * Held messages still queued behind the resident's turn, as rows of a
3360
+ * reader fork's backlog: each named by its held handle, as module rows name
3361
+ * it until it lands (heldRows), at a provisional sequence past the
3362
+ * resident's last stored message, and timed when it was first held.
3363
+ */
3364
+ private queuedReaderRows;
3365
+ /** A reader fork's own words to the resident: attributed mail when it has a route, else under its name. */
3366
+ private deliverFromReader;
2826
3367
  private runLoop;
2827
3368
  private processNextEvent;
2828
3369
  private handleProcessEvent;
@@ -2848,6 +3389,14 @@ export declare class AgentFramework {
2848
3389
  * Convert an incoming MCPL channel message to a context message.
2849
3390
  * This replaces the old MCPLModule.onProcess() message conversion.
2850
3391
  */
3392
+ /**
3393
+ * A delivered inbound message becomes the latest delivered inbound (the
3394
+ * channel context's reply anchor; the legacy speech fallback) through the
3395
+ * registry's noteDelivered — at once for a plain channels/incoming, whose
3396
+ * acceptance the registry answers synchronously; parked for a coalesced one
3397
+ * until its acceptance is acknowledged (see parkedAnchors).
3398
+ */
3399
+ private noteDeliveredOrPark;
2851
3400
  private handleMcplChannelIncoming;
2852
3401
  /**
2853
3402
  * Route an incoming channel message through the ConversationRouter:
@@ -2965,11 +3514,6 @@ export declare class AgentFramework {
2965
3514
  * explicit-prose agent's natural plain reply bounced with nowhere to go
2966
3515
  * (Rhys's first portal mention: a 2,320-char reply stranded).
2967
3516
  *
2968
- * Wording: option 1 teaches the `>>` destination prefix, which delivers for
2969
- * BOTH legacy (host-inferred) and explicit prose-routing agents. The
2970
- * previous "simply write your reply as normal text" was a false promise
2971
- * under explicit routing (the metadata flags it set had no consumers).
2972
- *
2973
3517
  * Human-readable names wherever the surface provided them — a mind reading
2974
3518
  * this should see WHO addressed it WHERE, not a wall of snowflake ids. Raw
2975
3519
  * ids remain only inside the tool-argument instructions, where they are the
@@ -3143,6 +3687,27 @@ export declare class AgentFramework {
3143
3687
  * channels answer to is never resolved to either.
3144
3688
  */
3145
3689
  private channelNamed;
3690
+ /**
3691
+ * A live agent's home channel, from its registry record (channelOfHome):
3692
+ * defined for a conversation fork, and only for one. Undefined for an agent
3693
+ * with none, and for one that has ended.
3694
+ */
3695
+ private homeOf;
3696
+ /**
3697
+ * The channel a registry record's `homeChannel` names: the channel on its
3698
+ * server. A bare channel id, as a record written before homes carried
3699
+ * their server keeps, is read as a wake that names its channel without its
3700
+ * server is (channelNamed): the one registered channel it names, read when
3701
+ * it's used, since the servers registered at that moment are what it can
3702
+ * mean. An id that names no one registered channel, as one no server
3703
+ * registers now or two servers do, is the home on no server (an empty
3704
+ * serverId, which channelNamed reads as none given), so the agent keeps a
3705
+ * home. A path that reads the pair finds no server registering it, and
3706
+ * refuses it; one that reads the name reads what the name means then: none
3707
+ * or two channels, which it refuses, or, once one server alone registers
3708
+ * the id, that server's channel.
3709
+ */
3710
+ private channelOfHome;
3146
3711
  /**
3147
3712
  * Explicit mode's typing channel for one start of a turn, which has no
3148
3713
  * locus, read once as the start opens (driveStream then shows what the
@@ -3183,6 +3748,23 @@ export declare class AgentFramework {
3183
3748
  * it takes their agent up (passRequests). */
3184
3749
  private processInferenceRequests;
3185
3750
  private runInferencePass;
3751
+ /**
3752
+ * `channel_publish` with no channel goes where the turn's plain speech
3753
+ * would: the frozen turn locus (the waking delivery's channel, or one
3754
+ * opened this turn), then the registry's own resolution. Under
3755
+ * `speech.locus: 'delivery'` the registry alone has no default, and the
3756
+ * tool failed on the very turn its own delivery woke (first live run,
3757
+ * 2026-10-12). Both dispatch paths — the stream driver's and
3758
+ * executeToolCall's — pass through here. Only a call made inside the turn
3759
+ * (callingTurnOf) takes the turn's locus: one made outside it, as a script
3760
+ * left running after its turn makes or a host's executeToolCall naming the
3761
+ * agent, takes none of the turn's channels. A conversation fork's home
3762
+ * isn't the turn's but the fork's own, so such a call from a fork naming
3763
+ * no channel still goes there (homeOf), as the fork's dispatched calls do
3764
+ * (dispatchChannelToolCall); anyone else's takes the registry's own
3765
+ * default.
3766
+ */
3767
+ private publishInputWithTurnLocus;
3186
3768
  /**
3187
3769
  * Stamps for the rows the agent's reply stores in its current turn: its
3188
3770
  * assistant responses, its tool_result rows (through `storeResults`), and
@@ -3333,6 +3915,21 @@ export declare class AgentFramework {
3333
3915
  /** Why a draft can't be resent now (dismissed, or possibly already posted
3334
3916
  * without the resident's confirmation), or undefined when it can. */
3335
3917
  private resendRefusal;
3918
+ /** Why a heartbeat's turn holds its plain speech, in a held-draft notice ("because …"). */
3919
+ private static readonly HEARTBEAT_HOLD_BECAUSE;
3920
+ /**
3921
+ * Locus mode's delivery of plain speech to the turn's frozen locus. A
3922
+ * heartbeat's turn with no locus of its own (TurnRouting.heartbeat) holds
3923
+ * the words as a draft instead of failing the delivery: nobody was waiting
3924
+ * for them, and the agent may send them where it chooses.
3925
+ */
3926
+ private routeLocusSpeech;
3927
+ /** The mark a framework wake takes from a heartbeat's turn with no locus
3928
+ * of its own (InferenceRequest.heartbeatTurn), so the turn it opens is a
3929
+ * heartbeat's too; nothing for any other turn. */
3930
+ private heartbeatTurnMark;
3931
+ /** Hold a heartbeat turn's plain speech as drafts ('no-destination'), named by `round`'s notice. */
3932
+ private holdHeartbeatProse;
3336
3933
  /** Record a successful plain-prose delivery for this turn's receipt. */
3337
3934
  private recordProseDelivery;
3338
3935
  /**
@@ -3362,14 +3959,27 @@ export declare class AgentFramework {
3362
3959
  * mid-turn. No-op otherwise.
3363
3960
  */
3364
3961
  private appendClosedChannelNoteAlone;
3962
+ /**
3963
+ * Tell a heartbeat's turn, before it compiles, that its plain speech has
3964
+ * no destination (TurnRouting.heartbeat): the last `[routing]` notice may
3965
+ * name a channel, and this turn's words won't go there. It leaves the
3966
+ * announced baseline alone (announceLocusIfChanged).
3967
+ */
3968
+ private noticeHeartbeatTurn;
3969
+ private rememberAnnouncedLocus;
3970
+ private forgetAnnouncedLocus;
3971
+ /** The stored baseline's entry for the agent set (rememberAnnouncedLocus),
3972
+ * or removed (undefined) when the agent ends without coming back. */
3973
+ private writeAnnouncedLocus;
3365
3974
  /**
3366
3975
  * Announce-on-change locus notice (turn-frozen routing). Appends a durable
3367
3976
  * `[routing]` window message when the turn's effective outbound locus
3368
3977
  * differs from the last one announced — the agent must never have to guess
3369
3978
  * where its plain prose lands. Durable append (never retracted) keeps the
3370
- * KV prefix stable; change-only keeps it out of steady-state turns. The
3371
- * first resolution after boot announces only a non-null locus ("prose has
3372
- * no destination" is the unremarkable boot default). Never triggers
3979
+ * KV prefix stable; change-only keeps it out of steady-state turns. An
3980
+ * agent never told of a locus, here or before a restart, hears only of a
3981
+ * non-null one ("prose has no destination" is the unremarkable start).
3982
+ * Never triggers
3373
3983
  * inference; never locus-eligible itself (system + no channel metadata).
3374
3984
  */
3375
3985
  private announceLocusIfChanged;
@@ -3381,7 +3991,11 @@ export declare class AgentFramework {
3381
3991
  * as the agent's first view) that addressed the agent, or that follows up
3382
3992
  * in a channel the turn sent into (TurnRouting.engaged). Undefined for any
3383
3993
  * other message. A tool boundary weighs the messages it injects by it,
3384
- * and noteArrival the ones no boundary of the turn weighs.
3994
+ * and noteArrival the ones no boundary of the turn weighs. The rule is
3995
+ * pure; what is done with its answer is `speech.locus`'s: under
3996
+ * `'latest-inbound'` the locus moves, under `'delivery'` (the default) the
3997
+ * agent is told it was addressed from elsewhere and the locus stays
3998
+ * (addressedElsewhereNotice).
3385
3999
  */
3386
4000
  private repinChannel;
3387
4001
  /** Whether `agent` has a turn alive: starting, streaming or waiting on its tools. */
@@ -3475,17 +4089,20 @@ export declare class AgentFramework {
3475
4089
  * more rows than that have come since the last clock; a window with no
3476
4090
  * clock row is read whole once, and then takes one (planClock). */
3477
4091
  private lastClockOf;
4092
+ private agentSees;
3478
4093
  /**
3479
4094
  * Weigh a message that no tool boundary of the agent's open logical turn
3480
4095
  * will weigh: one that would re-pin the locus becomes one of the turn's
3481
- * arrivals (TurnRouting.arrivals). A message tune-out diverted
3482
- * (metadata.tuneOut) never enters a resident's compiled view, so the agent
3483
- * won't see it, and it moves nothing.
4096
+ * arrivals (TurnRouting.arrivals). A message the agent's own view leaves
4097
+ * out (agentSees), such as one held from the residents (heldFromResidents,
4098
+ * the admission stage's one predicate, which every resident's view filter
4099
+ * reads) or another agent's stored context injection, never enters its
4100
+ * compiled view, so the agent won't see it, and it moves nothing.
3484
4101
  */
3485
4102
  private noteArrival;
3486
4103
  /**
3487
4104
  * Whether `agent`'s store is the residents' one message slot, which every
3488
- * ordinary resident reads (sharedSlotAgents). The subconscious reads that
4105
+ * ordinary resident reads (`readsSharedSlot` in the registry). The subconscious reads that
3489
4106
  * slot through a merged view, but its own store is isolated, as a fork's
3490
4107
  * or an ephemeral agent's is.
3491
4108
  */
@@ -3526,6 +4143,23 @@ export declare class AgentFramework {
3526
4143
  * so the agent's next turn announces where its speech lands.
3527
4144
  */
3528
4145
  private repinTurnLocus;
4146
+ /**
4147
+ * Under `speech.locus: 'delivery'`: tell the agent that someone addressed
4148
+ * it from another channel while its turn was busy, since incoming traffic
4149
+ * never moves the locus and a neutral message carries nothing that names
4150
+ * its channel (first live run, 2026-10-12, finding C). Once per channel
4151
+ * per turn (TurnRouting.addressedElsewhere); nothing for the turn's own
4152
+ * locus. Stored durably; returned as stored for a live stream to inject
4153
+ * with its boundary's other messages. Undefined when nothing was stored.
4154
+ */
4155
+ private addressedElsewhereNotice;
4156
+ /**
4157
+ * The arrivals a start of the turn consumes under `speech.locus:
4158
+ * 'delivery'`: each one that addressed the agent, whose message is still
4159
+ * in the store, gets the addressed-elsewhere notice, oldest first. A
4160
+ * follow-up in an engaged channel addressed nobody and is not announced.
4161
+ */
4162
+ private noticeAddressedArrivals;
3529
4163
  /**
3530
4164
  * Durable window notice for a channel the agent did not ask to open: a
3531
4165
  * subscription-policy admission, announced as the decision before its
@@ -3975,10 +4609,11 @@ export declare class AgentFramework {
3975
4609
  * exists only through the private closure handed to ModuleRegistry
3976
4610
  * (ctx.callTool → executeToolCallFrom with {kind:'module'}), which is exempt
3977
4611
  * from agent allowlists. Registered agents' allowedTools is enforced at
3978
- * dispatch, including namespaced utility names; utils only grants the
3979
- * list/describe/run slot. Genuinely unidentified public callers (including
3980
- * unknown legacy names) remain unrestricted. Framework-created identities
3981
- * are refused while unregistered, even if their configured list allows it.
4612
+ * dispatch, including namespaced utility names. Genuinely unidentified public callers (including
4613
+ * unknown legacy names) remain unrestricted. A name the framework made in
4614
+ * this process is refused while it isn't registered, even if its configured
4615
+ * list allows the tool; after a restart, such a name is a host's caller name
4616
+ * like any other.
3982
4617
  */
3983
4618
  executeToolCall(call: ToolCall): Promise<ToolResult>;
3984
4619
  /**
@@ -4043,6 +4678,33 @@ export declare class AgentFramework {
4043
4678
  * tool it makes, under that tool's model-facing name and with its
4044
4679
  * arguments, its id kept; or the reason it can't be sent. */
4045
4680
  private resolveToolsetAct;
4681
+ /**
4682
+ * A reader reads and reports: a reader fork (registry kind
4683
+ * 'subconscious-fork', in every incarnation) may call only its own tools,
4684
+ * and speak_in_channel where allowChannelSpeech allows it. Every other
4685
+ * tool the resident has stays in its block (the shared prefix) and is
4686
+ * refused here, so with speech off a fork can post nowhere (scout's
4687
+ * condition, 2026-10-19). It's decided at each call from what the reader
4688
+ * may call, not from what it is shown, so a tool added or moved out of
4689
+ * the block later is refused too.
4690
+ */
4691
+ private readerRefuses;
4692
+ /**
4693
+ * What a reader fork may call: exactly its own tools and the speech its
4694
+ * configuration allows, never widened or narrowed by its resident's
4695
+ * allowedTools. The resident's list bounds the resident's own surface;
4696
+ * the reader's tools are the framework's, for reading on its behalf. A
4697
+ * denyToolsAtDispatch entry the fork takes from its resident that names
4698
+ * one of them still refuses it (mayCallTool checks the deny first): a
4699
+ * resident never holds a reader tool, so such an entry is about readers.
4700
+ * The fork still shows its resident's block (the shared prefix): what it
4701
+ * may call is decided here, at each call, apart from what it is shown.
4702
+ */
4703
+ private readerMayCall;
4704
+ /** A toolsets--act call a host toolset resolved (HostPresentation.resolveAct):
4705
+ * its refusal answered, or the tool's own call dispatched in its place,
4706
+ * with the act's id, so its result is the act's. */
4707
+ private dispatchHostAct;
4046
4708
  /**
4047
4709
  * RFC-014 §8.2: a toolsets--act call from the agent (the model's, or a
4048
4710
  * script's) goes down the path a direct call of the server's tool takes
@@ -4388,9 +5050,15 @@ export declare class AgentFramework {
4388
5050
  * that. Never prefix-map insertion order.
4389
5051
  */
4390
5052
  private resolveMcplTool;
4391
- /** Registered policy; framework-created identities have no dispatch authority
4392
- * while unregistered. Genuine legacy caller names retain their surface. */
5053
+ /** Registered policy. Within this process, a name the framework made has no
5054
+ * dispatch authority while it isn't registered; after a restart, a host call names
5055
+ * its caller as any host call does. Genuine legacy caller names retain
5056
+ * their surface. */
4393
5057
  private canAgentUseTool;
5058
+ /** Whether a call of `toolName` as `agentName` is refused at dispatch (AgentConfig.denyToolsAtDispatch, or a reader's own rule). */
5059
+ private deniedAtDispatch;
5060
+ /** Whether `agentName` may call `toolName`: the one rule dispatch applies (agentToolPermissionFailure), for whatever else judges a call. */
5061
+ private mayCallTool;
4394
5062
  private agentToolPermissionFailure;
4395
5063
  private markedInputFailure;
4396
5064
  private cutOffResults;
@@ -4488,19 +5156,29 @@ export declare class AgentFramework {
4488
5156
  */
4489
5157
  private placeWakeLines;
4490
5158
  /** Whether `entry`'s own stored entry is the newest in `agent`'s window,
4491
- * clock rows and stored context injections after it aside: a channel
4492
- * message by its server, channel and message id, a push event by its
4493
- * server and event id, and never one a tune-out holds. Past
5159
+ * clock rows, stored context injections and rows the agent's own view
5160
+ * leaves out after it aside: a channel message by its server, channel and
5161
+ * message id, a push event by its server and event id, and never one the
5162
+ * agent's view leaves out, such as one a tune-out holds. Past
4494
5163
  * NEWEST_SCAN_ROWS such rows, it answers no. */
4495
5164
  private isNewestIn;
4496
5165
  /** Where addMessage delivers: the named agent, else the primary, else the
4497
5166
  * first registered agent. Undefined when there is no such agent. */
4498
5167
  private deliveryAgent;
5168
+ private noteSpokenTo;
4499
5169
  /** The notes addMessage takes for a message it stored: an arrival for the
4500
5170
  * agent when none of its turns is alive or the message was assembled for
4501
5171
  * the start now beginning (no tool boundary will weigh it), and one for
4502
5172
  * every other resident's open turn. */
4503
5173
  private noteStored;
5174
+ /**
5175
+ * Held agent mail is released only when its message has actually entered
5176
+ * the recipient's store — never on a deferral. Called at every site that
5177
+ * writes a message into a context: the direct path above and the two
5178
+ * deferred-write flushes (turn start, tool boundary). Both writes reach
5179
+ * disk in the same sync, so a crash keeps either both or neither.
5180
+ */
5181
+ private releaseLandedMail;
4504
5182
  /**
4505
5183
  * Splice out the deferred messages addressed to `agentName` (explicitly
4506
5184
  * via forAgent, or implicitly when it is the primary), leaving other
@@ -4938,7 +5616,7 @@ export declare class AgentFramework {
4938
5616
  * The writes the framework holds for the store `reader` reads, in queue
4939
5617
  * order: those addressed to it and, when it's an ordinary resident, those
4940
5618
  * addressed to any ordinary resident, since residents share one message
4941
- * slot (sharedSlotAgents). A write whose target is gone isn't among them:
5619
+ * slot (`readsSharedSlot` in the registry). A write whose target is gone isn't among them:
4942
5620
  * no module reads that agent's store, and the write waits for its window's
4943
5621
  * release (drainDeferredFor) or, at its flush, is dropped (addMessage), a
4944
5622
  * failed reply, or a channel notice its reader could act on, passing to the
@@ -5189,6 +5867,7 @@ export declare class AgentFramework {
5189
5867
  /** The restarts' claims (mcpRestartClaims), created on first use, as the
5190
5868
  * modern connections are. */
5191
5869
  private restartClaims;
5870
+ private closedTabConfigs;
5192
5871
  private legacyConnectAborts;
5193
5872
  /**
5194
5873
  * Hold a server id for one connect or disconnect, until `release()`.
@@ -5370,17 +6049,78 @@ export declare class AgentFramework {
5370
6049
  * logged here rather than replacing the failure the connect reports.
5371
6050
  */
5372
6051
  private closeFailedRuntimeConnect;
6052
+ /** RFC-014: who held the name `toolsets` at startup (a module given to
6053
+ * create(); a server's toolPrefix of it is refused), so a server that
6054
+ * leaves toolHints out has none for the life of this framework; null when
6055
+ * the name was free. */
6056
+ private toolsetsNameHeldAtStart;
6057
+ /** At startup: note who holds the name the meta-tools need, and say which
6058
+ * servers that leaves without hints. */
6059
+ private reserveToolsetsName;
6060
+ /**
6061
+ * RFC-014: whether a server has tool hints. Only an MCPL (legacy-family)
6062
+ * server can: a modern MCP server never has them. `true` and `false` are
6063
+ * as configured. Left out (or null) they're on, wherever the name
6064
+ * `toolsets` the meta-tools need is free: no other module holds it and no
6065
+ * server's prefix is it, now or at startup. So a configuration that loaded
6066
+ * when hints were opt-in still loads. A name held at startup stays held
6067
+ * for the framework's life.
6068
+ */
6069
+ private hintsFor;
5373
6070
  /**
5374
6071
  * The host capabilities offered to one server: the host's own, plus
5375
- * RFC-014's `toolHints` where its configuration asks for them. Without it,
5376
- * the very object every server is offered.
6072
+ * RFC-014's `toolHints` unless its configuration turns them off
6073
+ * (`toolHints: false`). With them off, the very object every server is
6074
+ * offered.
5377
6075
  */
5378
6076
  private mcplHostCapabilitiesFor;
5379
6077
  /** RFC-014: every toolHints server's presence, made on first use. */
5380
6078
  private toolsets;
5381
- /** RFC-014: the `toolsets` module (toolsets--open, --act, --look,
5382
- * --close), registered once, by the first server configured with
5383
- * toolHints. Its tools don't change after that. */
6079
+ /**
6080
+ * The host's own toolsets (host-presentation.ts): the built-in "settings"
6081
+ * toolset and each MCPL server's tab. State is kept beside the store, in
6082
+ * `config/toolsets.json`; with no store path, in memory only.
6083
+ */
6084
+ private makeHostPresentation;
6085
+ /** Whether a name is a module utility (and not a tool of its module, which takes the name). */
6086
+ private isModuleUtility;
6087
+ /** Whether an agent has the host's own toolsets: the meta-tools registered, and
6088
+ * usable by it (the subconscious keeps its own small surface). */
6089
+ /**
6090
+ * What a call of the removed `utils` is answered: where utilities went, as
6091
+ * this agent can reach them. One that can't use the built-in toolset is
6092
+ * told to call a utility by its own name and which ones it may call.
6093
+ */
6094
+ private utilsRemoved;
6095
+ private hostToolsetsFor;
6096
+ /**
6097
+ * Whether a host tool belongs to the built-in toolset: the framework's own
6098
+ * rarely-used ones (BUILTIN_TOOLSET_TOOLS), a module's that it places there
6099
+ * (Module.toolPlacement), and every module utility.
6100
+ */
6101
+ private placedInBuiltin;
6102
+ /**
6103
+ * The tool list an agent's requests carry, from the tools it may call: its
6104
+ * host presentation applied (the built-in toolset's tools, the servers it
6105
+ * has as tabs and its hidden tools left out; a utility never in it), as
6106
+ * every request of a registered agent has it (with its own tool
6107
+ * presentation, hidden tools and descriptions, applied first). For a stream that isn't
6108
+ * registered yet, such as a fork whose orientation is written before its
6109
+ * run starts, the host says whether it will be able to call
6110
+ * `toolsets--open` and `toolsets--act` (`canUseMeta`); left out, the agent
6111
+ * registered under that name is asked. Presentation it chose itself (open
6112
+ * toolsets, tabs) is read under that name, so a new name starts from the
6113
+ * configured presentation.
6114
+ */
6115
+ presentedTools(agentName: string, tools: import('./types/index.js').ToolDefinition[], canUseMeta?: boolean): import('./types/index.js').ToolDefinition[];
6116
+ /** The host presentation of a server's tools, for the tool list: the agent's
6117
+ * view, less the built-in toolset and the servers it has as tabs. */
6118
+ private headerTools;
6119
+ /** The `toolsets` module (toolsets--open, --act, --look, --close): the
6120
+ * meta-tools of the host's own toolsets and of RFC-014 servers' toolsets.
6121
+ * Registered once, at create(), unless a module given to create() holds
6122
+ * the name; a server with toolHints: true then can't have hints, and its
6123
+ * connect is refused here. Its tools don't change after that. */
5384
6124
  private ensureToolsetsModule;
5385
6125
  /** RFC-014 §5.3: after a (re)connect whose policy has settled, read what
5386
6126
  * the server holds open and adopt it. In the background: its notices are
@@ -5604,6 +6344,9 @@ export declare class AgentFramework {
5604
6344
  listMcplServers(): Array<{
5605
6345
  id: string;
5606
6346
  connected: boolean;
6347
+ /** Kept disconnected as a closed tab (host-presentation.ts) until an
6348
+ * agent's toolsets--open, an operator's connect or a restart connects it. */
6349
+ closedTab: boolean;
5607
6350
  retrying: boolean;
5608
6351
  /** Which engine serves it: `legacy` (MCP 2024-11-05 + MCPL) or `modern`
5609
6352
  * (MCP 2026-07-28), as its configuration selects; null when the
@@ -5809,6 +6552,15 @@ export declare class AgentFramework {
5809
6552
  * error and nothing is written.
5810
6553
  */
5811
6554
  private dispatchWakeRuleToolCall;
6555
+ /**
6556
+ * A reader's own tool (SUBCONSCIOUS_TOOL_NAMES), for both entries that run
6557
+ * an agent's call: the dispatcher's, for the model's call, and
6558
+ * executeToolCallFrom's, for a host's or the puppet's. The tools are
6559
+ * advertised to residents so reader forks share their prefix, and only a
6560
+ * registered reader may use them. A rejection is answered with a failed
6561
+ * result, never left unhandled.
6562
+ */
6563
+ private readerToolCall;
5812
6564
  /**
5813
6565
  * Handle the synthesized `sleep` / `wake` tools. `sleep` arms the gate's
5814
6566
  * suppression window, optionally announces in the sticky channel, and ends
@@ -5816,6 +6568,40 @@ export declare class AgentFramework {
5816
6568
  */
5817
6569
  /** tune_out tool (residents): enter or cancel a channel tune-out. */
5818
6570
  private dispatchTuneOutToolCall;
6571
+ /** `focus` is `tune_out` with scope "all-except". */
6572
+ private handleFocusTool;
6573
+ /**
6574
+ * A tune-out call's refusal for a channel it can't resolve: main's words
6575
+ * for a name no registered channel, and none of the calling turn's own,
6576
+ * answers to, and the registry's own otherwise, as for an id that is
6577
+ * ambiguous across servers (#232 gap 8).
6578
+ */
6579
+ private unknownChannelWords;
6580
+ /**
6581
+ * The tune_out tool's body. Channel resolution is server-qualified
6582
+ * (ChannelRegistry.resolveChannel): with a `serverId`, that server's
6583
+ * channel with the id; inside the calling turn, a name one of the turn's
6584
+ * own channels answers to by its id means that channel; otherwise the one
6585
+ * channel the name means, which may be server-qualified, and a name two
6586
+ * servers' channels answer to is refused with them as candidates (#232
6587
+ * gap 8). `turn` is the turn that made the call (callingTurnOf), the only
6588
+ * one whose speech an all-except entry moves.
6589
+ */
6590
+ private handleTuneOutTool;
6591
+ /**
6592
+ * The admission stage for one inbound event: the pure decision over the
6593
+ * framework's policy inputs (recipients, the hold in force, the wake
6594
+ * gate), traced. Callers apply it; nothing downstream re-asks.
6595
+ */
6596
+ private admitInbound;
6597
+ /**
6598
+ * Make delivered messages durable now, including those the delivery left
6599
+ * in the deferred queue: a tune-out release flips durable epoch state
6600
+ * first, so its dump must not be lost to a crash in between (#232 gap 6).
6601
+ */
6602
+ private commitDeliveries;
6603
+ /** The history-reading tool the primary resident actually has, if any (#232 gap 11). */
6604
+ private residentHistoryTool;
5819
6605
  private dispatchSleepToolCall;
5820
6606
  /**
5821
6607
  * Handle the synthesized `read_image` tool: read image bytes from a
@@ -5858,13 +6644,6 @@ export declare class AgentFramework {
5858
6644
  * authenticate bytes from another surface.
5859
6645
  */
5860
6646
  private dispatchSaveImageToolCall;
5861
- /** The `utils` meta-tool: list/describe/run over module utilities
5862
- * (Module.getUtilities). Shared by the model-facing dispatcher, which a
5863
- * running code_execution script's calls take too, and executeToolCallFrom,
5864
- * which the puppet and a host reach through executeToolCall and a module
5865
- * through callTool. */
5866
- private handleUtilsToolCall;
5867
- private dispatchUtilsToolCall;
5868
6647
  private readAgentSettings;
5869
6648
  private settingsChangedSince;
5870
6649
  private dispatchAgentSettingsToolCall;