@animalabs/agent-framework 0.27.0 → 0.28.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 +56 -15
  2. package/dist/src/agent.d.ts +29 -2
  3. package/dist/src/agent.d.ts.map +1 -1
  4. package/dist/src/agent.js +69 -11
  5. package/dist/src/agent.js.map +1 -1
  6. package/dist/src/api/server.d.ts.map +1 -1
  7. package/dist/src/api/server.js +4 -2
  8. package/dist/src/api/server.js.map +1 -1
  9. package/dist/src/auto-continue.d.ts +3 -2
  10. package/dist/src/auto-continue.d.ts.map +1 -1
  11. package/dist/src/auto-continue.js +4 -3
  12. package/dist/src/auto-continue.js.map +1 -1
  13. package/dist/src/cut-off-round.d.ts +24 -0
  14. package/dist/src/cut-off-round.d.ts.map +1 -0
  15. package/dist/src/cut-off-round.js +87 -0
  16. package/dist/src/cut-off-round.js.map +1 -0
  17. package/dist/src/framework.d.ts +304 -89
  18. package/dist/src/framework.d.ts.map +1 -1
  19. package/dist/src/framework.js +2577 -678
  20. package/dist/src/framework.js.map +1 -1
  21. package/dist/src/gate/event-gate.d.ts +99 -3
  22. package/dist/src/gate/event-gate.d.ts.map +1 -1
  23. package/dist/src/gate/event-gate.js +538 -13
  24. package/dist/src/gate/event-gate.js.map +1 -1
  25. package/dist/src/gate/index.d.ts +2 -1
  26. package/dist/src/gate/index.d.ts.map +1 -1
  27. package/dist/src/gate/index.js +1 -0
  28. package/dist/src/gate/index.js.map +1 -1
  29. package/dist/src/gate/reply-judge.d.ts +116 -0
  30. package/dist/src/gate/reply-judge.d.ts.map +1 -0
  31. package/dist/src/gate/reply-judge.js +467 -0
  32. package/dist/src/gate/reply-judge.js.map +1 -0
  33. package/dist/src/gate/types.d.ts +161 -0
  34. package/dist/src/gate/types.d.ts.map +1 -1
  35. package/dist/src/heartbeat/heartbeat.d.ts +184 -0
  36. package/dist/src/heartbeat/heartbeat.d.ts.map +1 -0
  37. package/dist/src/heartbeat/heartbeat.js +752 -0
  38. package/dist/src/heartbeat/heartbeat.js.map +1 -0
  39. package/dist/src/heartbeat/reminder-time.d.ts +5 -0
  40. package/dist/src/heartbeat/reminder-time.d.ts.map +1 -0
  41. package/dist/src/heartbeat/reminder-time.js +107 -0
  42. package/dist/src/heartbeat/reminder-time.js.map +1 -0
  43. package/dist/src/index.d.ts +4 -0
  44. package/dist/src/index.d.ts.map +1 -1
  45. package/dist/src/index.js +2 -0
  46. package/dist/src/index.js.map +1 -1
  47. package/dist/src/mcpl/capability-mask.d.ts.map +1 -1
  48. package/dist/src/mcpl/capability-mask.js +3 -2
  49. package/dist/src/mcpl/capability-mask.js.map +1 -1
  50. package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
  51. package/dist/src/mcpl/channel-registry.js +2 -1
  52. package/dist/src/mcpl/channel-registry.js.map +1 -1
  53. package/dist/src/mcpl/inbound-source.d.ts +26 -10
  54. package/dist/src/mcpl/inbound-source.d.ts.map +1 -1
  55. package/dist/src/mcpl/inbound-source.js +40 -69
  56. package/dist/src/mcpl/inbound-source.js.map +1 -1
  57. package/dist/src/mcpl/server-connection.d.ts +18 -8
  58. package/dist/src/mcpl/server-connection.d.ts.map +1 -1
  59. package/dist/src/mcpl/server-connection.js +50 -10
  60. package/dist/src/mcpl/server-connection.js.map +1 -1
  61. package/dist/src/mcpl/tags.d.ts +9 -2
  62. package/dist/src/mcpl/tags.d.ts.map +1 -1
  63. package/dist/src/mcpl/tags.js +12 -2
  64. package/dist/src/mcpl/tags.js.map +1 -1
  65. package/dist/src/mcpl/tool-presence.d.ts +66 -14
  66. package/dist/src/mcpl/tool-presence.d.ts.map +1 -1
  67. package/dist/src/mcpl/tool-presence.js +134 -65
  68. package/dist/src/mcpl/tool-presence.js.map +1 -1
  69. package/dist/src/mcpl/tool-signature.d.ts +10 -3
  70. package/dist/src/mcpl/tool-signature.d.ts.map +1 -1
  71. package/dist/src/mcpl/tool-signature.js +47 -18
  72. package/dist/src/mcpl/tool-signature.js.map +1 -1
  73. package/dist/src/mcpl/toolset-host.d.ts +88 -37
  74. package/dist/src/mcpl/toolset-host.d.ts.map +1 -1
  75. package/dist/src/mcpl/toolset-host.js +207 -108
  76. package/dist/src/mcpl/toolset-host.js.map +1 -1
  77. package/dist/src/mcpl/toolsets-module.d.ts +14 -11
  78. package/dist/src/mcpl/toolsets-module.d.ts.map +1 -1
  79. package/dist/src/mcpl/toolsets-module.js +141 -49
  80. package/dist/src/mcpl/toolsets-module.js.map +1 -1
  81. package/dist/src/mcpl/types.d.ts +3 -1
  82. package/dist/src/mcpl/types.d.ts.map +1 -1
  83. package/dist/src/mcpl/types.js.map +1 -1
  84. package/dist/src/module-registry.d.ts +4 -1
  85. package/dist/src/module-registry.d.ts.map +1 -1
  86. package/dist/src/module-registry.js +9 -2
  87. package/dist/src/module-registry.js.map +1 -1
  88. package/dist/src/modules/history/index.d.ts.map +1 -1
  89. package/dist/src/modules/history/index.js +22 -11
  90. package/dist/src/modules/history/index.js.map +1 -1
  91. package/dist/src/modules/workspace/answers.d.ts +22 -0
  92. package/dist/src/modules/workspace/answers.d.ts.map +1 -0
  93. package/dist/src/modules/workspace/answers.js +123 -0
  94. package/dist/src/modules/workspace/answers.js.map +1 -0
  95. package/dist/src/modules/workspace/branch-intent.d.ts +5 -3
  96. package/dist/src/modules/workspace/branch-intent.d.ts.map +1 -1
  97. package/dist/src/modules/workspace/branch-intent.js +6 -2
  98. package/dist/src/modules/workspace/branch-intent.js.map +1 -1
  99. package/dist/src/modules/workspace/direct-write.d.ts +3 -0
  100. package/dist/src/modules/workspace/direct-write.d.ts.map +1 -1
  101. package/dist/src/modules/workspace/direct-write.js +57 -24
  102. package/dist/src/modules/workspace/direct-write.js.map +1 -1
  103. package/dist/src/modules/workspace/disk-agreement.d.ts +33 -11
  104. package/dist/src/modules/workspace/disk-agreement.d.ts.map +1 -1
  105. package/dist/src/modules/workspace/disk-agreement.js +48 -17
  106. package/dist/src/modules/workspace/disk-agreement.js.map +1 -1
  107. package/dist/src/modules/workspace/edit-text.d.ts +2 -1
  108. package/dist/src/modules/workspace/edit-text.d.ts.map +1 -1
  109. package/dist/src/modules/workspace/edit-text.js +4 -2
  110. package/dist/src/modules/workspace/edit-text.js.map +1 -1
  111. package/dist/src/modules/workspace/effects.d.ts.map +1 -1
  112. package/dist/src/modules/workspace/effects.js +20 -13
  113. package/dist/src/modules/workspace/effects.js.map +1 -1
  114. package/dist/src/modules/workspace/index.d.ts +62 -51
  115. package/dist/src/modules/workspace/index.d.ts.map +1 -1
  116. package/dist/src/modules/workspace/index.js +934 -531
  117. package/dist/src/modules/workspace/index.js.map +1 -1
  118. package/dist/src/modules/workspace/observe.d.ts +75 -63
  119. package/dist/src/modules/workspace/observe.d.ts.map +1 -1
  120. package/dist/src/modules/workspace/observe.js +366 -180
  121. package/dist/src/modules/workspace/observe.js.map +1 -1
  122. package/dist/src/modules/workspace/read-page.d.ts.map +1 -1
  123. package/dist/src/modules/workspace/read-page.js +7 -1
  124. package/dist/src/modules/workspace/read-page.js.map +1 -1
  125. package/dist/src/modules/workspace/reconcile.d.ts.map +1 -1
  126. package/dist/src/modules/workspace/reconcile.js +26 -16
  127. package/dist/src/modules/workspace/reconcile.js.map +1 -1
  128. package/dist/src/modules/workspace/result-text.d.ts +1 -0
  129. package/dist/src/modules/workspace/result-text.d.ts.map +1 -1
  130. package/dist/src/modules/workspace/result-text.js.map +1 -1
  131. package/dist/src/modules/workspace/sync.d.ts +9 -0
  132. package/dist/src/modules/workspace/sync.d.ts.map +1 -1
  133. package/dist/src/modules/workspace/sync.js +14 -0
  134. package/dist/src/modules/workspace/sync.js.map +1 -1
  135. package/dist/src/modules/workspace/types.d.ts +96 -43
  136. package/dist/src/modules/workspace/types.d.ts.map +1 -1
  137. package/dist/src/modules/workspace/types.js.map +1 -1
  138. package/dist/src/modules/workspace/watcher.d.ts.map +1 -1
  139. package/dist/src/modules/workspace/watcher.js +8 -3
  140. package/dist/src/modules/workspace/watcher.js.map +1 -1
  141. package/dist/src/prose-drafts.d.ts +4 -3
  142. package/dist/src/prose-drafts.d.ts.map +1 -1
  143. package/dist/src/prose-drafts.js +3 -2
  144. package/dist/src/prose-drafts.js.map +1 -1
  145. package/dist/src/reasoning-loss-notice.d.ts +23 -0
  146. package/dist/src/reasoning-loss-notice.d.ts.map +1 -0
  147. package/dist/src/reasoning-loss-notice.js +50 -0
  148. package/dist/src/reasoning-loss-notice.js.map +1 -0
  149. package/dist/src/reasoning-loss.d.ts +24 -0
  150. package/dist/src/reasoning-loss.d.ts.map +1 -0
  151. package/dist/src/reasoning-loss.js +102 -0
  152. package/dist/src/reasoning-loss.js.map +1 -0
  153. package/dist/src/send-tools.d.ts +3 -2
  154. package/dist/src/send-tools.d.ts.map +1 -1
  155. package/dist/src/send-tools.js +3 -2
  156. package/dist/src/send-tools.js.map +1 -1
  157. package/dist/src/sent-rows.js +1 -1
  158. package/dist/src/thinking-drops.d.ts +4 -11
  159. package/dist/src/thinking-drops.d.ts.map +1 -1
  160. package/dist/src/thinking-drops.js +7 -14
  161. package/dist/src/thinking-drops.js.map +1 -1
  162. package/dist/src/tool-args.d.ts +12 -0
  163. package/dist/src/tool-args.d.ts.map +1 -1
  164. package/dist/src/tool-args.js +35 -1
  165. package/dist/src/tool-args.js.map +1 -1
  166. package/dist/src/tool-result-guard.d.ts +8 -4
  167. package/dist/src/tool-result-guard.d.ts.map +1 -1
  168. package/dist/src/tool-result-guard.js +23 -11
  169. package/dist/src/tool-result-guard.js.map +1 -1
  170. package/dist/src/tune-out/tools.d.ts +4 -1
  171. package/dist/src/tune-out/tools.d.ts.map +1 -1
  172. package/dist/src/types/agent.d.ts +40 -9
  173. package/dist/src/types/agent.d.ts.map +1 -1
  174. package/dist/src/types/events.d.ts +18 -8
  175. package/dist/src/types/events.d.ts.map +1 -1
  176. package/dist/src/types/framework.d.ts +15 -0
  177. package/dist/src/types/framework.d.ts.map +1 -1
  178. package/dist/src/types/module.d.ts +5 -2
  179. package/dist/src/types/module.d.ts.map +1 -1
  180. package/dist/src/types/trace.d.ts +34 -1
  181. package/dist/src/types/trace.d.ts.map +1 -1
  182. package/package.json +3 -3
  183. package/src/agent.ts +72 -11
  184. package/src/api/server.ts +4 -2
  185. package/src/auto-continue.ts +4 -3
  186. package/src/cut-off-round.ts +98 -0
  187. package/src/framework.ts +2694 -700
  188. package/src/gate/event-gate.ts +579 -15
  189. package/src/gate/index.ts +8 -0
  190. package/src/gate/reply-judge.ts +512 -0
  191. package/src/gate/types.ts +164 -1
  192. package/src/heartbeat/heartbeat.ts +804 -0
  193. package/src/heartbeat/reminder-time.ts +107 -0
  194. package/src/index.ts +4 -0
  195. package/src/mcpl/capability-mask.ts +3 -2
  196. package/src/mcpl/channel-registry.ts +2 -1
  197. package/src/mcpl/inbound-source.ts +42 -69
  198. package/src/mcpl/server-connection.ts +56 -16
  199. package/src/mcpl/tags.ts +13 -2
  200. package/src/mcpl/tool-presence.ts +133 -67
  201. package/src/mcpl/tool-signature.ts +51 -20
  202. package/src/mcpl/toolset-host.ts +197 -107
  203. package/src/mcpl/toolsets-module.ts +143 -49
  204. package/src/mcpl/types.ts +3 -1
  205. package/src/module-registry.ts +8 -2
  206. package/src/modules/history/index.ts +22 -12
  207. package/src/modules/workspace/answers.ts +133 -0
  208. package/src/modules/workspace/branch-intent.ts +10 -5
  209. package/src/modules/workspace/direct-write.ts +58 -23
  210. package/src/modules/workspace/disk-agreement.ts +52 -21
  211. package/src/modules/workspace/edit-text.ts +7 -5
  212. package/src/modules/workspace/effects.ts +21 -12
  213. package/src/modules/workspace/index.ts +927 -541
  214. package/src/modules/workspace/observe.ts +381 -177
  215. package/src/modules/workspace/read-page.ts +7 -1
  216. package/src/modules/workspace/reconcile.ts +27 -15
  217. package/src/modules/workspace/result-text.ts +2 -0
  218. package/src/modules/workspace/sync.ts +16 -0
  219. package/src/modules/workspace/types.ts +96 -43
  220. package/src/modules/workspace/watcher.ts +8 -3
  221. package/src/prose-drafts.ts +4 -3
  222. package/src/reasoning-loss-notice.ts +62 -0
  223. package/src/reasoning-loss.ts +120 -0
  224. package/src/send-tools.ts +3 -2
  225. package/src/sent-rows.ts +1 -1
  226. package/src/thinking-drops.ts +10 -16
  227. package/src/tool-args.ts +34 -1
  228. package/src/tool-result-guard.ts +26 -11
  229. package/src/tune-out/tools.ts +4 -1
  230. package/src/types/agent.ts +40 -9
  231. package/src/types/events.ts +18 -8
  232. package/src/types/framework.ts +15 -0
  233. package/src/types/module.ts +5 -2
  234. package/src/types/trace.ts +36 -1
