@animalabs/agent-framework 0.11.0 → 0.13.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 (160) hide show
  1. package/dist/src/agent.d.ts +11 -1
  2. package/dist/src/agent.d.ts.map +1 -1
  3. package/dist/src/agent.js +60 -4
  4. package/dist/src/agent.js.map +1 -1
  5. package/dist/src/framework.d.ts +72 -1
  6. package/dist/src/framework.d.ts.map +1 -1
  7. package/dist/src/framework.js +873 -123
  8. package/dist/src/framework.js.map +1 -1
  9. package/dist/src/gate/event-gate.d.ts +7 -1
  10. package/dist/src/gate/event-gate.d.ts.map +1 -1
  11. package/dist/src/gate/event-gate.js +15 -1
  12. package/dist/src/gate/event-gate.js.map +1 -1
  13. package/dist/src/kv-unified-wire.d.ts +16 -0
  14. package/dist/src/kv-unified-wire.d.ts.map +1 -0
  15. package/dist/src/kv-unified-wire.js +2 -0
  16. package/dist/src/kv-unified-wire.js.map +1 -0
  17. package/dist/src/mcpl/channel-registry.d.ts +84 -1
  18. package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
  19. package/dist/src/mcpl/channel-registry.js +188 -5
  20. package/dist/src/mcpl/channel-registry.js.map +1 -1
  21. package/dist/src/mcpl/hook-orchestrator.d.ts.map +1 -1
  22. package/dist/src/mcpl/hook-orchestrator.js +28 -2
  23. package/dist/src/mcpl/hook-orchestrator.js.map +1 -1
  24. package/dist/src/mcpl/push-handler.d.ts +6 -1
  25. package/dist/src/mcpl/push-handler.d.ts.map +1 -1
  26. package/dist/src/mcpl/push-handler.js +29 -2
  27. package/dist/src/mcpl/push-handler.js.map +1 -1
  28. package/dist/src/mcpl/reference-fetcher.d.ts +59 -0
  29. package/dist/src/mcpl/reference-fetcher.d.ts.map +1 -0
  30. package/dist/src/mcpl/reference-fetcher.js +240 -0
  31. package/dist/src/mcpl/reference-fetcher.js.map +1 -0
  32. package/dist/src/mcpl/references.d.ts +125 -0
  33. package/dist/src/mcpl/references.d.ts.map +1 -0
  34. package/dist/src/mcpl/references.js +262 -0
  35. package/dist/src/mcpl/references.js.map +1 -0
  36. package/dist/src/mcpl/types.d.ts +32 -0
  37. package/dist/src/mcpl/types.d.ts.map +1 -1
  38. package/dist/src/mcpl/types.js.map +1 -1
  39. package/dist/src/modules/index.d.ts +2 -1
  40. package/dist/src/modules/index.d.ts.map +1 -1
  41. package/dist/src/modules/index.js +1 -1
  42. package/dist/src/modules/index.js.map +1 -1
  43. package/dist/src/modules/workspace/index.d.ts +125 -2
  44. package/dist/src/modules/workspace/index.d.ts.map +1 -1
  45. package/dist/src/modules/workspace/index.js +354 -58
  46. package/dist/src/modules/workspace/index.js.map +1 -1
  47. package/dist/src/modules/workspace/types.d.ts +7 -0
  48. package/dist/src/modules/workspace/types.d.ts.map +1 -1
  49. package/dist/src/modules/workspace/types.js.map +1 -1
  50. package/dist/src/tool-result-history.d.ts.map +1 -1
  51. package/dist/src/tool-result-history.js +14 -0
  52. package/dist/src/tool-result-history.js.map +1 -1
  53. package/dist/src/tool-wrapper-prose-guard.d.ts +8 -0
  54. package/dist/src/tool-wrapper-prose-guard.d.ts.map +1 -0
  55. package/dist/src/tool-wrapper-prose-guard.js +37 -0
  56. package/dist/src/tool-wrapper-prose-guard.js.map +1 -0
  57. package/dist/src/tune-out/coordinator.d.ts +144 -0
  58. package/dist/src/tune-out/coordinator.d.ts.map +1 -0
  59. package/dist/src/tune-out/coordinator.js +444 -0
  60. package/dist/src/tune-out/coordinator.js.map +1 -0
  61. package/dist/src/tune-out/tools.d.ts +43 -0
  62. package/dist/src/tune-out/tools.d.ts.map +1 -0
  63. package/dist/src/tune-out/tools.js +93 -0
  64. package/dist/src/tune-out/tools.js.map +1 -0
  65. package/dist/src/types/agent.d.ts +15 -0
  66. package/dist/src/types/agent.d.ts.map +1 -1
  67. package/dist/src/types/framework.d.ts +6 -0
  68. package/dist/src/types/framework.d.ts.map +1 -1
  69. package/dist/src/usage-accounting.d.ts +5 -0
  70. package/dist/src/usage-accounting.d.ts.map +1 -0
  71. package/dist/src/usage-accounting.js +11 -0
  72. package/dist/src/usage-accounting.js.map +1 -0
  73. package/dist/test/channel-incoming-targeting.test.d.ts +2 -0
  74. package/dist/test/channel-incoming-targeting.test.d.ts.map +1 -0
  75. package/dist/test/channel-incoming-targeting.test.js +81 -0
  76. package/dist/test/channel-incoming-targeting.test.js.map +1 -0
  77. package/dist/test/conversation-routing.test.js +39 -0
  78. package/dist/test/conversation-routing.test.js.map +1 -1
  79. package/dist/test/kv-unified-wiring.test.d.ts +2 -0
  80. package/dist/test/kv-unified-wiring.test.d.ts.map +1 -0
  81. package/dist/test/kv-unified-wiring.test.js +56 -0
  82. package/dist/test/kv-unified-wiring.test.js.map +1 -0
  83. package/dist/test/mcpl-push-convert.test.d.ts +2 -0
  84. package/dist/test/mcpl-push-convert.test.d.ts.map +1 -0
  85. package/dist/test/mcpl-push-convert.test.js +42 -0
  86. package/dist/test/mcpl-push-convert.test.js.map +1 -0
  87. package/dist/test/mcpl-reference-fetcher.test.d.ts +2 -0
  88. package/dist/test/mcpl-reference-fetcher.test.d.ts.map +1 -0
  89. package/dist/test/mcpl-reference-fetcher.test.js +199 -0
  90. package/dist/test/mcpl-reference-fetcher.test.js.map +1 -0
  91. package/dist/test/per-agent-delivery.test.d.ts +2 -0
  92. package/dist/test/per-agent-delivery.test.d.ts.map +1 -0
  93. package/dist/test/per-agent-delivery.test.js +108 -0
  94. package/dist/test/per-agent-delivery.test.js.map +1 -0
  95. package/dist/test/present-while-acting.test.js +64 -0
  96. package/dist/test/present-while-acting.test.js.map +1 -1
  97. package/dist/test/tool-result-history.test.js +78 -0
  98. package/dist/test/tool-result-history.test.js.map +1 -1
  99. package/dist/test/tool-wrapper-prose-guard-integration.test.d.ts +2 -0
  100. package/dist/test/tool-wrapper-prose-guard-integration.test.d.ts.map +1 -0
  101. package/dist/test/tool-wrapper-prose-guard-integration.test.js +485 -0
  102. package/dist/test/tool-wrapper-prose-guard-integration.test.js.map +1 -0
  103. package/dist/test/tool-wrapper-prose-guard.test.d.ts +2 -0
  104. package/dist/test/tool-wrapper-prose-guard.test.d.ts.map +1 -0
  105. package/dist/test/tool-wrapper-prose-guard.test.js +34 -0
  106. package/dist/test/tool-wrapper-prose-guard.test.js.map +1 -0
  107. package/dist/test/tune-out-e2e.test.d.ts +2 -0
  108. package/dist/test/tune-out-e2e.test.d.ts.map +1 -0
  109. package/dist/test/tune-out-e2e.test.js +142 -0
  110. package/dist/test/tune-out-e2e.test.js.map +1 -0
  111. package/dist/test/tune-out-gate-composition.test.d.ts +2 -0
  112. package/dist/test/tune-out-gate-composition.test.d.ts.map +1 -0
  113. package/dist/test/tune-out-gate-composition.test.js +221 -0
  114. package/dist/test/tune-out-gate-composition.test.js.map +1 -0
  115. package/dist/test/tune-out-lifecycle.test.d.ts +2 -0
  116. package/dist/test/tune-out-lifecycle.test.d.ts.map +1 -0
  117. package/dist/test/tune-out-lifecycle.test.js +121 -0
  118. package/dist/test/tune-out-lifecycle.test.js.map +1 -0
  119. package/dist/test/turn-trigger-provenance.test.d.ts +2 -0
  120. package/dist/test/turn-trigger-provenance.test.d.ts.map +1 -0
  121. package/dist/test/turn-trigger-provenance.test.js +85 -0
  122. package/dist/test/turn-trigger-provenance.test.js.map +1 -0
  123. package/dist/test/usage-accounting.test.d.ts +2 -0
  124. package/dist/test/usage-accounting.test.d.ts.map +1 -0
  125. package/dist/test/usage-accounting.test.js +13 -0
  126. package/dist/test/usage-accounting.test.js.map +1 -0
  127. package/dist/test/workspace-branch-continuation.test.d.ts +15 -0
  128. package/dist/test/workspace-branch-continuation.test.d.ts.map +1 -0
  129. package/dist/test/workspace-branch-continuation.test.js +183 -0
  130. package/dist/test/workspace-branch-continuation.test.js.map +1 -0
  131. package/dist/test/workspace-read-file-from-disk.test.d.ts +17 -0
  132. package/dist/test/workspace-read-file-from-disk.test.d.ts.map +1 -0
  133. package/dist/test/workspace-read-file-from-disk.test.js +174 -0
  134. package/dist/test/workspace-read-file-from-disk.test.js.map +1 -0
  135. package/dist/test/workspace-read-image.test.js +8 -0
  136. package/dist/test/workspace-read-image.test.js.map +1 -1
  137. package/dist/test/workspace-restore-order.test.js +1 -1
  138. package/dist/test/workspace-restore-order.test.js.map +1 -1
  139. package/dist/tsconfig.tsbuildinfo +1 -1
  140. package/package.json +2 -2
  141. package/src/agent.ts +77 -4
  142. package/src/framework.ts +953 -128
  143. package/src/gate/event-gate.ts +28 -3
  144. package/src/kv-unified-wire.ts +12 -0
  145. package/src/mcpl/channel-registry.ts +264 -8
  146. package/src/mcpl/hook-orchestrator.ts +29 -2
  147. package/src/mcpl/push-handler.ts +30 -2
  148. package/src/mcpl/reference-fetcher.ts +240 -0
  149. package/src/mcpl/references.ts +292 -0
  150. package/src/mcpl/types.ts +29 -0
  151. package/src/modules/index.ts +2 -1
  152. package/src/modules/workspace/index.ts +425 -66
  153. package/src/modules/workspace/types.ts +7 -0
  154. package/src/tool-result-history.ts +11 -0
  155. package/src/tool-wrapper-prose-guard.ts +38 -0
  156. package/src/tune-out/coordinator.ts +548 -0
  157. package/src/tune-out/tools.ts +129 -0
  158. package/src/types/agent.ts +16 -0
  159. package/src/types/framework.ts +7 -0
  160. package/src/usage-accounting.ts +8 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@animalabs/agent-framework",
