@animalabs/agent-framework 0.22.4 → 0.23.1

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 -4
  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":"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"}
package/dist/src/agent.js CHANGED
@@ -3,7 +3,8 @@ import { createHash } from 'node:crypto';
3
3
  import { ToolResultGuard } from './tool-result-guard.js';
4
4
  import { withoutTokenEstimates } from './thinking-token-stamp.js';
5
5
  import { assertBooleanSetting, holdsSettings } from './config-checks.js';
6
- import { indexSilentTickRows, separateSilentHeartbeatTicks, silentHeartbeatSeparatorTurn, } from './silent-heartbeat.js';
6
+ import { CONTINUE_ROW, continueTurn, indexRequestOnlyRows, renderRequestOnlyRows, silentHeartbeatSeparatorTurn, tickKey, toolLoopPrompt, } from './silent-heartbeat.js';
7
+ import { randomUUID } from 'node:crypto';
7
8
  import { nonErrorResultText, truncateForHistory, DEFAULT_TOOL_RESULT_INLINE_MAX_CHARS, } from './tool-result-history.js';
8
9
  function stableHash(value) {
9
10
  const encode = (item) => {
@@ -1070,7 +1071,7 @@ export class Agent {
1070
1071
  * may show a withheld stub before its place is added; the activation waits
1071
1072
  * for them around its call.
1072
1073
  */
1073
- async buildActivationRequest(availableTools, injections, budget, compressionTools = availableTools, options = {}) {
1074
+ async assembleActivationRequest(availableTools, injections, budget, compressionTools = availableTools, options = {}) {
1074
1075
  // Compression may revisit hidden tools in recorded history. Keep its full
1075
1076
  // definition set separate from the resident's advertised tools: the
1076
1077
  // autobiographical strategy must declare the same tools on its
@@ -1120,17 +1121,31 @@ export class Agent {
1120
1121
  .filter((m) => m.content.length > 0);
1121
1122
  // The framework's own pricing stamp never goes out (thinking-token-stamp.ts).
1122
1123
  messages = withoutTokenEstimates(messages);
1123
- // Silent heartbeat ticks store no prompt row. Render a request-only
1124
- // separator before each tick's first surviving row so the wire formatter
1125
- // cannot merge the tick into the previous assistant message (see
1126
- // silent-heartbeat.ts for what can and cannot be matched). This agent's
1127
- // own first request for a tick ends on that same turn, so the prefix it
1128
- // caches is the one every later compile renders. "First" is per agent: a
1129
- // broadcast tick shares its eventId with every resident.
1130
- const ticks = this.indexSilentHeartbeatTicks();
1131
- messages = separateSilentHeartbeatTicks(messages, ticks.rows, this.name);
1124
+ // Silent heartbeat ticks and replies to a [Continue] turn store no
1125
+ // prompt row. Render each request-only turn before its response's first
1126
+ // surviving row, so the wire formatter cannot merge the response into the
1127
+ // previous assistant message and every later request keeps the prefix
1128
+ // the response was minted under (see silent-heartbeat.ts for what can
1129
+ // and cannot be matched). The request that minted the response ended on
1130
+ // that same turn, so the prefix it caches is the one every later compile
1131
+ // renders. "First" is per agent: a broadcast tick shares its eventId with
1132
+ // every resident.
1133
+ const index = this.indexRequestOnlyRows();
1134
+ const rendered = renderRequestOnlyRows(messages, index, this.name);
1135
+ messages = rendered.messages;
1136
+ // A tick opens wherever its separator isn't already rendered: on its first
1137
+ // request, and on a restart whose compile left none of the tick's rows,
1138
+ // so the restart's reply follows the separator, where every later compile
1139
+ // renders it.
1132
1140
  const openingTick = options.silentHeartbeat !== undefined
1133
- && !ticks.started.has(options.silentHeartbeat.eventId);
1141
+ && !rendered.separatedTicks.has(tickKey(options.silentHeartbeat));
1142
+ // The [Continue] prompt this request's reply follows, read from the
1143
+ // request itself: a new one when it ends on [Continue]; else, when it
1144
+ // ends on tool results, the prompt of the reply that called those tools,
1145
+ // whose tool loop this reply continues; else none. A request that ends
1146
+ // on anything else (a message that arrived during a cooldown, say) gets
1147
+ // a reply that follows that message and carries no prompt.
1148
+ let continuePrompt;
1134
1149
  if (openingTick) {
1135
1150
  messages = [...messages, silentHeartbeatSeparatorTurn()];
1136
1151
  }
@@ -1138,24 +1153,26 @@ export class Agent {
1138
1153
  // Safety: ensure messages don't end with an assistant message.
1139
1154
  // Some models reject trailing assistant messages ("prefill not supported"),
1140
1155
  // and after context compression a stale assistant turn can end up last.
1141
- messages = [...messages, {
1142
- participant: 'user',
1143
- content: [{ type: 'text', text: '[Continue]' }],
1144
- }];
1156
+ messages = [...messages, continueTurn()];
1157
+ continuePrompt = { turn: randomUUID(), text: CONTINUE_ROW };
1145
1158
  }
1146
- return {
1159
+ else {
1160
+ continuePrompt = toolLoopPrompt(messages.at(-1), index);
1161
+ }
1162
+ const request = {
1147
1163
  messages: this.toolResultGuard.prepareRequest(messages),
1148
1164
  system: this.buildSystemPrompt(systemInjections),
1149
1165
  tools: availableTools.length > 0 ? availableTools : undefined,
1150
1166
  ...this.requestSettings(),
1151
1167
  ...(kvUnified ? { cacheMarkers: 'cm-owned' } : {}),
1152
1168
  };
1169
+ return { request, ...(continuePrompt ? { continuePrompt } : {}) };
1153
1170
  }
1154
1171
  /**
1155
1172
  * The request fields that come from this agent's own settings: its model
1156
1173
  * config, prompt caching and cache TTL, prefill message, provider
1157
1174
  * parameters and participant name. Every request the agent sends takes
1158
- * them from here, a framework turn's (buildActivationRequest) and the
1175
+ * them from here, a framework turn's (assembleActivationRequest) and the
1159
1176
  * direct API's (runInferenceWithInjections), so a setting reaches both or
1160
1177
  * neither.
1161
1178
  */
@@ -1174,24 +1191,30 @@ export class Agent {
1174
1191
  assistantParticipant: this.name,
1175
1192
  };
1176
1193
  }
1177
- /** Stored silent-tick rows, memoized on the store's cached message array
1178
- * (ContextManager returns the same array until the store changes). */
1179
- silentTickIndex = null;
1180
- indexSilentHeartbeatTicks() {
1181
- const empty = { rows: new Map(), started: new Set() };
1194
+ /** The request `assembleActivationRequest` builds (see there), for preview
1195
+ * and debug tooling: what this agent's next activation would send. */
1196
+ async buildActivationRequest(availableTools, injections, budget, compressionTools = availableTools, options = {}) {
1197
+ return (await this.assembleActivationRequest(availableTools, injections, budget, compressionTools, options)).request;
1198
+ }
1199
+ /** Stored rows that follow a request-only turn, memoized on the store's
1200
+ * cached message array (ContextManager returns the same array until the
1201
+ * store changes). */
1202
+ requestOnlyIndex = null;
1203
+ indexRequestOnlyRows() {
1204
+ const empty = { ticks: new Map(), prompts: new Map() };
1182
1205
  const cm = this.contextManager;
1183
1206
  if (typeof cm.getAllMessages !== 'function')
1184
1207
  return empty;
1185
1208
  try {
1186
1209
  const stored = cm.getAllMessages();
1187
- if (this.silentTickIndex?.source === stored)
1188
- return this.silentTickIndex.index;
1189
- const index = indexSilentTickRows(stored, this.name);
1190
- this.silentTickIndex = { source: stored, index };
1210
+ if (this.requestOnlyIndex?.source === stored)
1211
+ return this.requestOnlyIndex.index;
1212
+ const index = indexRequestOnlyRows(stored, this.name);
1213
+ this.requestOnlyIndex = { source: stored, index };
1191
1214
  return index;
1192
1215
  }
1193
1216
  catch (error) {
1194
- console.error(`[silent-heartbeat] ${this.name}: could not index tick rows; separators omitted:`, error);
1217
+ console.error(`[request-only-rows] ${this.name}: could not index stored rows; request-only turns omitted:`, error);
1195
1218
  return empty;
1196
1219
  }
1197
1220
  }
@@ -1244,7 +1267,7 @@ export class Agent {
1244
1267
  // Compiled only once each withheld stub's annotation has finished,
1245
1268
  // including one that began during the compile, and after a stub edit that
1246
1269
  // failed has been retried (see afterAnnotations).
1247
- const request = await this.toolResultGuard.afterAnnotations(() => this.buildActivationRequest(availableTools, injections, budget, compressionTools, options));
1270
+ const { request, continuePrompt } = await this.toolResultGuard.afterAnnotations(() => this.assembleActivationRequest(availableTools, injections, budget, compressionTools, options));
1248
1271
  request.messages = this.toolResultGuard.prepareRequest(request.messages, true);
1249
1272
  const receiptAware = this.contextManager
1250
1273
  .getStrategy?.();
@@ -1287,6 +1310,7 @@ export class Agent {
1287
1310
  return {
1288
1311
  stream,
1289
1312
  request,
1313
+ ...(continuePrompt ? { continuePrompt } : {}),
1290
1314
  ...(kvEnabled
1291
1315
  ? {
1292
1316
  takeKvSubmission: () => kvQueue.shift(),
@@ -1375,20 +1399,40 @@ export class Agent {
1375
1399
  * report the cancel as `error` with no reason at all, so this record is
1376
1400
  * the only provenance a host-side cancel has. */
1377
1401
  _pendingCancel;
1402
+ /** The most recent cancelStream() made while this agent held no stream:
1403
+ * during a turn's hooks or compile, while it waits to retry, or while no
1404
+ * check of a turn is ahead at all. The framework collects it at the check
1405
+ * ahead of it, which ends the turn, and the next start drops one no check
1406
+ * collected, so a stop made while none was ahead, such as a host's
1407
+ * interrupt of every agent, ends nothing. */
1408
+ _stopWithoutStream;
1378
1409
  /**
1379
1410
  * Cancel the stream this agent's state holds (streaming, waiting on its
1380
1411
  * tools, or ready at a tool boundary with every result in), and reset to
1381
- * idle. `reason` is provenance for the framework's inference:aborted trace
1382
- * and marker metadata (e.g. 'zombie_reclaim', 'subagent_cancel'); it never
1383
- * reaches the provider.
1412
+ * idle. With no stream, the stop is kept for the turn in progress, which
1413
+ * the framework ends at its next check, before it sends anything more, if
1414
+ * one is still ahead; otherwise the next start drops it. `reason` is
1415
+ * provenance for the framework's inference:aborted trace and marker
1416
+ * metadata (e.g. 'zombie_reclaim', 'subagent_cancel'); it never reaches
1417
+ * the provider.
1384
1418
  */
1385
1419
  cancelStream(reason) {
1386
1420
  if ('stream' in this._state && this._state.stream) {
1387
1421
  this._pendingCancel = { reason };
1388
1422
  this._state.stream.cancel();
1389
1423
  }
1424
+ else {
1425
+ this._stopWithoutStream = { reason };
1426
+ }
1390
1427
  this._state = { status: 'idle' };
1391
1428
  }
1429
+ /** Collect (and clear) the cancelStream() made while this agent held no
1430
+ * stream, if one was made since the last collection. */
1431
+ takeStopWithoutStream() {
1432
+ const s = this._stopWithoutStream;
1433
+ this._stopWithoutStream = undefined;
1434
+ return s;
1435
+ }
1392
1436
  /** Collect (and clear) the cancel that ended the current stream, if this
1393
1437
  * side issued one. The stream driver calls it once, while the stream
1394
1438
  * still owns the agent, at the stream's terminal event (`aborted`