package/src/gate/types.ts CHANGED
@@ -55,6 +55,39 @@ export interface PassiveSampleConfig {
55
55
  keyBy?: string;
56
56
  }
57
57
 
58
+ /**
59
+ * Configuration for the `judge` behavior: batch matching events as `debounce`
60
+ * does, then, instead of waking the agent when the batch fires, ask a small,
61
+ * cheap model (the host's reply judge, `GateOptions.judge`) whether now is a
62
+ * good time for the agent to reply. The judge reads the agent's context as one
63
+ * document (its newest part), the agent's own `instructions` and the batch,
64
+ * and answers reply or wait. On reply the
65
+ * batch is delivered as a debounce's is; on wait the agent isn't woken: the
66
+ * events are in its context already, as for `defer`, and the next batch is
67
+ * judged afresh. Rules are read in order, as ever: a mention rule placed ahead
68
+ * of a judge rule wakes the agent without the judge. A judge that fails or
69
+ * times out wakes the agent (fail open),
70
+ * unless the host set its `onError` to `"skip"`.
71
+ */
72
+ export interface JudgeConfig {
73
+ /** Quiet period (ms) before the batch is judged, as `debounce`'s. */
74
+ debounceMs: number;
75
+ /**
76
+ * The longest (ms) a batch waits from its first event before it's judged,
77
+ * even while events keep arriving and pushing the quiet period back. Left
78
+ * out, a batch is judged only after `debounceMs` of quiet, as a debounce
79
+ * delivers.
80
+ */
81
+ maxWaitMs?: number;
82
+ /**
83
+ * The agent's own word to the judge: when it wants to be woken and when it
84
+ * would rather stay quiet ("wake me when someone asks me something or the
85
+ * talk turns to the garden; let banter between others go by"). Shown to the
86
+ * judge with every batch this rule sends it.
87
+ */
88
+ instructions?: string;
89
+ }
90
+
58
91
  /** How a matching policy affects inference triggering. */
