@animalabs/agent-framework 0.30.0 → 0.32.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 (189) hide show
  1. package/README.md +71 -8
  2. package/dist/src/agent.d.ts +29 -9
  3. package/dist/src/agent.d.ts.map +1 -1
  4. package/dist/src/agent.js +82 -17
  5. package/dist/src/agent.js.map +1 -1
  6. package/dist/src/api/mcp-server-core.d.ts.map +1 -1
  7. package/dist/src/api/mcp-server-core.js +10 -3
  8. package/dist/src/api/mcp-server-core.js.map +1 -1
  9. package/dist/src/code-execution/isolate/render.d.ts.map +1 -1
  10. package/dist/src/code-execution/isolate/render.js +7 -6
  11. package/dist/src/code-execution/isolate/render.js.map +1 -1
  12. package/dist/src/code-execution/isolate/scripts.d.ts.map +1 -1
  13. package/dist/src/code-execution/isolate/scripts.js +5 -4
  14. package/dist/src/code-execution/isolate/scripts.js.map +1 -1
  15. package/dist/src/framework.d.ts +138 -102
  16. package/dist/src/framework.d.ts.map +1 -1
  17. package/dist/src/framework.js +1133 -752
  18. package/dist/src/framework.js.map +1 -1
  19. package/dist/src/gate/event-gate.d.ts +24 -17
  20. package/dist/src/gate/event-gate.d.ts.map +1 -1
  21. package/dist/src/gate/event-gate.js +198 -144
  22. package/dist/src/gate/event-gate.js.map +1 -1
  23. package/dist/src/gate/recipe-reconcile.d.ts.map +1 -1
  24. package/dist/src/gate/recipe-reconcile.js +6 -5
  25. package/dist/src/gate/recipe-reconcile.js.map +1 -1
  26. package/dist/src/host-presentation.d.ts.map +1 -1
  27. package/dist/src/host-presentation.js +5 -7
  28. package/dist/src/host-presentation.js.map +1 -1
  29. package/dist/src/index.d.ts +1 -0
  30. package/dist/src/index.d.ts.map +1 -1
  31. package/dist/src/index.js +1 -0
  32. package/dist/src/index.js.map +1 -1
  33. package/dist/src/inference-bounds.d.ts +37 -0
  34. package/dist/src/inference-bounds.d.ts.map +1 -0
  35. package/dist/src/inference-bounds.js +84 -0
  36. package/dist/src/inference-bounds.js.map +1 -0
  37. package/dist/src/line-reader.d.ts +7 -1
  38. package/dist/src/line-reader.d.ts.map +1 -1
  39. package/dist/src/line-reader.js +17 -6
  40. package/dist/src/line-reader.js.map +1 -1
  41. package/dist/src/mcpl/errors.d.ts +1 -0
  42. package/dist/src/mcpl/errors.d.ts.map +1 -1
  43. package/dist/src/mcpl/errors.js +3 -0
  44. package/dist/src/mcpl/errors.js.map +1 -1
  45. package/dist/src/mcpl/inbound-source.d.ts +2 -2
  46. package/dist/src/mcpl/inbound-source.js +2 -2
  47. package/dist/src/mcpl/inference-router.d.ts +11 -1
  48. package/dist/src/mcpl/inference-router.d.ts.map +1 -1
  49. package/dist/src/mcpl/inference-router.js +65 -9
  50. package/dist/src/mcpl/inference-router.js.map +1 -1
  51. package/dist/src/mcpl/modern-connection.d.ts +10 -7
  52. package/dist/src/mcpl/modern-connection.d.ts.map +1 -1
  53. package/dist/src/mcpl/modern-connection.js +85 -74
  54. package/dist/src/mcpl/modern-connection.js.map +1 -1
  55. package/dist/src/mcpl/protocol-family.d.ts +1 -1
  56. package/dist/src/mcpl/protocol-family.d.ts.map +1 -1
  57. package/dist/src/mcpl/protocol-family.js +45 -3
  58. package/dist/src/mcpl/protocol-family.js.map +1 -1
  59. package/dist/src/mcpl/push-coalescer.d.ts +2 -7
  60. package/dist/src/mcpl/push-coalescer.d.ts.map +1 -1
  61. package/dist/src/mcpl/push-coalescer.js.map +1 -1
  62. package/dist/src/mcpl/references.d.ts +1 -2
  63. package/dist/src/mcpl/references.d.ts.map +1 -1
  64. package/dist/src/mcpl/references.js +3 -3
  65. package/dist/src/mcpl/references.js.map +1 -1
  66. package/dist/src/mcpl/server-connection.d.ts +14 -0
  67. package/dist/src/mcpl/server-connection.d.ts.map +1 -1
  68. package/dist/src/mcpl/server-connection.js +26 -22
  69. package/dist/src/mcpl/server-connection.js.map +1 -1
  70. package/dist/src/mcpl/tool-signature.d.ts +1 -0
  71. package/dist/src/mcpl/tool-signature.d.ts.map +1 -1
  72. package/dist/src/mcpl/tool-signature.js +16 -11
  73. package/dist/src/mcpl/tool-signature.js.map +1 -1
  74. package/dist/src/mcpl/transport.d.ts +44 -21
  75. package/dist/src/mcpl/transport.d.ts.map +1 -1
  76. package/dist/src/mcpl/transport.js +283 -64
  77. package/dist/src/mcpl/transport.js.map +1 -1
  78. package/dist/src/mcpl/types.d.ts +17 -1
  79. package/dist/src/mcpl/types.d.ts.map +1 -1
  80. package/dist/src/mcpl/types.js.map +1 -1
  81. package/dist/src/module-registry.d.ts +32 -4
  82. package/dist/src/module-registry.d.ts.map +1 -1
  83. package/dist/src/module-registry.js +189 -25
  84. package/dist/src/module-registry.js.map +1 -1
  85. package/dist/src/modules/discord/discord-js-client.d.ts.map +1 -1
  86. package/dist/src/modules/discord/discord-js-client.js +24 -16
  87. package/dist/src/modules/discord/discord-js-client.js.map +1 -1
  88. package/dist/src/modules/sender-name.d.ts +5 -4
  89. package/dist/src/modules/sender-name.d.ts.map +1 -1
  90. package/dist/src/modules/sender-name.js +7 -5
  91. package/dist/src/modules/sender-name.js.map +1 -1
  92. package/dist/src/modules/workspace/disk-agreement.d.ts +16 -8
  93. package/dist/src/modules/workspace/disk-agreement.d.ts.map +1 -1
  94. package/dist/src/modules/workspace/disk-agreement.js +33 -12
  95. package/dist/src/modules/workspace/disk-agreement.js.map +1 -1
  96. package/dist/src/modules/workspace/index.d.ts +6 -3
  97. package/dist/src/modules/workspace/index.d.ts.map +1 -1
  98. package/dist/src/modules/workspace/index.js +61 -15
  99. package/dist/src/modules/workspace/index.js.map +1 -1
  100. package/dist/src/modules/workspace/observe.d.ts +9 -1
  101. package/dist/src/modules/workspace/observe.d.ts.map +1 -1
  102. package/dist/src/modules/workspace/observe.js +50 -10
  103. package/dist/src/modules/workspace/observe.js.map +1 -1
  104. package/dist/src/modules/workspace/reconcile.d.ts +11 -1
  105. package/dist/src/modules/workspace/reconcile.d.ts.map +1 -1
  106. package/dist/src/modules/workspace/reconcile.js +19 -8
  107. package/dist/src/modules/workspace/reconcile.js.map +1 -1
  108. package/dist/src/modules/workspace/types.d.ts +8 -0
  109. package/dist/src/modules/workspace/types.d.ts.map +1 -1
  110. package/dist/src/modules/workspace/types.js.map +1 -1
  111. package/dist/src/modules/workspace/watcher.d.ts +7 -0
  112. package/dist/src/modules/workspace/watcher.d.ts.map +1 -1
  113. package/dist/src/modules/workspace/watcher.js +7 -5
  114. package/dist/src/modules/workspace/watcher.js.map +1 -1
  115. package/dist/src/recovery/discord-awareness-outbox.d.ts.map +1 -1
  116. package/dist/src/recovery/discord-awareness-outbox.js +1 -9
  117. package/dist/src/recovery/discord-awareness-outbox.js.map +1 -1
  118. package/dist/src/supplied-text.d.ts +2 -0
  119. package/dist/src/supplied-text.d.ts.map +1 -1
  120. package/dist/src/supplied-text.js +16 -7
  121. package/dist/src/supplied-text.js.map +1 -1
  122. package/dist/src/tool-result-guard.js +1 -1
  123. package/dist/src/tool-result-guard.js.map +1 -1
  124. package/dist/src/tune-out/coordinator.d.ts +2 -20
  125. package/dist/src/tune-out/coordinator.d.ts.map +1 -1
  126. package/dist/src/tune-out/coordinator.js +175 -70
  127. package/dist/src/tune-out/coordinator.js.map +1 -1
  128. package/dist/src/tune-out/tools.d.ts +14 -2
  129. package/dist/src/tune-out/tools.d.ts.map +1 -1
  130. package/dist/src/tune-out/tools.js.map +1 -1
  131. package/dist/src/types/agent.d.ts +6 -12
  132. package/dist/src/types/agent.d.ts.map +1 -1
  133. package/dist/src/types/framework.d.ts +65 -24
  134. package/dist/src/types/framework.d.ts.map +1 -1
  135. package/dist/src/types/module.d.ts +42 -3
  136. package/dist/src/types/module.d.ts.map +1 -1
  137. package/dist/src/types/trace.d.ts +4 -3
  138. package/dist/src/types/trace.d.ts.map +1 -1
  139. package/package.json +3 -3
  140. package/src/agent.ts +90 -25
  141. package/src/api/mcp-server-core.ts +10 -3
  142. package/src/code-execution/isolate/render.ts +7 -6
  143. package/src/code-execution/isolate/scripts.ts +5 -4
  144. package/src/framework.ts +1163 -770
  145. package/src/gate/event-gate.ts +220 -145
  146. package/src/gate/recipe-reconcile.ts +7 -5
  147. package/src/host-presentation.ts +4 -7
  148. package/src/index.ts +1 -0
  149. package/src/inference-bounds.ts +111 -0
  150. package/src/line-reader.ts +22 -5
  151. package/src/mcpl/errors.ts +4 -0
  152. package/src/mcpl/inbound-source.ts +2 -2
  153. package/src/mcpl/inference-router.ts +67 -10
  154. package/src/mcpl/modern-connection.ts +83 -68
  155. package/src/mcpl/protocol-family.ts +37 -4
  156. package/src/mcpl/push-coalescer.ts +2 -7
  157. package/src/mcpl/references.ts +3 -4
  158. package/src/mcpl/server-connection.ts +30 -21
  159. package/src/mcpl/tool-signature.ts +18 -11
  160. package/src/mcpl/transport.ts +261 -60
  161. package/src/mcpl/types.ts +18 -1
  162. package/src/module-registry.ts +178 -25
  163. package/src/modules/discord/discord-js-client.ts +33 -29
  164. package/src/modules/sender-name.ts +8 -5
  165. package/src/modules/workspace/disk-agreement.ts +39 -15
  166. package/src/modules/workspace/index.ts +65 -14
  167. package/src/modules/workspace/observe.ts +51 -10
  168. package/src/modules/workspace/reconcile.ts +22 -8
  169. package/src/modules/workspace/types.ts +5 -0
  170. package/src/modules/workspace/watcher.ts +8 -6
  171. package/src/recovery/discord-awareness-outbox.ts +1 -11
  172. package/src/supplied-text.ts +17 -6
  173. package/src/tool-result-guard.ts +1 -1
  174. package/src/tune-out/coordinator.ts +187 -85
  175. package/src/tune-out/tools.ts +14 -2
  176. package/src/types/agent.ts +6 -12
  177. package/src/types/framework.ts +66 -24
  178. package/src/types/module.ts +42 -3
  179. package/src/types/trace.ts +4 -3
  180. package/dist/src/reasoning-loss-notice.d.ts +0 -23
  181. package/dist/src/reasoning-loss-notice.d.ts.map +0 -1
  182. package/dist/src/reasoning-loss-notice.js +0 -52
  183. package/dist/src/reasoning-loss-notice.js.map +0 -1
  184. package/dist/src/reasoning-loss.d.ts +0 -24
  185. package/dist/src/reasoning-loss.d.ts.map +0 -1
  186. package/dist/src/reasoning-loss.js +0 -102
  187. package/dist/src/reasoning-loss.js.map +0 -1
  188. package/src/reasoning-loss-notice.ts +0 -64
  189. package/src/reasoning-loss.ts +0 -120