3
- "version": "0.11.0",
3
+ "version": "0.13.0",
4
4
  "description": "Multi-agent framework with pluggable modules, persistent state, and concurrent tool execution",
5
5
  "repository": {
6
6
  "type": "git",
@@ -47,7 +47,7 @@
47
47
  "license": "MIT",
48
48
  "dependencies": {
49
49
  "@animalabs/chronicle": "^0.3.0",
50
- "@animalabs/context-manager": "^0.6.0",
50
+ "@animalabs/context-manager": "^0.8.0",
51
51
  "@animalabs/membrane": "^0.5.78",
52
52
  "chokidar": "^4.0.3",
53
53
  "discord.js": "^14.25.1",
package/src/agent.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import type { Membrane, NormalizedMessage, NormalizedRequest, ContentBlock, YieldingStream } from '@animalabs/membrane';
2
2
  import { isAbortedResponse } from '@animalabs/membrane';
3
+ import { createHash } from 'node:crypto';
4
+ import type { CacheWireReceipt, KvUnifiedRequestHooks } from './kv-unified-wire.js';
3
5
  import {
4
6
  toolResultDataToHistoryString,
5
7
  truncateForHistory,
@@ -9,6 +11,8 @@ import {
9
11
  export interface StartStreamResult {
10
12
  stream: YieldingStream;
11
13
  request: NormalizedRequest;
14
+ takeKvSubmission?: () => { submissionId: string; wireReceipt: CacheWireReceipt } | undefined;
15
+ drainKvSubmissionIds?: () => string[];
12
16
  }
13
17
  import type {
14
18
  ContextManager,
@@ -37,6 +41,18 @@ import type {
37
41
  AgentRuntimeSettingsOverrides,
38
42
  } from './types/index.js';
39
43
 
44
+ function stableHash(value: unknown): string {
45
+ const encode = (item: unknown): string => {
46
+ if (Array.isArray(item)) return `[${item.map(encode).join(',')}]`;
47
+ if (item && typeof item === 'object') {
48
+ const record = item as Record<string, unknown>;
49
+ return `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${encode(record[key])}`).join(',')}}`;
50
+ }
51
+ return JSON.stringify(item) ?? 'null';
52
+ };
53
+ return createHash('sha256').update(encode(value)).digest('hex');
54
+ }
55
+
40
56
  const DEFAULT_CONTEXT_BUDGET_TOKENS = 100_000;
41
57
  const DEFAULT_TRANSITION_PACE_TOKENS = 16_000;
42
58
  const DEFAULT_SAME_ROUND_THINK_TEXT_POLICY: SameRoundThinkTextPolicy = 'public';
@@ -68,6 +84,8 @@ export class Agent {
68
84
  readonly refusalHandling: AgentConfig['refusalHandling'];
69
85
  /** Prose delivery mode (see AgentConfig.proseRouting). Default 'locus'. */
70
86
  readonly proseRouting: 'locus' | 'explicit' | 'hybrid' | 'disabled';
87
+ /** Exact whole-response known-tool wrapper containment (default off). */
88
+ readonly toolWrapperProseGuard: boolean;
71
89
  /** Prompt-cache TTL forwarded to the provider (see AgentConfig.cacheTtl). */
72
90
  readonly cacheTtl: NonNullable<AgentConfig['cacheTtl']>;
73
91
  /** Emit prompt-cache markers on requests (see AgentConfig.promptCaching). */
@@ -121,6 +139,7 @@ export class Agent {
121
139
  this.thinking = config.thinking;
122
140
  this.refusalHandling = config.refusalHandling;
123
141
  this.proseRouting = config.proseRouting ?? 'locus';
142
+ this.toolWrapperProseGuard = config.toolWrapperProseGuard ?? false;
124
143
  this.cacheTtl = config.cacheTtl ?? '1h';
125
144
  this.promptCaching = config.promptCaching ?? true;
126
145
  this.prefillUserMessage = config.prefillUserMessage;
@@ -442,9 +461,12 @@ export class Agent {
442
461
  */
443
462
  async compileWithInjections(
444
463
  budget?: TokenBudget,
445
- injections?: ContextInjection[]
464
+ injections?: ContextInjection[],
465
+ opts?: { kvUnifiedImmutablePrefixHash?: string },
446
466
  ): Promise<CompileResult> {
447
- const result = await this.contextManager.compile(this.resolveBudget(budget), injections);
467
+ const result = await this.contextManager.compile(
468
+ this.resolveBudget(budget), injections, opts as never,
469
+ );
448
470
  if (!budget) this.settleRuntimeSettingsTransition();
449
471
  return result;
450
472
  }
@@ -623,7 +645,26 @@ export class Agent {
623
645
  (this.contextManager as unknown as { setToolDefinitions?: (t: ToolDefinition[]) => void })
624
646
  .setToolDefinitions?.(availableTools);
625
647
 
626
- let { messages, systemInjections } = await this.compileWithInjections(budget, injections);
648
+ const strategy = (this.contextManager as unknown as { getStrategy?: () => unknown })
649
+ .getStrategy?.() as {
650
+ beginKvUnifiedSubmission?: (args: { submissionId: string; requestHash: string; layoutHash: string }) => void;
651
+ isKvUnifiedEnabled?: () => boolean;
652
+ };
653
+ const kvUnified = strategy?.isKvUnifiedEnabled?.() === true;
654
+ const prospectiveSystemInjections = (injections ?? [])
655
+ .filter((injection) => injection.position === 'system')
656
+ .flatMap((injection) => injection.content);
657
+ const immutablePrefixHash = kvUnified
658
+ ? stableHash({
659
+ tools: availableTools.length > 0 ? availableTools : undefined,
660
+ system: this.buildSystemPrompt(prospectiveSystemInjections),
661
+ })
662
+ : undefined;
663
+ let { messages, systemInjections } = await this.compileWithInjections(
664
+ budget,
665
+ injections,
666
+ immutablePrefixHash ? { kvUnifiedImmutablePrefixHash: immutablePrefixHash } : undefined,
667
+ );
627
668
 
628
669
  // Sanitize: strip empty/whitespace text blocks and drop messages left with
629
670
  // no content. The Anthropic API rejects empty text blocks with 400
@@ -668,6 +709,7 @@ export class Agent {
668
709
  },
669
710
  tools: availableTools.length > 0 ? availableTools : undefined,
670
711
  promptCaching: this.promptCaching,
712
+ ...(kvUnified ? { cacheMarkers: 'cm-owned' as const } : {}),
671
713
  cacheTtl: this.cacheTtl,
672
714
  ...(this.prefillUserMessage && { prefillUserMessage: this.prefillUserMessage }),
673
715
  ...(this.providerParams && { providerParams: this.providerParams }),
@@ -702,6 +744,28 @@ export class Agent {
702
744
 
703
745
  const request = await this.buildActivationRequest(availableTools, injections, budget);
704
746
 
747
+ const receiptAware = (this.contextManager as unknown as { getStrategy?: () => unknown })
748
+ .getStrategy?.() as {
749
+ beginKvUnifiedSubmission?: (args: { submissionId: string; requestHash: string; layoutHash: string }) => void;
750
+ isKvUnifiedEnabled?: () => boolean;
751
+ };
752
+ const kvEnabled = receiptAware?.isKvUnifiedEnabled?.() === true;
753
+ const kvQueue: Array<{ submissionId: string; wireReceipt: CacheWireReceipt }> = [];
754
+ let kvCall = 0;
755
+ if (kvEnabled) {
756
+ const layoutHash = stableHash(request.messages);
757
+ const kvRequest = request as NormalizedRequest & KvUnifiedRequestHooks;
758
+ kvRequest.onCacheWireReceipt = (receipt) => {
759
+ const submissionId = `${this.name}:${this._streamId}:${Date.now()}:${kvCall++}`;
760
+ receiptAware.beginKvUnifiedSubmission!({
761
+ submissionId,
762
+ requestHash: receipt.requestHash,
763
+ layoutHash,
764
+ });
765
+ kvQueue.push({ submissionId, wireReceipt: receipt });
766
+ };
767
+ }
768
+
705
769
  const stream = this.membrane.streamYielding(request, {
706
770
  emitTokens: true,
707
771
  emitBlocks: false,
@@ -715,7 +779,16 @@ export class Agent {
715
779
  });
716
780
 
717
781
  this._state = { status: 'streaming', stream };
718
- return { stream, request };
782
+ return {
783
+ stream,
784
+ request,
785
+ ...(kvEnabled
786
+ ? {
787
+ takeKvSubmission: () => kvQueue.shift(),
788
+ drainKvSubmissionIds: () => kvQueue.splice(0).map((item) => item.submissionId),
789
+ }
790
+ : {}),
791
+ };
719
792
  }
720
793
 
721
794
  /**