59
92
  export type GateBehavior =
60
93
  | 'always' // Trigger inference immediately
@@ -62,7 +95,8 @@ export type GateBehavior =
62
95
  | 'skip' // Legacy alias for 'defer' (still accepted).
63
96
  | { debounce: number } // Batch events per-policy, deliver after delay (ms)
64
97
  | { rate_limit: RateLimitConfig } // Token bucket per `keyBy`; deny when empty
65
- | { passive_sample: PassiveSampleConfig }; // Fire every Nth match
98
+ | { passive_sample: PassiveSampleConfig } // Fire every Nth match
99
+ | { judge: JudgeConfig }; // Batch like debounce, then ask the reply judge
66
100
 
67
101
  // ---------------------------------------------------------------------------
68
102
  // Policy match criteria
@@ -185,8 +219,117 @@ export interface GateOptions {
185
219
  * missing, no one bypasses sleep.
186
220
  */
187
221
  privilegedUsersPath?: string;
222
+ /** The reply judge that `judge` rules ask (see JudgeConfig). Left out (or
223
+ * null), the judge is wired with its defaults; it runs only for `judge`
224
+ * rules, so a gate with none makes no judge calls. */
225
+ judge?: ReplyJudgeOptions | null;
188
226
  }
189
227
 
228
+ /**
229
+ * Host options for the reply judge, the small model `judge` rules ask whether
230
+ * now is a good time for the agent to reply. The host sets the model and how
231
+ * the judge runs, not the agent: an agent's rule says when to ask and what to
232
+ * say.
233
+ */
234
+ export interface ReplyJudgeOptions {
235
+ /** False leaves the judge unwired: `wake_add_rule` then offers no `judge`,
236
+ * and a `judge` rule in gate.json wakes the agent as a debounce of its
237
+ * `debounceMs` would, which gate_status says. Default true. */
238
+ enabled?: boolean;
239
+ /** The model the judge runs on, as the host's membrane names it. Default
240
+ * `claude-haiku-5-5`. */
241
+ model?: string;
242
+ /**
243
+ * The most input tokens one judge request may carry, its instructions and
244
+ * the batch included; the context document is cut from its oldest end to
245
+ * fit. Default 90,000: Claude Haiku 5.5 costs five times as much past
246
+ * 100,000 input tokens, and the margin covers the estimate's error. The
247
+ * least is 4,000, a short tail of the conversation: cheaper and quicker,
248
+ * with less of the room's history to weigh.
249
+ */
250
+ maxInputTokens?: number;
251
+ /** The longest (ms) a judge request may take before the batch is decided by
252
+ * `onError`. Default 20,000. */
253
+ timeoutMs?: number;
254
+ /** What a judge that fails, times out or answers unreadably does: `"wake"`
255
+ * wakes the agent as a debounce would (the default, so a judge outage
256
+ * never silences the agent); `"skip"` doesn't. */
257
+ onError?: 'wake' | 'skip';
258
+ /** The judge's effort (`output_config.effort`). Default `"low"`: a short
259
+ * verdict, quickly. `"none"` sends no effort, for a provider that doesn't
260
+ * take Anthropic's `output_config`. */
261
+ effort?: 'low' | 'medium' | 'high' | 'none';
262
+ /** The prompt cache's lifetime for the judge's context document. `"5m"`
263
+ * (the default) suits judge rules that fire minutes apart; `"1h"` costs
264
+ * more to write and suits ones that fire less often. */
265
+ cacheTtl?: '5m' | '1h';
266
+ }
267
+
268
+ /** One event of a batch, as the reply judge is shown it. */
269
+ export interface JudgeEventSummary {
270
+ eventType: string;
271
+ /** The channel as the agent is shown it, when the event named one. */
272
+ channel?: string;
273
+ /** The author's id, when the event named one. */
274
+ authorId?: string;
275
+ /** Whether the event addressed the agent (mention, reply, DM). */
276
+ addressed: boolean;
277
+ /** The event's text, cut short when long. */
278
+ content: string;
279
+ /** When the event arrived (ms). */
280
+ at: number;
281
+ }
282
+
283
+ /**
284
+ * Something that will (or, for a batch going to the judge, may) wake the
285
+ * agent with no new event: what the judge is told would happen if it answers
286
+ * wait and nothing else arrives.
287
+ */
288
+ export interface UpcomingWake {
289
+ /** When (ms), when known; absent for one due as soon as the agent is free. */
290
+ at?: number;
291
+ /** False when it only may wake the agent (a judge rule's batch goes to the judge then). */
292
+ certain: boolean;
293
+ /** What it is, as the judge is told ("its own skip_reply timer"). */
294
+ what: string;
295
+ }
296
+
297
+ /** What the gate asks the reply judge for one batch. */
298
+ export interface JudgeRequest {
299
+ /** The rule whose batch this is. */
300
+ policyName: string;
301
+ /** The rule's `instructions`, the agent's own word to the judge. */
302
+ instructions?: string;
303
+ /** The batch, oldest first. */
304
+ events: JudgeEventSummary[];
305
+ /** The agents the batch would wake. */
306
+ agentNames: string[];
307
+ /** The gate's own timers that will wake those agents with no new event
308
+ * (upcomingWakes): their self-wakes, a sleep's end, other rules' pending
309
+ * batches. The judge adds what the framework knows besides. */
310
+ upcomingWakes?: UpcomingWake[];
311
+ /** Aborted when the judge's time is up or the gate is disposed. */
312
+ signal: AbortSignal;
313
+ }
314
+
315
+ /** The reply judge's answer for one batch. */
316
+ export interface JudgeVerdict {
317
+ /** True: wake the agent now. False: let the batch go by. */
318
+ reply: boolean;
319
+ /** The judge's one-line reason. */
320
+ reason: string;
321
+ /** The model that answered. */
322
+ model?: string;
323
+ /** Input tokens the request carried (all of them: uncached, cache reads and writes). */
324
+ inputTokens?: number;
325
+ /** Of those, the tokens read from the prompt cache. */
326
+ cacheReadTokens?: number;
327
+ outputTokens?: number;
328
+ }
329
+
330
+ /** The judge's function, as the framework wires it into the gate. */
331
+ export type JudgeFn = (request: JudgeRequest) => Promise<JudgeVerdict>;
332
+
190
333
  // ---------------------------------------------------------------------------
191
334
  // Runtime types (internal to EventGate, exported for tests/tools)
192
335
  // ---------------------------------------------------------------------------
@@ -313,6 +456,26 @@ export interface GatePolicyStats {
313
456
  counterCount: number;
314
457
  fireCount: number;
315
458
  };
459
+ /** Present for `judge` behaviors. */
460
+ judgeState?: {
461
+ /** Events in the batch still waiting out its quiet period. */
462
+ pendingCount: number;
463
+ /** Whether the judge is deciding one of this rule's batches now. */
464
+ judging: boolean;
465
+ /** Events held for the judge until the agent's turn (or the host's quiesce) ends. */
466
+ heldCount: number;
467
+ /** Verdicts so far: woke the agent, let the batch go by, and judge failures. */
468
+ verdicts: { reply: number; wait: number; error: number };
469
+ /** The newest verdict. */
470
+ last?: {
471
+ at: number;
472
+ verdict: 'reply' | 'wait' | 'error';
473
+ reason: string;
474
+ eventCount: number;
475
+ durationMs: number;
476
+ inputTokens?: number;
477
+ };
478
+ };
316
479
  }
317
480
 
318
481
  /** Full gate status returned by gate:status tool. */