@animalabs/agent-framework 0.22.3 → 0.23.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 (234) hide show
  1. package/README.md +105 -3
  2. package/dist/src/agent.d.ts +36 -10
  3. package/dist/src/agent.d.ts.map +1 -1
  4. package/dist/src/agent.js +76 -32
  5. package/dist/src/agent.js.map +1 -1
  6. package/dist/src/code-execution/index.d.ts +1 -1
  7. package/dist/src/code-execution/index.d.ts.map +1 -1
  8. package/dist/src/code-execution/index.js.map +1 -1
  9. package/dist/src/code-execution/py-runner.d.ts +34 -2
  10. package/dist/src/code-execution/py-runner.d.ts.map +1 -1
  11. package/dist/src/code-execution/py-runner.js +72 -16
  12. package/dist/src/code-execution/py-runner.js.map +1 -1
  13. package/dist/src/code-execution/runtime-py.d.ts +3 -2
  14. package/dist/src/code-execution/runtime-py.d.ts.map +1 -1
  15. package/dist/src/code-execution/runtime-py.js +47 -7
  16. package/dist/src/code-execution/runtime-py.js.map +1 -1
  17. package/dist/src/code-execution/tool-definition.d.ts +12 -7
  18. package/dist/src/code-execution/tool-definition.d.ts.map +1 -1
  19. package/dist/src/code-execution/tool-definition.js +59 -11
  20. package/dist/src/code-execution/tool-definition.js.map +1 -1
  21. package/dist/src/config-checks.d.ts +2 -2
  22. package/dist/src/config-checks.d.ts.map +1 -1
  23. package/dist/src/config-checks.js +6 -2
  24. package/dist/src/config-checks.js.map +1 -1
  25. package/dist/src/framework.d.ts +744 -120
  26. package/dist/src/framework.d.ts.map +1 -1
  27. package/dist/src/framework.js +3546 -906
  28. package/dist/src/framework.js.map +1 -1
  29. package/dist/src/gate/event-gate.d.ts.map +1 -1
  30. package/dist/src/gate/event-gate.js +13 -6
  31. package/dist/src/gate/event-gate.js.map +1 -1
  32. package/dist/src/held-writes.d.ts +16 -0
  33. package/dist/src/held-writes.d.ts.map +1 -0
  34. package/dist/src/held-writes.js +56 -0
  35. package/dist/src/held-writes.js.map +1 -0
  36. package/dist/src/index.d.ts +7 -3
  37. package/dist/src/index.d.ts.map +1 -1
  38. package/dist/src/index.js +8 -4
  39. package/dist/src/index.js.map +1 -1
  40. package/dist/src/mcpl/capability-grant.d.ts +4 -0
  41. package/dist/src/mcpl/capability-grant.d.ts.map +1 -1
  42. package/dist/src/mcpl/capability-grant.js +1 -1
  43. package/dist/src/mcpl/capability-grant.js.map +1 -1
  44. package/dist/src/mcpl/channel-registry.d.ts +95 -18
  45. package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
  46. package/dist/src/mcpl/channel-registry.js +578 -150
  47. package/dist/src/mcpl/channel-registry.js.map +1 -1
  48. package/dist/src/mcpl/convert-block.d.ts +2 -2
  49. package/dist/src/mcpl/convert-block.d.ts.map +1 -1
  50. package/dist/src/mcpl/convert-block.js +6 -7
  51. package/dist/src/mcpl/convert-block.js.map +1 -1
  52. package/dist/src/mcpl/index.d.ts +5 -1
  53. package/dist/src/mcpl/index.d.ts.map +1 -1
  54. package/dist/src/mcpl/index.js +3 -1
  55. package/dist/src/mcpl/index.js.map +1 -1
  56. package/dist/src/mcpl/inference-router.d.ts +4 -2
  57. package/dist/src/mcpl/inference-router.d.ts.map +1 -1
  58. package/dist/src/mcpl/inference-router.js +6 -7
  59. package/dist/src/mcpl/inference-router.js.map +1 -1
  60. package/dist/src/mcpl/log-value.d.ts +7 -0
  61. package/dist/src/mcpl/log-value.d.ts.map +1 -1
  62. package/dist/src/mcpl/log-value.js +9 -0
  63. package/dist/src/mcpl/log-value.js.map +1 -1
  64. package/dist/src/mcpl/modern-connection.d.ts +227 -0
  65. package/dist/src/mcpl/modern-connection.d.ts.map +1 -0
  66. package/dist/src/mcpl/modern-connection.js +1088 -0
  67. package/dist/src/mcpl/modern-connection.js.map +1 -0
  68. package/dist/src/mcpl/prefix-rule.d.ts +18 -0
  69. package/dist/src/mcpl/prefix-rule.d.ts.map +1 -0
  70. package/dist/src/mcpl/prefix-rule.js +25 -0
  71. package/dist/src/mcpl/prefix-rule.js.map +1 -0
  72. package/dist/src/mcpl/protocol-family.d.ts +179 -0
  73. package/dist/src/mcpl/protocol-family.d.ts.map +1 -0
  74. package/dist/src/mcpl/protocol-family.js +697 -0
  75. package/dist/src/mcpl/protocol-family.js.map +1 -0
  76. package/dist/src/mcpl/push-coalescer.d.ts +38 -19
  77. package/dist/src/mcpl/push-coalescer.d.ts.map +1 -1
  78. package/dist/src/mcpl/push-coalescer.js +52 -23
  79. package/dist/src/mcpl/push-coalescer.js.map +1 -1
  80. package/dist/src/mcpl/reference-fetcher.d.ts +66 -15
  81. package/dist/src/mcpl/reference-fetcher.d.ts.map +1 -1
  82. package/dist/src/mcpl/reference-fetcher.js +243 -76
  83. package/dist/src/mcpl/reference-fetcher.js.map +1 -1
  84. package/dist/src/mcpl/references.d.ts +63 -18
  85. package/dist/src/mcpl/references.d.ts.map +1 -1
  86. package/dist/src/mcpl/references.js +117 -32
  87. package/dist/src/mcpl/references.js.map +1 -1
  88. package/dist/src/mcpl/server-connection.d.ts +326 -30
  89. package/dist/src/mcpl/server-connection.d.ts.map +1 -1
  90. package/dist/src/mcpl/server-connection.js +995 -212
  91. package/dist/src/mcpl/server-connection.js.map +1 -1
  92. package/dist/src/mcpl/server-registry.d.ts +25 -5
  93. package/dist/src/mcpl/server-registry.d.ts.map +1 -1
  94. package/dist/src/mcpl/server-registry.js +51 -12
  95. package/dist/src/mcpl/server-registry.js.map +1 -1
  96. package/dist/src/mcpl/tool-result-normalize.d.ts +54 -0
  97. package/dist/src/mcpl/tool-result-normalize.d.ts.map +1 -0
  98. package/dist/src/mcpl/tool-result-normalize.js +232 -0
  99. package/dist/src/mcpl/tool-result-normalize.js.map +1 -0
  100. package/dist/src/mcpl/transport.d.ts +56 -13
  101. package/dist/src/mcpl/transport.d.ts.map +1 -1
  102. package/dist/src/mcpl/transport.js +206 -70
  103. package/dist/src/mcpl/transport.js.map +1 -1
  104. package/dist/src/mcpl/types.d.ts +66 -20
  105. package/dist/src/mcpl/types.d.ts.map +1 -1
  106. package/dist/src/mcpl/types.js.map +1 -1
  107. package/dist/src/mcpl/visible-content.d.ts +2 -1
  108. package/dist/src/mcpl/visible-content.d.ts.map +1 -1
  109. package/dist/src/mcpl/visible-content.js +2 -1
  110. package/dist/src/mcpl/visible-content.js.map +1 -1
  111. package/dist/src/module-registry.d.ts +16 -6
  112. package/dist/src/module-registry.d.ts.map +1 -1
  113. package/dist/src/module-registry.js +65 -6
  114. package/dist/src/module-registry.js.map +1 -1
  115. package/dist/src/modules/api/index.d.ts +1 -1
  116. package/dist/src/modules/api/index.d.ts.map +1 -1
  117. package/dist/src/modules/api/index.js +3 -2
  118. package/dist/src/modules/api/index.js.map +1 -1
  119. package/dist/src/modules/discord/discord-js-client.d.ts +42 -2
  120. package/dist/src/modules/discord/discord-js-client.d.ts.map +1 -1
  121. package/dist/src/modules/discord/discord-js-client.js +268 -65
  122. package/dist/src/modules/discord/discord-js-client.js.map +1 -1
  123. package/dist/src/modules/discord/index.d.ts +27 -5
  124. package/dist/src/modules/discord/index.d.ts.map +1 -1
  125. package/dist/src/modules/discord/index.js +366 -76
  126. package/dist/src/modules/discord/index.js.map +1 -1
  127. package/dist/src/modules/discord/refusal.d.ts +14 -0
  128. package/dist/src/modules/discord/refusal.d.ts.map +1 -0
  129. package/dist/src/modules/discord/refusal.js +14 -0
  130. package/dist/src/modules/discord/refusal.js.map +1 -0
  131. package/dist/src/modules/discord/types.d.ts +17 -7
  132. package/dist/src/modules/discord/types.d.ts.map +1 -1
  133. package/dist/src/modules/health/index.d.ts.map +1 -1
  134. package/dist/src/modules/health/index.js +6 -2
  135. package/dist/src/modules/health/index.js.map +1 -1
  136. package/dist/src/modules/index.d.ts +1 -1
  137. package/dist/src/modules/index.d.ts.map +1 -1
  138. package/dist/src/modules/index.js +1 -1
  139. package/dist/src/modules/index.js.map +1 -1
  140. package/dist/src/modules/workspace/disk-agreement.d.ts +25 -2
  141. package/dist/src/modules/workspace/disk-agreement.d.ts.map +1 -1
  142. package/dist/src/modules/workspace/disk-agreement.js +45 -5
  143. package/dist/src/modules/workspace/disk-agreement.js.map +1 -1
  144. package/dist/src/modules/workspace/effects.d.ts +2 -1
  145. package/dist/src/modules/workspace/effects.d.ts.map +1 -1
  146. package/dist/src/modules/workspace/effects.js +19 -9
  147. package/dist/src/modules/workspace/effects.js.map +1 -1
  148. package/dist/src/modules/workspace/index.d.ts +214 -42
  149. package/dist/src/modules/workspace/index.d.ts.map +1 -1
  150. package/dist/src/modules/workspace/index.js +667 -113
  151. package/dist/src/modules/workspace/index.js.map +1 -1
  152. package/dist/src/modules/workspace/observe.d.ts +240 -8
  153. package/dist/src/modules/workspace/observe.d.ts.map +1 -1
  154. package/dist/src/modules/workspace/observe.js +554 -24
  155. package/dist/src/modules/workspace/observe.js.map +1 -1
  156. package/dist/src/modules/workspace/types.d.ts +10 -1
  157. package/dist/src/modules/workspace/types.d.ts.map +1 -1
  158. package/dist/src/modules/workspace/types.js.map +1 -1
  159. package/dist/src/modules/workspace/watcher.d.ts +42 -0
  160. package/dist/src/modules/workspace/watcher.d.ts.map +1 -1
  161. package/dist/src/modules/workspace/watcher.js +130 -25
  162. package/dist/src/modules/workspace/watcher.js.map +1 -1
  163. package/dist/src/silent-heartbeat.d.ts +112 -39
  164. package/dist/src/silent-heartbeat.d.ts.map +1 -1
  165. package/dist/src/silent-heartbeat.js +100 -29
  166. package/dist/src/silent-heartbeat.js.map +1 -1
  167. package/dist/src/tool-args.d.ts +40 -0
  168. package/dist/src/tool-args.d.ts.map +1 -0
  169. package/dist/src/tool-args.js +207 -0
  170. package/dist/src/tool-args.js.map +1 -0
  171. package/dist/src/tool-presentation.d.ts.map +1 -1
  172. package/dist/src/tool-presentation.js +9 -2
  173. package/dist/src/tool-presentation.js.map +1 -1
  174. package/dist/src/types/agent.d.ts +27 -17
  175. package/dist/src/types/agent.d.ts.map +1 -1
  176. package/dist/src/types/events.d.ts +8 -0
  177. package/dist/src/types/events.d.ts.map +1 -1
  178. package/dist/src/types/framework.d.ts +17 -2
  179. package/dist/src/types/framework.d.ts.map +1 -1
  180. package/dist/src/types/module.d.ts +54 -10
  181. package/dist/src/types/module.d.ts.map +1 -1
  182. package/dist/src/types/trace.d.ts +2 -2
  183. package/dist/src/types/trace.d.ts.map +1 -1
  184. package/package.json +3 -1
  185. package/src/agent.ts +99 -36
  186. package/src/code-execution/index.ts +1 -0
  187. package/src/code-execution/py-runner.ts +104 -17
  188. package/src/code-execution/runtime-py.ts +47 -7
  189. package/src/code-execution/tool-definition.ts +65 -11
  190. package/src/config-checks.ts +4 -2
  191. package/src/framework.ts +3633 -956
  192. package/src/gate/event-gate.ts +14 -6
  193. package/src/held-writes.ts +59 -0
  194. package/src/index.ts +19 -4
  195. package/src/mcpl/capability-grant.ts +1 -1
  196. package/src/mcpl/channel-registry.ts +613 -160
  197. package/src/mcpl/convert-block.ts +15 -7
  198. package/src/mcpl/index.ts +14 -1
  199. package/src/mcpl/inference-router.ts +8 -7
  200. package/src/mcpl/log-value.ts +10 -0
  201. package/src/mcpl/modern-connection.ts +1182 -0
  202. package/src/mcpl/prefix-rule.ts +32 -0
  203. package/src/mcpl/protocol-family.ts +691 -0
  204. package/src/mcpl/push-coalescer.ts +67 -29
  205. package/src/mcpl/reference-fetcher.ts +288 -82
  206. package/src/mcpl/references.ts +123 -33
  207. package/src/mcpl/server-connection.ts +1050 -221
  208. package/src/mcpl/server-registry.ts +50 -12
  209. package/src/mcpl/tool-result-normalize.ts +294 -0
  210. package/src/mcpl/transport.ts +204 -62
  211. package/src/mcpl/types.ts +67 -20
  212. package/src/mcpl/visible-content.ts +2 -1
  213. package/src/module-registry.ts +68 -13
  214. package/src/modules/api/index.ts +3 -2
  215. package/src/modules/discord/discord-js-client.ts +288 -72
  216. package/src/modules/discord/index.ts +380 -77
  217. package/src/modules/discord/refusal.ts +13 -0
  218. package/src/modules/discord/types.ts +17 -9
  219. package/src/modules/health/index.ts +6 -2
  220. package/src/modules/index.ts +1 -1
  221. package/src/modules/workspace/disk-agreement.ts +46 -5
  222. package/src/modules/workspace/effects.ts +18 -7
  223. package/src/modules/workspace/index.ts +722 -124
  224. package/src/modules/workspace/observe.ts +591 -22
  225. package/src/modules/workspace/types.ts +10 -1
  226. package/src/modules/workspace/watcher.ts +126 -25
  227. package/src/silent-heartbeat.ts +184 -59
  228. package/src/tool-args.ts +213 -0
  229. package/src/tool-presentation.ts +9 -2
  230. package/src/types/agent.ts +27 -17
  231. package/src/types/events.ts +8 -0
  232. package/src/types/framework.ts +17 -2
  233. package/src/types/module.ts +55 -10
  234. package/src/types/trace.ts +2 -2