@@ -120,7 +120,10 @@ export interface Module {
120
120
 
121
121
  /**
122
122
  * Start the module.
123
- * Called when the framework starts or when the module is added.
123
+ * Called when the module is added: create() adds the modules it is given,
124
+ * so for those it runs before create() returns. Its own removal and the
125
+ * framework's stop() wait for it to settle before the module's stop()
126
+ * runs, so it mustn't await either.
124
127
  */
125
128
  start(ctx: ModuleContext): Promise<void>;
126
129
 
@@ -132,6 +135,8 @@ export interface Module {
132
135
  * a host wires up after create() returns, such as a WorkspaceModule's
133
136
  * initStore(). A stop() that saves state can therefore run before that
134
137
  * wiring, and shouldn't then save over state it was handed and hasn't used.
138
+ * It isn't called before the module's start() has settled, so it can end
139
+ * what start() set up.
135
140
  */
136
141
  stop(): Promise<void>;
137
142
 
@@ -259,6 +264,41 @@ export interface AgentSettingsExtension {
259
264
 
260
265
  /**
261
266
  * Context provided to modules for interacting with the framework.
267
+ *
268
+ * Once the module's `stop()` has completed, through `removeModule()` or the
269
+ * framework's `stop()`, its context has no effect on the framework:
270
+ * - each push is dropped with a log line, as a push after the framework's
271
+ * `stop()` is;
272
+ * - `setState`, `registerLogState`, `appendToLog`, `editLogItem`,
273
+ * `editMessage`, `removeMessage`, `notifyOps`, `registerSpeechHandler` and
274
+ * `unregisterSpeechHandler` do nothing; `addMessage` returns `''` and adds
275
+ * nothing; `callTool` resolves with an error result and runs nothing;
276
+ * `getModule` returns `null`; and `onTrace` subscribes nothing, while the
277
+ * subscriptions made through the context end. None of these throws, and
278
+ * the first such call of each method logs one line naming the module and
279
+ * the method;
280
+ * - `findMessageByExternalId` answers without updating its mapping, and logs
281
+ * nothing.
282
+ *
283
+ * Its reads (`getState`, `getLog`, `getLogLength`, `getMessage`,
284
+ * `queryMessages`, `getAgents`, `getActiveTools`, `findMessageByExternalId`)
285
+ * answer, and fail, as before; one that meets a held write may record that
286
+ * the write has landed, as any reader's does. The framework calls none of the
287
+ * module's `onProcess`, `onAgentSpeech` and `onToolBatchComplete` again; it
288
+ * drops whole a response of its that hadn't been applied by then, with a line
289
+ * naming what the response asked for if it asked for anything; and it leaves
290
+ * its `gatherContext` answer out of a turn whose answers it hadn't merged by
291
+ * then, with a line if it held injections. After `removeModule()`, the result
292
+ * its `handleToolCall` returns for a call it was running when its `stop()`
293
+ * completed is still delivered while the framework runs. The framework's
294
+ * `stop()` closes its event queue before it stops any module, so through the
295
+ * framework's `stop()` that result is dropped, with the line any tool result
296
+ * arriving after the framework's `stop()` gets. A result it pushes through
297
+ * its context after its `stop()` completes is dropped, as its other pushes
298
+ * are. A module whose `stop()` fails stays registered, and its context keeps
299
+ * working.
300
+ * References the module already holds, to other modules or to its own
301
+ * timers, stay as they are.
262
302
  */
263
303
  export interface ModuleContext {
264
304
  /**
@@ -366,8 +406,7 @@ export interface ModuleContext {
366
406
  * and a tool round moves when it injects messages into a stream that
367
407
  * declares it carries them. So one that waited for its target's end (a
368
408
  * run's end, or a fork's last turn), one stored while it was idle and
369
- * never sent, one stored at a tool round that ended the turn, and one
370
- * injected into a stream that didn't declare it carries injections go to
409
+ * never sent, and one stored at a tool round that ended the turn go to
371
410
  * the primary. The framework's own
372
411
  * writes for a run or a fork are unchanged: they stay in its store,
373
412
  * unless they're notices the primary already takes in their place (a
@@ -730,9 +730,10 @@ export type TraceEvent =
730
730
  /** Signal that terminated the child, if any. */
731
731
  signal: string | null;
732
732
  /** Why the transport closed, in its own words, such as `child process
733
- * exited, and its pipe failed with write EPIPE` or `closed by host`;
734
- * null when it gave none, or when its reason is a WebSocket server's
735
- * own close text, which stays off the trace. */
733
+ * exited, and this host had stopped using the server's stdio (write
734
+ * EPIPE)` or `closed by host`; null when it gave none, or when its
735
+ * reason is a WebSocket server's own close text, which stays off the
736
+ * trace. */
736
737
  reason: string | null;
737
738
  /** True when a background reconnect loop will revive the connection. */
738
739
  willReconnect: boolean;
@@ -1,23 +0,0 @@
1
- export type ReasoningLossCause = 'tools' | 'system' | 'model';
2
- export type ReasoningLossAnchor = {
3
- text: string;
4
- } | {
5
- toolCall: string;
6
- };
7
- export interface ReasoningLossNoticeInput {
8
- agentName: string;
9
- scope: {
10
- kind: 'all';
11
- through?: ReasoningLossAnchor;
12
- thisTurn: boolean;
13
- } | {
14
- kind: 'some';
15
- count: number;
16
- first?: ReasoningLossAnchor;
17
- unplaced?: boolean;
18
- thisTurn: boolean;
19
- };
20
- causes: readonly ReasoningLossCause[];
21
- }
22
- export declare function reasoningLossNotice(input: ReasoningLossNoticeInput): string;
23
- //# sourceMappingURL=reasoning-loss-notice.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"reasoning-loss-notice.d.ts","sourceRoot":"","sources":["../../src/reasoning-loss-notice.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE9D,MAAM,MAAM,mBAAmB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1E,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EACD;QAAE,IAAI,EAAE,KAAK,CAAC;QAAC,OAAO,CAAC,EAAE,mBAAmB,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,GACjE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,mBAAmB,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;IACxG,MAAM,EAAE,SAAS,kBAAkB,EAAE,CAAC;CACvC;AAWD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,wBAAwB,GAAG,MAAM,CAyB3E"}
@@ -1,52 +0,0 @@
1
- import { NOTICE_TAG } from './notice-tags.js';
2
- import { oneLine, suppliedValue } from './supplied-text.js';
3
- import { safeSlice } from './safe-slice.js';
4
- const ANCHOR_CHARS = 80;
5
- const CAUSE_WORDS = {
6
- tools: 'your tools changed',
7
- system: 'your system prompt changed',
8
- model: 'your model changed',
9
- };
10
- const CAUSE_ORDER = ['tools', 'system', 'model'];
11
- export function reasoningLossNotice(input) {
12
- const causes = CAUSE_ORDER.filter((c) => input.causes.includes(c)).map((c) => CAUSE_WORDS[c]);
13
- const because = causes.length > 0 ? `, because ${joinAnd(causes)}` : '';
14
- const scope = input.scope;
15
- let lost;
16
- let reread;
17
- if (scope.kind === 'all') {
18
- const through = scope.through ? anchorWords(scope.through) : undefined;
19
- const among = scope.thisTurn ? ", this turn's earlier steps among them," : '';
20
- lost = through
21
- ? `The reasoning behind your replies up to the one ${through}${among} is no longer in your context${because}.`
22
- : `The reasoning behind your earlier replies${among} is no longer in your context${because}.`;
23
- reread = 'Re-read before relying on an earlier decision.';
24
- }
25
- else {
26
- const one = scope.count === 1 && !scope.unplaced;
27
- const replies = scope.unplaced
28
- ? `at least ${scope.count} of your replies`
29
- : one ? 'one of your replies' : `${scope.count} of your replies`;
30
- const named = scope.first && !scope.unplaced ? anchorWords(scope.first) : undefined;
31
- const first = named ? (one ? `, the one ${named}` : `, the first being the one ${named}`) : '';
32
- const among = scope.thisTurn ? (one ? ', an earlier step of this turn' : ", this turn's earlier steps among them") : '';
33
- lost = `Some of your earlier reasoning is no longer in your context: the reasoning behind ${replies}${first}${among}${because}.`;
34
- reread = named ? 'Re-read before relying on a decision made since then.' : 'Re-read before relying on an earlier decision.';
35
- }
36
- return `[${NOTICE_TAG.reasoning}] ${input.agentName}: ${lost} Their words are still here. ${reread}`;
37
- }
38
- function anchorWords(anchor) {
39
- if ('toolCall' in anchor)
40
- return anchor.toolCall ? `that called \`${suppliedValue(anchor.toolCall)}\`` : undefined;
41
- const text = oneLine(anchor.text).replace(/\s+/g, ' ').trim();
42
- if (!text)
43
- return undefined;
44
- const clipped = text.length > ANCHOR_CHARS ? `${safeSlice(text, 0, ANCHOR_CHARS).trimEnd()}…` : text;
45
- return `beginning "${clipped}"`;
46
- }
47
- function joinAnd(parts) {
48
- if (parts.length <= 1)
49
- return parts.join('');
50
- return `${parts.slice(0, -1).join(', ')} and ${parts[parts.length - 1]}`;
51
- }
52
- //# sourceMappingURL=reasoning-loss-notice.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"reasoning-loss-notice.js","sourceRoot":"","sources":["../../src/reasoning-loss-notice.ts"],"names":[],"mappings":"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"}
@@ -1,24 +0,0 @@
1
- import type { ContentBlock } from '@animalabs/membrane';
2
- import type { MessageId, ThinkingStrip } from '@animalabs/context-manager';
3
- import { type PlacedDrop } from './thinking-drops.js';
4
- export interface StoredReplyReader {
5
- getMessage(id: MessageId): {
6
- sequence: number;
7
- content: readonly ContentBlock[];
8
- } | null;
9
- }
10
- export interface ReasoningLossTurn {
11
- start?: {
12
- branch: string;
13
- sequence: number;
14
- };
15
- }
16
- export declare class ReasoningLossTeller {
17
- private readonly told;
18
- private readonly drops;
19
- forStrip(agentName: string, branch: string, strip: ThinkingStrip, turn: ReasoningLossTurn, store: StoredReplyReader): string | undefined;
20
- forDrops(agentName: string, branch: string, placed: readonly PlacedDrop[], turn: ReasoningLossTurn, store: StoredReplyReader): string | undefined;
21
- forget(agentName: string): void;
22
- private toldFor;
23
- }
24
- //# sourceMappingURL=reasoning-loss.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"reasoning-loss.d.ts","sourceRoot":"","sources":["../../src/reasoning-loss.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3E,OAAO,EAAyB,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAO7E,MAAM,WAAW,iBAAiB;IAChC,UAAU,CAAC,EAAE,EAAE,SAAS,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,SAAS,YAAY,EAAE,CAAA;KAAE,GAAG,IAAI,CAAC;CAC1F;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9C;AAQD,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAkD;IACvE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA+B;IAErD,QAAQ,CACN,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE,iBAAiB,EACvB,KAAK,EAAE,iBAAiB,GACvB,MAAM,GAAG,SAAS,CA0BpB;IAED,QAAQ,CACN,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,SAAS,UAAU,EAAE,EAC7B,IAAI,EAAE,iBAAiB,EACvB,KAAK,EAAE,iBAAiB,GACvB,MAAM,GAAG,SAAS,CAuBpB;IAED,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAG9B;IAED,OAAO,CAAC,OAAO;CAOhB"}
@@ -1,102 +0,0 @@
1
- import { ThinkingLossIncidents } from './thinking-drops.js';
2
- import { reasoningLossNotice, } from './reasoning-loss-notice.js';
3
- const HEAD_CAUSES = {
4
- tools: 'tools',
5
- system: 'system',
6
- model: 'model',
7
- };
8
- export class ReasoningLossTeller {
9
- told = new Map();
10
- drops = new ThinkingLossIncidents();
11
- forStrip(agentName, branch, strip, turn, store) {
12
- const told = this.toldFor(agentName, branch);
13
- const taken = strip.newly
14
- .map((id) => ({ id, sequence: store.getMessage(id)?.sequence }))
15
- .sort((a, b) => (a.sequence ?? Infinity) - (b.sequence ?? Infinity));
16
- const replies = taken.filter((r) => !told.has(r.id));
17
- if (replies.length === 0)
18
- return undefined;
19
- const thisTurn = replies.some((r) => isThisTurn(r.sequence, branch, turn));
20
- if (strip.cause === 'head') {
21
- const causes = (strip.changed ?? [])
22
- .map((c) => HEAD_CAUSES[c])
23
- .filter((c) => c !== undefined);
24
- const newest = taken.filter((r) => r.sequence !== undefined).at(-1);
25
- const through = newest ? anchorOf(store.getMessage(newest.id)?.content) : undefined;
26
- const amongThisTurn = taken.some((r) => isThisTurn(r.sequence, branch, turn));
27
- for (const r of replies)
28
- told.add(r.id);
29
- return reasoningLossNotice({ agentName, scope: { kind: 'all', ...(through ? { through } : {}), thisTurn: amongThisTurn }, causes });
30
- }
31
- if (strip.cause !== 'first' && !taken.some((r) => isThisTurn(r.sequence, branch, turn)))
32
- return undefined;
33
- const first = anchorOf(store.getMessage(replies[0].id)?.content);
34
- for (const r of replies)
35
- told.add(r.id);
36
- return reasoningLossNotice({
37
- agentName,
38
- scope: { kind: 'some', count: replies.length, ...(first ? { first } : {}), thisTurn },
39
- causes: [],
40
- });
41
- }
42
- forDrops(agentName, branch, placed, turn, store) {
43
- const replies = new Map();
44
- const rounds = new Set();
45
- let blocks = 0;
46
- for (const drop of placed) {
47
- if (drop.kind === 'unplaced')
48
- continue;
49
- blocks++;
50
- if (drop.kind === 'round')
51
- rounds.add(drop.round);
52
- else
53
- for (const body of drop.bodies)
54
- replies.set(body.messageId, body.sequence);
55
- }
56
- const unplaced = blocks < placed.length;
57
- const count = replies.size + rounds.size;
58
- const ordered = [...replies].sort((a, b) => a[1] - b[1]);
59
- const thisTurn = rounds.size > 0 || ordered.some(([, sequence]) => isThisTurn(sequence, branch, turn));
60
- const first = ordered.length > 0 && !unplaced ? anchorOf(store.getMessage(ordered[0][0])?.content) : undefined;
61
- if (this.drops.observe(agentName, blocks, branch) === undefined)
62
- return undefined;
63
- const told = this.toldFor(agentName, branch);
64
- for (const id of replies.keys())
65
- told.add(id);
66
- return reasoningLossNotice({
67
- agentName,
68
- scope: { kind: 'some', count, ...(first ? { first } : {}), ...(unplaced ? { unplaced: true } : {}), thisTurn },
69
- causes: [],
70
- });
71
- }
72
- forget(agentName) {
73
- this.told.delete(agentName);
74
- this.drops.forget(agentName);
75
- }
76
- toldFor(agentName, branch) {
77
- let branches = this.told.get(agentName);
78
- if (!branches)
79
- this.told.set(agentName, (branches = new Map()));
80
- let told = branches.get(branch);
81
- if (!told)
82
- branches.set(branch, (told = new Set()));
83
- return told;
84
- }
85
- }
86
- function isThisTurn(sequence, branch, turn) {
87
- return sequence !== undefined && turn.start?.branch === branch && sequence > turn.start.sequence;
88
- }
89
- function anchorOf(content) {
90
- if (!content)
91
- return undefined;
92
- for (const block of content) {
93
- if (block.type === 'text' && typeof block.text === 'string' && block.text.trim() !== '')
94
- return { text: block.text };
95
- }
96
- for (const block of content) {
97
- if (block.type === 'tool_use' && typeof block.name === 'string' && block.name !== '')
98
- return { toolCall: block.name };
99
- }
100
- return undefined;
101
- }
102
- //# sourceMappingURL=reasoning-loss.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"reasoning-loss.js","sourceRoot":"","sources":["../../src/reasoning-loss.ts"],"names":[],"mappings":"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"}
@@ -1,64 +0,0 @@
1
- import { NOTICE_TAG } from './notice-tags.js';
2
- import { oneLine, suppliedValue } from './supplied-text.js';
3
- import { safeSlice } from './safe-slice.js';
4
-
5
- export type ReasoningLossCause = 'tools' | 'system' | 'model';
6
-
7
- export type ReasoningLossAnchor = { text: string } | { toolCall: string };
8
-
9
- export interface ReasoningLossNoticeInput {
10
- agentName: string;
11
- scope:
12
- | { kind: 'all'; through?: ReasoningLossAnchor; thisTurn: boolean }
13
- | { kind: 'some'; count: number; first?: ReasoningLossAnchor; unplaced?: boolean; thisTurn: boolean };
14
- causes: readonly ReasoningLossCause[];
15
- }
16
-
17
- const ANCHOR_CHARS = 80;
18
-
19
- const CAUSE_WORDS: Record<ReasoningLossCause, string> = {
20
- tools: 'your tools changed',
21
- system: 'your system prompt changed',
22
- model: 'your model changed',
23
- };
24
- const CAUSE_ORDER: readonly ReasoningLossCause[] = ['tools', 'system', 'model'];
25
-
26
- export function reasoningLossNotice(input: ReasoningLossNoticeInput): string {
27
- const causes = CAUSE_ORDER.filter((c) => input.causes.includes(c)).map((c) => CAUSE_WORDS[c]);
28
- const because = causes.length > 0 ? `, because ${joinAnd(causes)}` : '';
29
- const scope = input.scope;
30
- let lost: string;
31
- let reread: string;
32
- if (scope.kind === 'all') {
33
- const through = scope.through ? anchorWords(scope.through) : undefined;
34
- const among = scope.thisTurn ? ", this turn's earlier steps among them," : '';
35
- lost = through
36
- ? `The reasoning behind your replies up to the one ${through}${among} is no longer in your context${because}.`
37
- : `The reasoning behind your earlier replies${among} is no longer in your context${because}.`;
38
- reread = 'Re-read before relying on an earlier decision.';
39
- } else {
40
- const one = scope.count === 1 && !scope.unplaced;
41
- const replies = scope.unplaced
42
- ? `at least ${scope.count} of your replies`
43
- : one ? 'one of your replies' : `${scope.count} of your replies`;
44
- const named = scope.first && !scope.unplaced ? anchorWords(scope.first) : undefined;
45
- const first = named ? (one ? `, the one ${named}` : `, the first being the one ${named}`) : '';
46
- const among = scope.thisTurn ? (one ? ', an earlier step of this turn' : ", this turn's earlier steps among them") : '';
47
- lost = `Some of your earlier reasoning is no longer in your context: the reasoning behind ${replies}${first}${among}${because}.`;
48
- reread = named ? 'Re-read before relying on a decision made since then.' : 'Re-read before relying on an earlier decision.';
49
- }
50
- return `[${NOTICE_TAG.reasoning}] ${input.agentName}: ${lost} Their words are still here. ${reread}`;
51
- }
52
-
53
- function anchorWords(anchor: ReasoningLossAnchor): string | undefined {
54
- if ('toolCall' in anchor) return anchor.toolCall ? `that called \`${suppliedValue(anchor.toolCall)}\`` : undefined;
55
- const text = oneLine(anchor.text).replace(/\s+/g, ' ').trim();
56
- if (!text) return undefined;
57
- const clipped = text.length > ANCHOR_CHARS ? `${safeSlice(text, 0, ANCHOR_CHARS).trimEnd()}…` : text;
58
- return `beginning "${clipped}"`;
59
- }
60
-
61
- function joinAnd(parts: readonly string[]): string {
62
- if (parts.length <= 1) return parts.join('');
63
- return `${parts.slice(0, -1).join(', ')} and ${parts[parts.length - 1]}`;
64
- }
@@ -1,120 +0,0 @@
1
- import type { ContentBlock } from '@animalabs/membrane';
2
- import type { MessageId, ThinkingStrip } from '@animalabs/context-manager';
3
- import { ThinkingLossIncidents, type PlacedDrop } from './thinking-drops.js';
4
- import {
5
- reasoningLossNotice,
6
- type ReasoningLossAnchor,
7
- type ReasoningLossCause,
8
- } from './reasoning-loss-notice.js';
9
-
10
- export interface StoredReplyReader {
11
- getMessage(id: MessageId): { sequence: number; content: readonly ContentBlock[] } | null;
12
- }
13
-
14
- export interface ReasoningLossTurn {
15
- start?: { branch: string; sequence: number };
16
- }
17
-
18
- const HEAD_CAUSES: Partial<Record<NonNullable<ThinkingStrip['changed']>[number], ReasoningLossCause>> = {
19
- tools: 'tools',
20
- system: 'system',
21
- model: 'model',
22
- };
23
-
24
- export class ReasoningLossTeller {
25
- private readonly told = new Map<string, Map<string, Set<MessageId>>>();
26
- private readonly drops = new ThinkingLossIncidents();
27
-
28
- forStrip(
29
- agentName: string,
30
- branch: string,
31
- strip: ThinkingStrip,
32
- turn: ReasoningLossTurn,
33
- store: StoredReplyReader,
34
- ): string | undefined {
35
- const told = this.toldFor(agentName, branch);
36
- const taken = strip.newly
37
- .map((id) => ({ id, sequence: store.getMessage(id)?.sequence }))
38
- .sort((a, b) => (a.sequence ?? Infinity) - (b.sequence ?? Infinity));
39
- const replies = taken.filter((r) => !told.has(r.id));
40
- if (replies.length === 0) return undefined;
41
- const thisTurn = replies.some((r) => isThisTurn(r.sequence, branch, turn));
42
- if (strip.cause === 'head') {
43
- const causes = (strip.changed ?? [])
44
- .map((c) => HEAD_CAUSES[c])
45
- .filter((c): c is ReasoningLossCause => c !== undefined);
46
- const newest = taken.filter((r) => r.sequence !== undefined).at(-1);
47
- const through = newest ? anchorOf(store.getMessage(newest.id)?.content) : undefined;
48
- const amongThisTurn = taken.some((r) => isThisTurn(r.sequence, branch, turn));
49
- for (const r of replies) told.add(r.id);
50
- return reasoningLossNotice({ agentName, scope: { kind: 'all', ...(through ? { through } : {}), thisTurn: amongThisTurn }, causes });
51
- }
52
- if (strip.cause !== 'first' && !taken.some((r) => isThisTurn(r.sequence, branch, turn))) return undefined;
53
- const first = anchorOf(store.getMessage(replies[0]!.id)?.content);
54
- for (const r of replies) told.add(r.id);
55
- return reasoningLossNotice({
56
- agentName,
57
- scope: { kind: 'some', count: replies.length, ...(first ? { first } : {}), thisTurn },
58
- causes: [],
59
- });
60
- }
61
-
62
- forDrops(
63
- agentName: string,
64
- branch: string,
65
- placed: readonly PlacedDrop[],
66
- turn: ReasoningLossTurn,
67
- store: StoredReplyReader,
68
- ): string | undefined {
69
- const replies = new Map<MessageId, number>();
70
- const rounds = new Set<number>();
71
- let blocks = 0;
72
- for (const drop of placed) {
73
- if (drop.kind === 'unplaced') continue;
74
- blocks++;
75
- if (drop.kind === 'round') rounds.add(drop.round);
76
- else for (const body of drop.bodies) replies.set(body.messageId, body.sequence);
77
- }
78
- const unplaced = blocks < placed.length;
79
- const count = replies.size + rounds.size;
80
- const ordered = [...replies].sort((a, b) => a[1] - b[1]);
81
- const thisTurn = rounds.size > 0 || ordered.some(([, sequence]) => isThisTurn(sequence, branch, turn));
82
- const first = ordered.length > 0 && !unplaced ? anchorOf(store.getMessage(ordered[0]![0])?.content) : undefined;
83
- if (this.drops.observe(agentName, blocks, branch) === undefined) return undefined;
84
- const told = this.toldFor(agentName, branch);
85
- for (const id of replies.keys()) told.add(id);
86
- return reasoningLossNotice({
87
- agentName,
88
- scope: { kind: 'some', count, ...(first ? { first } : {}), ...(unplaced ? { unplaced: true } : {}), thisTurn },
89
- causes: [],
90
- });
91
- }
92
-
93
- forget(agentName: string): void {
94
- this.told.delete(agentName);
95
- this.drops.forget(agentName);
96
- }
97
-
98
- private toldFor(agentName: string, branch: string): Set<MessageId> {
99
- let branches = this.told.get(agentName);
100
- if (!branches) this.told.set(agentName, (branches = new Map()));
101
- let told = branches.get(branch);
102
- if (!told) branches.set(branch, (told = new Set()));
103
- return told;
104
- }
105
- }
106
-
107
- function isThisTurn(sequence: number | undefined, branch: string, turn: ReasoningLossTurn): boolean {
108
- return sequence !== undefined && turn.start?.branch === branch && sequence > turn.start.sequence;
109
- }
110
-
111
- function anchorOf(content: readonly ContentBlock[] | undefined): ReasoningLossAnchor | undefined {
112
- if (!content) return undefined;
113
- for (const block of content) {
114
- if (block.type === 'text' && typeof block.text === 'string' && block.text.trim() !== '') return { text: block.text };
115
- }
116
- for (const block of content) {
117
- if (block.type === 'tool_use' && typeof block.name === 'string' && block.name !== '') return { toolCall: block.name };
118
- }
119
- return undefined;
120
- }