package/README.md CHANGED
@@ -64,13 +64,33 @@ Chronicle's audit history.
64
64
  model: 'claude-opus-4-20250514',
65
65
  systemPrompt: '...',
66
66
  strategy: new AutobiographicalStrategy({ recentWindowTokens: 30000 }),
67
- allowedTools: ['search', 'read', 'write'], // or 'all'
67
+ allowedTools: ['search--query', 'utils', 'files--archive'], // or 'all'
68
68
  triggerSources: ['discord'], // or 'all'
69
69
  maxTokens: 8192,
70
70
  maxStreamTokens: 150_000, // input token budget before stream restart
71
71
  }
72
72
  ```
73
73
 
74
+ `allowedTools` is enforced at dispatch for registered agents. Omission or
75
+ `'all'` permits all tools; an explicit list matches exact names, including
76
+ `module--utility` names. Utilities aren't tools of their own: an agent's model
77
+ and its scripts are offered them only through `utils`, whose `run` checks the
78
+ utility's own name. An agent that should use a utility lists both `utils` and
79
+ `module--utility`. The name alone passes the dispatch check for any call by
80
+ that name, whether the host makes it with `executeToolCall` on the agent's
81
+ behalf or the model or a script makes it without being offered it. The slot
82
+ is hidden when the agent can use no registered utility. If utilities exist
83
+ but none are permitted, `list` returns a failed `ToolResult` with the registered
84
+ and permitted counts and migration advice, and a list containing `utils`
85
+ logs one warning per Agent instance after registration.
86
+ An empty registry still returns a successful empty list.
87
+
88
+ Trusted module calls are exempt from agent allowlists. Genuinely unidentified
89
+ public callers, including unknown legacy caller names, remain unrestricted.
90
+ Framework-created ephemeral and conversation identities fail closed while
91
+ unregistered. Hosts using `createEphemeralAgent` must register and run the
92
+ returned agent through `runEphemeralToCompletion` for tool authority.
93
+
74
94
  **Inference modes:**
75
95
  - **Streaming** (default in framework): `startStreamWithInjections()` returns a `YieldingStream` that emits tokens, tool calls, and completion events. The framework drives the stream, dispatches tools, and resumes automatically.
76
96
  - **Request/response**: `runInferenceWithInjections()` for simple complete-and-return usage with optional `AbortSignal` for cancellation.
@@ -217,8 +237,11 @@ queue. Switching back to the source branch queues removal of the bot's marker;
217
237
  returning to the recovery branch queues it again. Initial MCPL events remain
218
238
  buffered until the ledger has been reconciled. Startup, reconnect, runtime
219
239
  list-change, and online undo use one framework-global generation: every MCPL
220
- data plane waits while all control planes remain live for registration and
221
- marker service. Awareness marker calls also have a mandatory deadline that is
240
+ data plane waits while the control planes remain live for registration and
241
+ marker service. A connection whose policy exchange is in flight, after a
242
+ connect or a reconnect, keeps both planes closed until the exchange settles,
243
+ since its traffic is admitted against the grant the exchange establishes.
244
+ Awareness marker calls also have a mandatory deadline that is
222
245
  independent of `requestTimeoutMs` (including when that value is `0`); configure
223
246
  it with `discordAwarenessDeadlineMs` (default 10000ms, clamped to 50..60000ms).
224
247
  Configure the online marker with `discordAwarenessEmoji`; the offline CLI
@@ -255,6 +278,17 @@ defaults to `mcpl--<serverId>`: server `search` with no `toolPrefix` offers
255
278
  `mcpl--search--query`, and with `toolPrefix: 'search'` it offers
256
279
  `search--query`.
257
280
 
281
+ No two servers' prefixes may meet, since their servers could then give one
282
+ tool name. Two prefixes meet when one is the other's followed by `-`, or
283
+ begins with the other's followed by `--`: server `foo` listing `bar--echo` and
284
+ server `foo--bar` listing `echo` would both give `foo--bar--echo`. `create()`
285
+ refuses such a pair, and so do a runtime connect and a restart (before it
286
+ disconnects anything), naming both servers and the rule. `foo` beside
287
+ `foo-bar` or `foobar` is fine. A server that lists one tool more than once has
288
+ its first listing offered to the model and the rest left out, and each tool
289
+ refresh that finds it raises an `mcpl-tool-duplicate` ops alert naming the
290
+ tools. Its webhook post goes out at most once per server in 15 minutes.
291
+
258
292
  These settings take RFC-007 §6.2 patterns (`*` matches any run of characters)
259
293
  over that full model-facing name, so they need the prefix:
260
294
 
@@ -270,6 +304,72 @@ A pattern that matches no tool is reported once, as a console line and an
270
304
  A pattern that could name a server's tools is not judged until that server
271
305
  has listed them, so late connects and reconnects don't cause early reports.
272
306
 
307
+ #### Modern MCP servers (2026-07-28)
308
+
309
+ The same `mcplServers` list also takes servers that speak modern MCP
310
+ (revision `2026-07-28`), reached through the official SDK client. The
311
+ configuration chooses the family, and nothing is probed:
312
+
313
+ | Configuration | Family | Transport |
314
+ |---|---|---|
315
+ | `url: 'ws://…'` / `'wss://…'` | MCPL (MCP `2024-11-05`) | WebSocket |
316
+ | `url: 'http://…'` / `'https://…'` | modern MCP | Streamable HTTP (`token` / `accessProvider` as bearer) |
317
+ | `command` | MCPL | stdio |
318
+ | `command` + `protocol: 'modern'` | modern MCP | stdio |
319
+
320
+ ```typescript
321
+ {
322
+ mcplServers: [
323
+ { id: 'docs', url: 'https://mcp.example.com/mcp', accessProvider: getToken },
324
+ { id: 'search', command: 'search-mcp', protocol: 'modern', reconnect: true },
325
+ ],
326
+ }
327
+ ```
328
+
329
+ A configuration with both `command` and `url` needs `transport` to say which
330
+ one is used; without it, it is refused rather than silently ignoring one.
331
+
332
+ A modern server's tools get the same prefix, `enabledTools`/`disabledTools`,
333
+ class overrides and dispatch as an MCPL server's, and `listMcplServers()`
334
+ shows its `family`, `protocolVersion` and `transport`. Its config differs in
335
+ three ways:
336
+ - It has no MCPL surface (grant, push, channels, inference requests, feature
337
+ sets). A setting that asks for that surface can't apply, so it is a
338
+ configuration error: `allowHostCommands: true`, an `enabledCapabilities`
339
+ pattern that matches a capability denied by default, `channelSubscription:
340
+ 'auto'` or a non-empty list, a scope's non-empty `whitelist`, a
341
+ `toolLifecycle` `observe` or `inputs` block, and a
342
+ `toolLifecycle.maxInputBytes` or an `autofetch` bound above its default.
343
+ A setting
344
+ that only takes something away, or repeats a default, is already
345
+ satisfied, so it is accepted: `enabledFeatureSets` and the rest of
346
+ `enabledCapabilities`, which are allow-lists, `disabledFeatureSets`,
347
+ `disabledCapabilities`, a scope's `blacklist`, `channelSubscription:
348
+ 'manual'`, a `toolLifecycle.maxInputBytes` or an `autofetch` bound at or
349
+ below its default, and `shouldTriggerInference`.
350
+ So a host that puts a deny-list on every server it deploys can deploy a
351
+ modern one.
352
+ - `requestTimeoutMs` is one deadline per tool call and must be 1 to 2^31−1;
353
+ 0 is refused, where MCPL reads it as no watchdog.
354
+ - Over stdio it takes no credential: `token` or `accessProvider` on one is
355
+ refused.
356
+
357
+ At the deadline, cancellation is requested for a leg still in flight;
358
+ between the rounds of an `input_required` continuation nothing is in flight
359
+ to cancel. Either way the outcome is reported as unknown (`no-response`),
360
+ and the call is never retried. The protocol has no cancel for a paused call,
361
+ so whatever the server holds for it, beyond the `requestState` it gave this
362
+ client, stays until the server lets it go. A call that ends for any other
363
+ reason after the server asked for another round, before its final answer, is
364
+ reported the same way, since the server may already have acted. An MCPL
365
+ server that refuses `2024-11-05` with `-32022` fails with
366
+ `McplProtocolVersionError`, and is not retried. The error names the
367
+ revisions the server says it supports ("none listed" for an empty list), or its error text when it sends no list,
368
+ and when the list includes `2026-07-28` it says to configure the server with
369
+ `protocol: 'modern'` (stdio) or reach it over http(s).
370
+
371
+ Server and transport text the framework records has the server's configured credentials replaced, in both engines. That covers connection traces, console lines, stderr traces, ops alerts, and a tool call's failure as its caller, the model and the `tool:failed` trace get it. The credentials are those the configuration holds and those its dials sent: from the url as each dial sends it (a WebSocket dial sets the token in the query, which writes the whole query again, form-encoded, and an access provider's token can be in it), credential-like path segments and query names, credential-shaped or credential-named query values, and a WebSocket url's userinfo, in their encoded and decoded forms, replaced wherever they occur; every non-empty query parameter as its whole `name=value`, where no letter or digit adjoins it; the static `token`, and each token an access provider handed a dial, the newest sixteen, raw and url-encoded; and a stdio server's `env` values whose names have a part ending in a credential word, such as `GITHUB_TOKEN`, `PGPASSWORD` or `SESSION_COOKIE`, raw and url-encoded. A stdio server's command-line arguments aren't derived. Standalone strings shorter than eight characters stay unchanged because they may be ordinary words; short query values are still removed with their parameter names. Treat a submitted configuration as immutable while the server uses it: apply changes with `restartMcplServer(id, newConfig)`. Secrets neither the configuration holds nor a dial sent remain outside this filtering. JSON-RPC tool answers, and the error a host's own connect raises, pass through as sent.
372
+
273
373
  #### Feature sets
274
374
 
275
375
  `enabledFeatureSets` and `disabledFeatureSets` select which of a server's
@@ -335,6 +435,8 @@ The non-streaming path uses `AbortSignal` forwarded to `membrane.stream()`, whic
335
435
 
336
436
  A turn whose stream is cancelled this way, or by `agent.cancelStream()`, ends as a stop, whether the stream reports the cancel as `aborted`, as an `error`, or by just closing: one `inference:aborted` carrying the caller's reason (`user` when none was given), a `[turn-interrupted]` note in the agent's context, and never `inference:exhausted`, which is for failed inferences. A stream that membrane aborts on its own, at a deadline or on an error (reason `timeout` or `error`), is a failed inference. `stop()` and an operator's quiesce abandon end a turn as a stop too, with their own reasons, `shutdown` and `quiesce_abandoned`, and write no note. A stopped stream still writes its inference-log row, with `success: false`.
337
437
 
438
+ A caller's stop and an operator's quiesce abandon also reach a turn that has no live stream: one running its modules' `gatherContext`, its MCPL hooks or its compile, one waiting to retry a failed inference or compile (`abortInference()` and an operator's abandon end the wait, and a stop through `Agent.cancelStream()` waits for it to run out), and one whose tool-result guard is waiting to retry after a refusal, which holds only the round's finished stream. The turn ends at its next check, before it sends anything more, as a stop on a live stream ends it, and a turn whose compile fails after the stop ends at the failure, before a provider hold, the error policy's retry or `inference:exhausted`. A caller's stop leaves the note saying the turn was stopped before it sent anything or before it finished, and an operator's abandon leaves none. `abortInference()` returns `true` for such a turn. In the guard's wait, `stop()` ends the turn as a stop with reason `shutdown`, and an operator's abandon ends it as the abandon, even when a caller's stop came first; with both, it ends as `stop()`'s. `stop()` drops a turn in its hooks, its compile or a wait to retry before it sends anything, as before, and drops one whose compile fails while it runs, once a caller's stop has reached it, rather than ending it as that stop. While the failure of a turn's stream is reported (`inference:failed`), the agent no longer holds that stream, so `abortInference()` from a listener reports `false`. A failure to build a turn's request is reported while the turn's check is still ahead, so there `abortInference()` reports `true`, and the turn ends at that check. A stop made where no check of a turn is ahead stops nothing, and doesn't end the agent's next turn: while the agent is idle, while a turn finishes its last delivery, while a budget restart or a non-streaming turn's tool results wait to start the turn's next call, and while a provider-capacity hold or a provider's stated wait has parked a turn until the hold ends.
439
+
338
440
  ## API Server
339
441
 
340
442
  WebSocket server for external clients (UIs, scripts, other agents).
@@ -1,7 +1,7 @@
1
1
  import type { Membrane, NormalizedRequest, ContentBlock, YieldingStream } from '@animalabs/membrane';
2
2
  import type { CacheWireReceipt } from './kv-unified-wire.js';
3
3
  import { ToolResultGuard } from './tool-result-guard.js';
4
- import { type SilentHeartbeatTick } from './silent-heartbeat.js';
4
+ import { type RequestOnlyPrompt, type SilentHeartbeatTick } from './silent-heartbeat.js';
5
5
  export interface ActivationRequestOptions {
6
6
  /** The silent heartbeat tick this request answers, if any. */
7
7
  silentHeartbeat?: SilentHeartbeatTick;
@@ -12,6 +12,13 @@ export interface ActivationRequestOptions {
12
12
  export interface StartStreamResult {
13
13
  stream: YieldingStream;
14
14
  request: NormalizedRequest;
15
+ /** The request-only `[Continue]` prompt this request's reply follows, if
16
+ * any, read from the request: a new one when it ends on `[Continue]`;
17
+ * else, when it ends on tool results, the prompt of the reply that called
18
+ * those tools (`toolLoopPrompt`); else none. The framework stamps the
19
+ * reply's rows with it (`metadata.promptedBy`), for later compiles to
20
+ * render it before them. */
21
+ continuePrompt?: RequestOnlyPrompt;
15
22
  takeKvSubmission?: () => {
16
23
  submissionId: string;
17
24
  wireReceipt: CacheWireReceipt;
@@ -429,20 +436,24 @@ export declare class Agent {
429
436
  * may show a withheld stub before its place is added; the activation waits
430
437
  * for them around its call.
431
438
  */
432
- buildActivationRequest(availableTools: ToolDefinition[], injections?: ContextInjection[], budget?: TokenBudget, compressionTools?: ToolDefinition[], options?: ActivationRequestOptions): Promise<NormalizedRequest>;
439
+ private assembleActivationRequest;
433
440
  /**
434
441
  * The request fields that come from this agent's own settings: its model
435
442
  * config, prompt caching and cache TTL, prefill message, provider
436
443
  * parameters and participant name. Every request the agent sends takes
437
- * them from here, a framework turn's (buildActivationRequest) and the
444
+ * them from here, a framework turn's (assembleActivationRequest) and the
438
445
  * direct API's (runInferenceWithInjections), so a setting reaches both or
439
446
  * neither.
440
447
  */
441
448
  private requestSettings;
442
- /** Stored silent-tick rows, memoized on the store's cached message array
443
- * (ContextManager returns the same array until the store changes). */
444
- private silentTickIndex;
445
- private indexSilentHeartbeatTicks;
449
+ /** The request `assembleActivationRequest` builds (see there), for preview
450
+ * and debug tooling: what this agent's next activation would send. */
451
+ buildActivationRequest(availableTools: ToolDefinition[], injections?: ContextInjection[], budget?: TokenBudget, compressionTools?: ToolDefinition[], options?: ActivationRequestOptions): Promise<NormalizedRequest>;
452
+ /** Stored rows that follow a request-only turn, memoized on the store's
453
+ * cached message array (ContextManager returns the same array until the
454
+ * store changes). */
455
+ private requestOnlyIndex;
456
+ private indexRequestOnlyRows;
446
457
  /**
447
458
  * Start a yielding stream with context injections.
448
459
  * Same as startStream but passes injections through to compile.
@@ -476,14 +487,29 @@ export declare class Agent {
476
487
  * report the cancel as `error` with no reason at all, so this record is
477
488
  * the only provenance a host-side cancel has. */
478
489
  private _pendingCancel;
490
+ /** The most recent cancelStream() made while this agent held no stream:
491
+ * during a turn's hooks or compile, while it waits to retry, or while no
492
+ * check of a turn is ahead at all. The framework collects it at the check
493
+ * ahead of it, which ends the turn, and the next start drops one no check
494
+ * collected, so a stop made while none was ahead, such as a host's
495
+ * interrupt of every agent, ends nothing. */
496
+ private _stopWithoutStream;
479
497
  /**
480
498
  * Cancel the stream this agent's state holds (streaming, waiting on its
481
499
  * tools, or ready at a tool boundary with every result in), and reset to
482
- * idle. `reason` is provenance for the framework's inference:aborted trace
483
- * and marker metadata (e.g. 'zombie_reclaim', 'subagent_cancel'); it never
484
- * reaches the provider.
500
+ * idle. With no stream, the stop is kept for the turn in progress, which
501
+ * the framework ends at its next check, before it sends anything more, if
502
+ * one is still ahead; otherwise the next start drops it. `reason` is
503
+ * provenance for the framework's inference:aborted trace and marker
504
+ * metadata (e.g. 'zombie_reclaim', 'subagent_cancel'); it never reaches
505
+ * the provider.
485
506
  */
486
507
  cancelStream(reason?: string): void;
508
+ /** Collect (and clear) the cancelStream() made while this agent held no
509
+ * stream, if one was made since the last collection. */
510
+ takeStopWithoutStream(): {
511
+ reason?: string;
512
+ } | undefined;
487
513
  /** Collect (and clear) the cancel that ended the current stream, if this
488
514
  * side issued one. The stream driver calls it once, while the stream
489
515
  * still owns the agent, at the stream's terminal event (`aborted`
@@ -1 +1 @@
1
- {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/agent.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/agent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAqB,iBAAiB,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAGxH,OAAO,KAAK,EAAE,gBAAgB,EAAyB,MAAM,sBAAsB,CAAC;AACpF,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,OAAO,EAQL,KAAK,iBAAiB,EAEtB,KAAK,mBAAmB,EAEzB,MAAM,uBAAuB,CAAC;AAQ/B,MAAM,WAAW,wBAAwB;IACvC,8DAA8D;IAC9D,eAAe,CAAC,EAAE,mBAAmB,CAAC;IACtC;wEACoE;IACpE,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,cAAc,CAAC;IACvB,OAAO,EAAE,iBAAiB,CAAC;IAC3B;;;;;iCAK6B;IAC7B,cAAc,CAAC,EAAE,iBAAiB,CAAC;IACnC,gBAAgB,CAAC,EAAE,MAAM;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,gBAAgB,CAAA;KAAE,GAAG,SAAS,CAAC;IAC7F,oBAAoB,CAAC,EAAE,MAAM,MAAM,EAAE,CAAC;CACvC;AACD,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EACX,gBAAgB,EAChB,aAAa,EAGb,eAAe,EAChB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EACV,WAAW,EACX,UAAU,EACV,wBAAwB,EACxB,8BAA8B,EAG9B,UAAU,EACV,QAAQ,EACR,UAAU,EACV,cAAc,EACd,SAAS,EACT,eAAe,EACf,gBAAgB,EAChB,yBAAyB,EACzB,4BAA4B,EAC5B,6BAA6B,EAC9B,MAAM,kBAAkB,CAAC;AAkB1B;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAkC7D;AAED;;GAEG;AACH,qBAAa,KAAK;IAChB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,KAAK,GAAG,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,cAAc,EAAE,KAAK,GAAG,MAAM,EAAE,CAAC;IAC1C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;IAC3C,oEAAoE;IACpE,QAAQ,CAAC,eAAe,EAAE,WAAW,CAAC,iBAAiB,CAAC,CAAC;IACzD,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;IAC1C,2EAA2E;IAC3E,QAAQ,CAAC,YAAY,EAAE,OAAO,GAAG,UAAU,GAAG,QAAQ,GAAG,UAAU,CAAC;IACpE,yEAAyE;IACzE,QAAQ,CAAC,qBAAqB,EAAE,OAAO,CAAC;IACxC,6EAA6E;IAC7E,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC;IACxD,6EAA6E;IAC7E,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,0EAA0E;IAC1E,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,4EAA4E;IAC5E,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClD,QAAQ,CAAC,wBAAwB,EAAE,WAAW,CAAC,0BAA0B,CAAC,CAAC;IAE3E,OAAO,CAAC,MAAM,CAAkC;IAChD,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,SAAS,CAAK;IACtB;;;2CAGuC;IACvC,OAAO,CAAC,WAAW,CAA+E;IAClG;;yBAEqB;IACrB,qBAAqB,SAAK;IAC1B;;;;;;;;;6CASyC;IACzC,yBAAyB,SAAK;IAC9B;;;;;sBAKkB;IAClB,sBAAsB,SAAK;IAC3B;;;;;;;;6DAQyD;IACzD,0BAA0B,SAAK;IAC/B,eAAe,EAAE,MAAM,CAAC;IACxB,wEAAwE;IACxE,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IACvC;;iCAE6B;IAC7B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,OAAO,CAAC,QAAQ,CAAC,6BAA6B,CAAC,CAAS;IACxD,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAS;IAC/C,OAAO,CAAC,QAAQ,CAAC,8BAA8B,CAAC,CAAS;IACzD,OAAO,CAAC,QAAQ,CAAC,kCAAkC,CAAC,CAA2B;IAC/E,OAAO,CAAC,yBAAyB,CAAC,CAAS;IAC3C,OAAO,CAAC,wBAAwB,CAAiC;IACjE;;;;;OAKG;IACH,OAAO,CAAC,eAAe,CAAK;IAC5B;;;;OAIG;IACH,OAAO,CAAC,YAAY,CAAK;IACzB,qGAAqG;IACrG,OAAO,CAAC,kBAAkB,CAAC,CAAkD;IAC7E,wDAAwD;IACxD,OAAO,CAAC,eAAe,CAAK;IAC5B,0EAA0E;IAC1E,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqB;IACrD;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA6B;IAC9D,2GAA2G;IAC3G,OAAO,CAAC,sBAAsB,CAAC,CAAkD;IACjF;;;;;OAKG;IACH,OAAO,CAAC,cAAc,CAAS;IAC/B,qFAAqF;IACrF,OAAO,CAAC,sBAAsB,CAAC,CAA4C;IAC3E,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,QAAQ,CAAW;IAE3B,YACE,MAAM,EAAE,WAAW,EACnB,cAAc,EAAE,cAAc,EAC9B,QAAQ,EAAE,QAAQ,EA8BnB;IAED;;OAEG;IACH,IAAI,KAAK,IAAI,UAAU,CAEtB;IAED;;;OAGG;IACH,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,SAAS,CAMpB;IAED;;OAEG;IACH,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAKpC;IAED;;OAEG;IACH,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAKxC;IAMD;;;;OAIG;IACH;8EAC0E;IAC1E,OAAO,CAAC,aAAa;IAMrB;;;;0DAIsD;IACtD,OAAO,CAAC,aAAa;IASrB;8EAC0E;IAC1E,OAAO,CAAC,qBAAqB;IAS7B,OAAO,CAAC,wBAAwB;IAUhC,kBAAkB,IAAI,4BAA4B,CA8BjD;IAED,2BAA2B,IAAI,6BAA6B,CAE3D;IAED;;;;;OAKG;IACH,uBAAuB,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,GAAG,SAAS,GAAG,IAAI,CAE/F;IAED;;;OAGG;IACH,4BAA4B,IAAI,MAAM,GAAG,SAAS,CAGjD;IAED;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IAOxB;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IAMrB;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAS1B,2EAA2E;YAC7D,mBAAmB;IAcjC,0FAA0F;YAC5E,yBAAyB;IA4DvC;;;;;;OAMG;IACH,iBAAiB,CAAC,KAAK,CAAC,EAAE,yBAAyB,GAAG;QACpD,gBAAgB,EAAE,MAAM,CAAC;QACzB,IAAI,EAAE,WAAW,GAAG,OAAO,GAAG,MAAM,CAAC;QACrC,UAAU,EAAE,QAAQ,GAAG,YAAY,CAAC;KACrC,CAQA;IAED;;;;;;;OAOG;IACH,qBAAqB,IAAI,OAAO,CAO/B;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,mBAAmB,CAAC,KAAK,CAAC,EAAE,yBAAyB,GAAG;QACtD,qBAAqB,EAAE,MAAM,CAAC;QAC9B;;iFAEyE;QACzE,gBAAgB,EAAE,MAAM,CAAC;QACzB,oBAAoB,CAAC,EAAE,MAAM,CAAC;QAC9B,IAAI,EAAE,WAAW,GAAG,OAAO,GAAG,MAAM,CAAC;QACrC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACpC,CAmCA;IAED,oCAAoC,IAAI,wBAAwB,CAI/D;IAED,iCAAiC,IAAI,8BAA8B,CAQlE;IAED,qBAAqB,CAAC,KAAK,EAAE,yBAAyB,GAAG,4BAA4B,CA6DpF;IAED,oBAAoB,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,MAAM,yBAAyB,CAAC,GAAG,4BAA4B,CAqDhG;IAED,+BAA+B,IAAI,4BAA4B,CAY9D;IAED;;;;;;;;;OASG;IACH,sBAAsB,CACpB,QAAQ,EAAE,yBAAyB,EACnC,IAAI,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,GAC/B,4BAA4B,CAS9B;IAED;;;;;;OAMG;IACH,mBAAmB,CAAC,QAAQ,EAAE,IAAI,CAAC,yBAAyB,EAAE,qBAAqB,GAAG,YAAY,GAAG,sBAAsB,CAAC,GAAG,IAAI,CAIlI;IAED,OAAO,CAAC,4BAA4B;IAQpC;;;OAGG;IACH,yBAAyB,CAAC,KAAK,EAAE,yBAAyB,GAAG,IAAI,CAoBhE;IAED,kFAAkF;IAClF,OAAO,CAAC,+BAA+B;IASvC;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB,CAAqD;IAC9E;uEACmE;IACnE,OAAO,CAAC,cAAc,CAAK;IAE3B,oBAAoB,IAAI;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAElE;IAED;;mBAEe;IACf,mBAAmB,IAAI,IAAI,CAK1B;IAED;;;;;;OAMG;IACH,OAAO,CAAC,qBAAqB;IAQ7B,uFAAuF;IACvF,OAAO,CAAC,gBAAgB;IAmBxB;;;;cAIU;IACJ,cAAc,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,CASjE;IAED;;;;;;;OAOG;IACG,qBAAqB,CACzB,MAAM,CAAC,EAAE,WAAW,EACpB,UAAU,CAAC,EAAE,gBAAgB,EAAE,EAC/B,IAAI,CAAC,EAAE;QAAE,4BAA4B,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GACjE,OAAO,CAAC,aAAa,CAAC,CA4BxB;IAMD;;;OAGG;IACG,YAAY,CAChB,cAAc,EAAE,cAAc,EAAE,EAChC,MAAM,CAAC,EAAE,WAAW,EACpB,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,eAAe,CAAC,CAE1B;IAED;;;OAGG;IACG,0BAA0B,CAC9B,cAAc,EAAE,cAAc,EAAE,EAChC,UAAU,CAAC,EAAE,gBAAgB,EAAE,EAC/B,MAAM,CAAC,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,eAAe,CAAC,CAmG1B;IAED;;OAEG;IACH,iBAAiB,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CA+B9D;IAED;;;OAGG;IACG,WAAW,CACf,cAAc,EAAE,cAAc,EAAE,EAChC,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,iBAAiB,CAAC,CAE5B;IAED;;;;;;;;;;;;;;;;;;;;OAoBG;YACW,yBAAyB;IAiHvC;;;;;;;OAOG;IACH,OAAO,CAAC,eAAe;IAiBvB;0EACsE;IAChE,sBAAsB,CAC1B,cAAc,EAAE,cAAc,EAAE,EAChC,UAAU,CAAC,EAAE,gBAAgB,EAAE,EAC/B,MAAM,CAAC,EAAE,WAAW,EACpB,gBAAgB,GAAE,cAAc,EAAmB,EACnD,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,iBAAiB,CAAC,CAE5B;IAED;;yBAEqB;IACrB,OAAO,CAAC,gBAAgB,CAA2E;IAEnG,OAAO,CAAC,oBAAoB;IAgB5B;;;OAGG;IACG,yBAAyB,CAC7B,cAAc,EAAE,cAAc,EAAE,EAChC,UAAU,CAAC,EAAE,gBAAgB,EAAE,EAC/B,MAAM,CAAC,EAAE,WAAW,EACpB,gBAAgB,GAAE,cAAc,EAAmB,EACnD,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,iBAAiB,CAAC,CA2G5B;IAED;;;gFAG4E;IAC5E,OAAO,CAAC,qBAAqB;IAkB7B;;;;OAIG;IACH,oBAAoB,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,wBAAwB,CAAC,EAAE,OAAO,GAAG,IAAI,CAWxG;IAED;;;OAGG;IACH,oBAAoB,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,QAAQ,CAAC,EAAE,eAAe,GAAG,IAAI,CA2B9E;IAED;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAEzC;IAED;;;;;;sDAMkD;IAClD,OAAO,CAAC,cAAc,CAAkC;IAExD;;;;;kDAK8C;IAC9C,OAAO,CAAC,kBAAkB,CAAkC;IAE5D;;;;;;;;;OASG;IACH,YAAY,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAQlC;IAED;6DACyD;IACzD,qBAAqB,IAAI;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAIvD;IAED;;;;;0EAKsE;IACtE,UAAU,IAAI;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAI5C;IAED;;OAEG;IACH,eAAe,IAAI,OAAO,CAEzB;IAED;;OAEG;IACH,iBAAiB,IAAI,UAAU,EAAE,CAKhC;IAED;;OAEG;IACH,KAAK,IAAI,IAAI,CAEZ;IAED;;OAEG;IACH,iBAAiB,IAAI,cAAc,CAElC;IAED;;;;;;;OAOG;IACH,OAAO,CAAC,iBAAiB;IAWzB,cAAc,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,IAAI,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,KAAK,CAc7E;YAEa,WAAW;IAsEzB,OAAO,CAAC,yBAAyB;IAsBjC,OAAO,CAAC,uBAAuB;CAuBhC"}
package/dist/src/agent.js CHANGED
@@ -2,7 +2,8 @@ import { isAbortedResponse } from '@animalabs/membrane';
2
2
  import { createHash } from 'node:crypto';
3
3
  import { ToolResultGuard } from './tool-result-guard.js';
4
4
  import { assertBooleanSetting, holdsSettings } from './config-checks.js';
5
- import { indexSilentTickRows, separateSilentHeartbeatTicks, silentHeartbeatSeparatorTurn, } from './silent-heartbeat.js';
5
+ import { CONTINUE_ROW, continueTurn, indexRequestOnlyRows, renderRequestOnlyRows, silentHeartbeatSeparatorTurn, tickKey, toolLoopPrompt, } from './silent-heartbeat.js';
6
+ import { randomUUID } from 'node:crypto';
6
7
  import { nonErrorResultText, truncateForHistory, DEFAULT_TOOL_RESULT_INLINE_MAX_CHARS, } from './tool-result-history.js';
7
8
  function stableHash(value) {
8
9
  const encode = (item) => {
@@ -1066,7 +1067,7 @@ export class Agent {
1066
1067
  * may show a withheld stub before its place is added; the activation waits
1067
1068
  * for them around its call.
1068
1069
  */
1069
- async buildActivationRequest(availableTools, injections, budget, compressionTools = availableTools, options = {}) {
1070
+ async assembleActivationRequest(availableTools, injections, budget, compressionTools = availableTools, options = {}) {
1070
1071
  // Compression may revisit hidden tools in recorded history. Keep its full
1071
1072
  // definition set separate from the resident's advertised tools: the
1072
1073
  // autobiographical strategy must declare the same tools on its
@@ -1114,17 +1115,31 @@ export class Agent {
1114
1115
  (b) => !(b.type === "text" && (typeof b.text !== "string" || b.text.trim() === ""))),
1115
1116
  }))
1116
1117
  .filter((m) => m.content.length > 0);
1117
- // Silent heartbeat ticks store no prompt row. Render a request-only
1118
- // separator before each tick's first surviving row so the wire formatter
1119
- // cannot merge the tick into the previous assistant message (see
1120
- // silent-heartbeat.ts for what can and cannot be matched). This agent's
1121
- // own first request for a tick ends on that same turn, so the prefix it
1122
- // caches is the one every later compile renders. "First" is per agent: a
1123
- // broadcast tick shares its eventId with every resident.
1124
- const ticks = this.indexSilentHeartbeatTicks();
1125
- messages = separateSilentHeartbeatTicks(messages, ticks.rows, this.name);
1118
+ // Silent heartbeat ticks and replies to a [Continue] turn store no
1119
+ // prompt row. Render each request-only turn before its response's first
1120
+ // surviving row, so the wire formatter cannot merge the response into the
1121
+ // previous assistant message and every later request keeps the prefix
1122
+ // the response was minted under (see silent-heartbeat.ts for what can
1123
+ // and cannot be matched). The request that minted the response ended on
1124
+ // that same turn, so the prefix it caches is the one every later compile
1125
+ // renders. "First" is per agent: a broadcast tick shares its eventId with
1126
+ // every resident.
1127
+ const index = this.indexRequestOnlyRows();
1128
+ const rendered = renderRequestOnlyRows(messages, index, this.name);
1129
+ messages = rendered.messages;
1130
+ // A tick opens wherever its separator isn't already rendered: on its first
1131
+ // request, and on a restart whose compile left none of the tick's rows,
1132
+ // so the restart's reply follows the separator, where every later compile
1133
+ // renders it.
1126
1134
  const openingTick = options.silentHeartbeat !== undefined
1127
- && !ticks.started.has(options.silentHeartbeat.eventId);
1135
+ && !rendered.separatedTicks.has(tickKey(options.silentHeartbeat));
1136
+ // The [Continue] prompt this request's reply follows, read from the
1137
+ // request itself: a new one when it ends on [Continue]; else, when it
1138
+ // ends on tool results, the prompt of the reply that called those tools,
1139
+ // whose tool loop this reply continues; else none. A request that ends
1140
+ // on anything else (a message that arrived during a cooldown, say) gets
1141
+ // a reply that follows that message and carries no prompt.
1142
+ let continuePrompt;
1128
1143
  if (openingTick) {
1129
1144
  messages = [...messages, silentHeartbeatSeparatorTurn()];
1130
1145
  }
@@ -1132,24 +1147,26 @@ export class Agent {
1132
1147
  // Safety: ensure messages don't end with an assistant message.
1133
1148
  // Some models reject trailing assistant messages ("prefill not supported"),
1134
1149
  // and after context compression a stale assistant turn can end up last.
1135
- messages = [...messages, {
1136
- participant: 'user',
1137
- content: [{ type: 'text', text: '[Continue]' }],
1138
- }];
1150
+ messages = [...messages, continueTurn()];
1151
+ continuePrompt = { turn: randomUUID(), text: CONTINUE_ROW };
1139
1152
  }
1140
- return {
1153
+ else {
1154
+ continuePrompt = toolLoopPrompt(messages.at(-1), index);
1155
+ }
1156
+ const request = {
1141
1157
  messages: this.toolResultGuard.prepareRequest(messages),
1142
1158
  system: this.buildSystemPrompt(systemInjections),
1143
1159
  tools: availableTools.length > 0 ? availableTools : undefined,
1144
1160
  ...this.requestSettings(),
1145
1161
  ...(kvUnified ? { cacheMarkers: 'cm-owned' } : {}),
1146
1162
  };
1163
+ return { request, ...(continuePrompt ? { continuePrompt } : {}) };
1147
1164
  }
1148
1165
  /**
1149
1166
  * The request fields that come from this agent's own settings: its model
1150
1167
  * config, prompt caching and cache TTL, prefill message, provider
1151
1168
  * parameters and participant name. Every request the agent sends takes
1152
- * them from here, a framework turn's (buildActivationRequest) and the
1169
+ * them from here, a framework turn's (assembleActivationRequest) and the
1153
1170
  * direct API's (runInferenceWithInjections), so a setting reaches both or
1154
1171
  * neither.
1155
1172
  */
@@ -1168,24 +1185,30 @@ export class Agent {
1168
1185
  assistantParticipant: this.name,
1169
1186
  };
1170
1187
  }
1171
- /** Stored silent-tick rows, memoized on the store's cached message array
1172
- * (ContextManager returns the same array until the store changes). */
1173
- silentTickIndex = null;
1174
- indexSilentHeartbeatTicks() {
1175
- const empty = { rows: new Map(), started: new Set() };
1188
+ /** The request `assembleActivationRequest` builds (see there), for preview
1189
+ * and debug tooling: what this agent's next activation would send. */
1190
+ async buildActivationRequest(availableTools, injections, budget, compressionTools = availableTools, options = {}) {
1191
+ return (await this.assembleActivationRequest(availableTools, injections, budget, compressionTools, options)).request;
1192
+ }
1193
+ /** Stored rows that follow a request-only turn, memoized on the store's
1194
+ * cached message array (ContextManager returns the same array until the
1195
+ * store changes). */
1196
+ requestOnlyIndex = null;
1197
+ indexRequestOnlyRows() {
1198
+ const empty = { ticks: new Map(), prompts: new Map() };
1176
1199
  const cm = this.contextManager;
1177
1200
  if (typeof cm.getAllMessages !== 'function')
1178
1201
  return empty;
1179
1202
  try {
1180
1203
  const stored = cm.getAllMessages();
1181
- if (this.silentTickIndex?.source === stored)
1182
- return this.silentTickIndex.index;
1183
- const index = indexSilentTickRows(stored, this.name);
1184
- this.silentTickIndex = { source: stored, index };
1204
+ if (this.requestOnlyIndex?.source === stored)
1205
+ return this.requestOnlyIndex.index;
1206
+ const index = indexRequestOnlyRows(stored, this.name);
1207
+ this.requestOnlyIndex = { source: stored, index };
1185
1208
  return index;
1186
1209
  }
1187
1210
  catch (error) {
1188
- console.error(`[silent-heartbeat] ${this.name}: could not index tick rows; separators omitted:`, error);
1211
+ console.error(`[request-only-rows] ${this.name}: could not index stored rows; request-only turns omitted:`, error);
1189
1212
  return empty;
1190
1213
  }
1191
1214
  }
@@ -1238,7 +1261,7 @@ export class Agent {
1238
1261
  // Compiled only once each withheld stub's annotation has finished,
1239
1262
  // including one that began during the compile, and after a stub edit that
1240
1263
  // failed has been retried (see afterAnnotations).
1241
- const request = await this.toolResultGuard.afterAnnotations(() => this.buildActivationRequest(availableTools, injections, budget, compressionTools, options));
1264
+ const { request, continuePrompt } = await this.toolResultGuard.afterAnnotations(() => this.assembleActivationRequest(availableTools, injections, budget, compressionTools, options));
1242
1265
  request.messages = this.toolResultGuard.prepareRequest(request.messages, true);
1243
1266
  const receiptAware = this.contextManager
1244
1267
  .getStrategy?.();
@@ -1281,6 +1304,7 @@ export class Agent {
1281
1304
  return {
1282
1305
  stream,
1283
1306
  request,
1307
+ ...(continuePrompt ? { continuePrompt } : {}),
1284
1308
  ...(kvEnabled
1285
1309
  ? {
1286
1310
  takeKvSubmission: () => kvQueue.shift(),
@@ -1369,20 +1393,40 @@ export class Agent {
1369
1393
  * report the cancel as `error` with no reason at all, so this record is
1370
1394
  * the only provenance a host-side cancel has. */
1371
1395
  _pendingCancel;
1396
+ /** The most recent cancelStream() made while this agent held no stream:
1397
+ * during a turn's hooks or compile, while it waits to retry, or while no
1398
+ * check of a turn is ahead at all. The framework collects it at the check
1399
+ * ahead of it, which ends the turn, and the next start drops one no check
1400
+ * collected, so a stop made while none was ahead, such as a host's
1401
+ * interrupt of every agent, ends nothing. */
1402
+ _stopWithoutStream;
1372
1403
  /**
1373
1404
  * Cancel the stream this agent's state holds (streaming, waiting on its
1374
1405
  * tools, or ready at a tool boundary with every result in), and reset to
1375
- * idle. `reason` is provenance for the framework's inference:aborted trace
1376
- * and marker metadata (e.g. 'zombie_reclaim', 'subagent_cancel'); it never
1377
- * reaches the provider.
1406
+ * idle. With no stream, the stop is kept for the turn in progress, which
1407
+ * the framework ends at its next check, before it sends anything more, if
1408
+ * one is still ahead; otherwise the next start drops it. `reason` is
1409
+ * provenance for the framework's inference:aborted trace and marker
1410
+ * metadata (e.g. 'zombie_reclaim', 'subagent_cancel'); it never reaches
1411
+ * the provider.
1378
1412
  */
1379
1413
  cancelStream(reason) {
1380
1414
  if ('stream' in this._state && this._state.stream) {
1381
1415
  this._pendingCancel = { reason };
1382
1416
  this._state.stream.cancel();
1383
1417
  }
1418
+ else {
1419
+ this._stopWithoutStream = { reason };
1420
+ }
1384
1421
  this._state = { status: 'idle' };
1385
1422
  }
1423
+ /** Collect (and clear) the cancelStream() made while this agent held no
1424
+ * stream, if one was made since the last collection. */
1425
+ takeStopWithoutStream() {
1426
+ const s = this._stopWithoutStream;
1427
+ this._stopWithoutStream = undefined;
1428
+ return s;
1429
+ }
1386
1430
  /** Collect (and clear) the cancel that ended the current stream, if this
1387
1431
  * side issued one. The stream driver calls it once, while the stream
1388
1432
  * still owns the agent, at the stream's terminal event (`aborted`