agentfootprint 2.1.0 → 2.3.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 (164) hide show
  1. package/AGENTS.md +80 -0
  2. package/CLAUDE.md +80 -0
  3. package/README.md +51 -1
  4. package/README.proposed.md +258 -0
  5. package/ai-instructions/claude-code/SKILL.md +56 -5
  6. package/ai-instructions/clinerules +44 -5
  7. package/ai-instructions/copilot-instructions.md +44 -5
  8. package/ai-instructions/cursor/agentfootprint.md +44 -5
  9. package/ai-instructions/kiro/agentfootprint.md +44 -5
  10. package/ai-instructions/windsurfrules +44 -5
  11. package/dist/adapters/llm/AnthropicProvider.js +0 -31
  12. package/dist/adapters/llm/AnthropicProvider.js.map +1 -1
  13. package/dist/adapters/llm/BedrockProvider.js +2 -28
  14. package/dist/adapters/llm/BedrockProvider.js.map +1 -1
  15. package/dist/adapters/llm/BrowserAnthropicProvider.js +1 -31
  16. package/dist/adapters/llm/BrowserAnthropicProvider.js.map +1 -1
  17. package/dist/adapters/llm/BrowserOpenAIProvider.js +1 -11
  18. package/dist/adapters/llm/BrowserOpenAIProvider.js.map +1 -1
  19. package/dist/adapters/llm/MockProvider.js +35 -1
  20. package/dist/adapters/llm/MockProvider.js.map +1 -1
  21. package/dist/adapters/llm/OpenAIProvider.js +3 -29
  22. package/dist/adapters/llm/OpenAIProvider.js.map +1 -1
  23. package/dist/adapters/memory/agentcore.js +305 -0
  24. package/dist/adapters/memory/agentcore.js.map +1 -0
  25. package/dist/adapters/memory/redis.js +287 -0
  26. package/dist/adapters/memory/redis.js.map +1 -0
  27. package/dist/core/Agent.js +11 -0
  28. package/dist/core/Agent.js.map +1 -1
  29. package/dist/esm/adapters/llm/AnthropicProvider.js +0 -31
  30. package/dist/esm/adapters/llm/AnthropicProvider.js.map +1 -1
  31. package/dist/esm/adapters/llm/BedrockProvider.js +2 -28
  32. package/dist/esm/adapters/llm/BedrockProvider.js.map +1 -1
  33. package/dist/esm/adapters/llm/BrowserAnthropicProvider.js +1 -31
  34. package/dist/esm/adapters/llm/BrowserAnthropicProvider.js.map +1 -1
  35. package/dist/esm/adapters/llm/BrowserOpenAIProvider.js +1 -11
  36. package/dist/esm/adapters/llm/BrowserOpenAIProvider.js.map +1 -1
  37. package/dist/esm/adapters/llm/MockProvider.js +35 -1
  38. package/dist/esm/adapters/llm/MockProvider.js.map +1 -1
  39. package/dist/esm/adapters/llm/OpenAIProvider.js +3 -29
  40. package/dist/esm/adapters/llm/OpenAIProvider.js.map +1 -1
  41. package/dist/esm/adapters/memory/agentcore.js +301 -0
  42. package/dist/esm/adapters/memory/agentcore.js.map +1 -0
  43. package/dist/esm/adapters/memory/redis.js +283 -0
  44. package/dist/esm/adapters/memory/redis.js.map +1 -0
  45. package/dist/esm/core/Agent.js +11 -0
  46. package/dist/esm/core/Agent.js.map +1 -1
  47. package/dist/esm/index.js +6 -1
  48. package/dist/esm/index.js.map +1 -1
  49. package/dist/esm/lib/injection-engine/index.js +0 -54
  50. package/dist/esm/lib/injection-engine/index.js.map +1 -1
  51. package/dist/esm/lib/mcp/index.js +9 -0
  52. package/dist/esm/lib/mcp/index.js.map +1 -0
  53. package/dist/esm/lib/mcp/mcpClient.js +176 -0
  54. package/dist/esm/lib/mcp/mcpClient.js.map +1 -0
  55. package/dist/esm/lib/mcp/mockMcpClient.js +97 -0
  56. package/dist/esm/lib/mcp/mockMcpClient.js.map +1 -0
  57. package/dist/esm/lib/mcp/types.js +24 -0
  58. package/dist/esm/lib/mcp/types.js.map +1 -0
  59. package/dist/esm/lib/rag/defineRAG.js +0 -18
  60. package/dist/esm/lib/rag/defineRAG.js.map +1 -1
  61. package/dist/esm/lib/rag/indexDocuments.js +39 -4
  62. package/dist/esm/lib/rag/indexDocuments.js.map +1 -1
  63. package/dist/esm/memory/causal/loadSnapshot.js +1 -1
  64. package/dist/esm/memory/define.js +0 -14
  65. package/dist/esm/memory/define.js.map +1 -1
  66. package/dist/esm/memory/define.types.js +0 -10
  67. package/dist/esm/memory/define.types.js.map +1 -1
  68. package/dist/esm/resilience/index.js +0 -44
  69. package/dist/esm/resilience/index.js.map +1 -1
  70. package/dist/esm/stream.js +0 -29
  71. package/dist/esm/stream.js.map +1 -1
  72. package/dist/index.js +8 -1
  73. package/dist/index.js.map +1 -1
  74. package/dist/instructions.js +21 -0
  75. package/dist/instructions.js.map +1 -0
  76. package/dist/lib/injection-engine/index.js +0 -54
  77. package/dist/lib/injection-engine/index.js.map +1 -1
  78. package/dist/lib/instructions/defineInstruction.js +35 -0
  79. package/dist/lib/instructions/defineInstruction.js.map +1 -0
  80. package/dist/lib/instructions/evaluator.js +38 -0
  81. package/dist/lib/instructions/evaluator.js.map +1 -0
  82. package/dist/lib/instructions/index.js +48 -0
  83. package/dist/lib/instructions/index.js.map +1 -0
  84. package/dist/lib/instructions/types.js +22 -0
  85. package/dist/lib/instructions/types.js.map +1 -0
  86. package/dist/lib/mcp/index.js +14 -0
  87. package/dist/lib/mcp/index.js.map +1 -0
  88. package/dist/lib/mcp/mcpClient.js +180 -0
  89. package/dist/lib/mcp/mcpClient.js.map +1 -0
  90. package/dist/lib/mcp/mockMcpClient.js +101 -0
  91. package/dist/lib/mcp/mockMcpClient.js.map +1 -0
  92. package/dist/lib/mcp/types.js +25 -0
  93. package/dist/lib/mcp/types.js.map +1 -0
  94. package/dist/lib/rag/defineRAG.js +0 -18
  95. package/dist/lib/rag/defineRAG.js.map +1 -1
  96. package/dist/lib/rag/indexDocuments.js +39 -4
  97. package/dist/lib/rag/indexDocuments.js.map +1 -1
  98. package/dist/memory/causal/loadSnapshot.js +1 -1
  99. package/dist/memory/conversationHelpers.js +39 -0
  100. package/dist/memory/conversationHelpers.js.map +1 -0
  101. package/dist/memory/define.js +0 -14
  102. package/dist/memory/define.js.map +1 -1
  103. package/dist/memory/define.types.js +0 -10
  104. package/dist/memory/define.types.js.map +1 -1
  105. package/dist/resilience/index.js +0 -44
  106. package/dist/resilience/index.js.map +1 -1
  107. package/dist/stream.js +0 -29
  108. package/dist/stream.js.map +1 -1
  109. package/dist/types/adapters/llm/AnthropicProvider.d.ts +0 -31
  110. package/dist/types/adapters/llm/AnthropicProvider.d.ts.map +1 -1
  111. package/dist/types/adapters/llm/BedrockProvider.d.ts +2 -28
  112. package/dist/types/adapters/llm/BedrockProvider.d.ts.map +1 -1
  113. package/dist/types/adapters/llm/BrowserAnthropicProvider.d.ts +1 -31
  114. package/dist/types/adapters/llm/BrowserAnthropicProvider.d.ts.map +1 -1
  115. package/dist/types/adapters/llm/BrowserOpenAIProvider.d.ts +1 -11
  116. package/dist/types/adapters/llm/BrowserOpenAIProvider.d.ts.map +1 -1
  117. package/dist/types/adapters/llm/MockProvider.d.ts +45 -0
  118. package/dist/types/adapters/llm/MockProvider.d.ts.map +1 -1
  119. package/dist/types/adapters/llm/OpenAIProvider.d.ts +3 -29
  120. package/dist/types/adapters/llm/OpenAIProvider.d.ts.map +1 -1
  121. package/dist/types/adapters/memory/agentcore.d.ts +157 -0
  122. package/dist/types/adapters/memory/agentcore.d.ts.map +1 -0
  123. package/dist/types/adapters/memory/redis.d.ts +126 -0
  124. package/dist/types/adapters/memory/redis.d.ts.map +1 -0
  125. package/dist/types/core/Agent.d.ts +7 -0
  126. package/dist/types/core/Agent.d.ts.map +1 -1
  127. package/dist/types/index.d.ts +2 -1
  128. package/dist/types/index.d.ts.map +1 -1
  129. package/dist/types/instructions.d.ts +5 -0
  130. package/dist/types/instructions.d.ts.map +1 -0
  131. package/dist/types/lib/injection-engine/index.d.ts +0 -54
  132. package/dist/types/lib/injection-engine/index.d.ts.map +1 -1
  133. package/dist/types/lib/instructions/defineInstruction.d.ts +22 -0
  134. package/dist/types/lib/instructions/defineInstruction.d.ts.map +1 -0
  135. package/dist/types/lib/instructions/evaluator.d.ts +11 -0
  136. package/dist/types/lib/instructions/evaluator.d.ts.map +1 -0
  137. package/dist/types/lib/instructions/index.d.ts +44 -0
  138. package/dist/types/lib/instructions/index.d.ts.map +1 -0
  139. package/dist/types/lib/instructions/types.d.ts +100 -0
  140. package/dist/types/lib/instructions/types.d.ts.map +1 -0
  141. package/dist/types/lib/mcp/index.d.ts +10 -0
  142. package/dist/types/lib/mcp/index.d.ts.map +1 -0
  143. package/dist/types/lib/mcp/mcpClient.d.ts +47 -0
  144. package/dist/types/lib/mcp/mcpClient.d.ts.map +1 -0
  145. package/dist/types/lib/mcp/mockMcpClient.d.ts +66 -0
  146. package/dist/types/lib/mcp/mockMcpClient.d.ts.map +1 -0
  147. package/dist/types/lib/mcp/types.d.ts +134 -0
  148. package/dist/types/lib/mcp/types.d.ts.map +1 -0
  149. package/dist/types/lib/rag/defineRAG.d.ts +18 -21
  150. package/dist/types/lib/rag/defineRAG.d.ts.map +1 -1
  151. package/dist/types/lib/rag/indexDocuments.d.ts +30 -1
  152. package/dist/types/lib/rag/indexDocuments.d.ts.map +1 -1
  153. package/dist/types/memory/causal/loadSnapshot.d.ts +1 -1
  154. package/dist/types/memory/conversationHelpers.d.ts +19 -0
  155. package/dist/types/memory/conversationHelpers.d.ts.map +1 -0
  156. package/dist/types/memory/define.d.ts +0 -14
  157. package/dist/types/memory/define.d.ts.map +1 -1
  158. package/dist/types/memory/define.types.d.ts +2 -12
  159. package/dist/types/memory/define.types.d.ts.map +1 -1
  160. package/dist/types/resilience/index.d.ts +0 -44
  161. package/dist/types/resilience/index.d.ts.map +1 -1
  162. package/dist/types/stream.d.ts +0 -29
  163. package/dist/types/stream.d.ts.map +1 -1
  164. package/package.json +20 -1
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Instruction evaluator — runs the `activeWhen` predicates and
3
+ * returns the active set + any skipped predicates.
4
+ *
5
+ * Pattern: Pure function. Stateless.
6
+ * Role: Internal helper used by Agent during pre-LLM stage.
7
+ * Emits: N/A — caller handles emit + observability.
8
+ */
9
+ import type { Instruction, InstructionContext, InstructionEvaluation } from './types.js';
10
+ export declare function evaluateInstructions(instructions: readonly Instruction[], ctx: InstructionContext): InstructionEvaluation;
11
+ //# sourceMappingURL=evaluator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluator.d.ts","sourceRoot":"","sources":["../../../../src/lib/instructions/evaluator.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,kBAAkB,EAClB,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAEpB,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,SAAS,WAAW,EAAE,EACpC,GAAG,EAAE,kBAAkB,GACtB,qBAAqB,CAwBvB"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Instructions — declarative rule-based system-prompt injection.
3
+ *
4
+ * Public API for the v2 Instructions subsystem. See `types.ts` for the
5
+ * full interface + the unified context-engineering model placement.
6
+ *
7
+ * ─── 7-panel design review (2026-04-28) ─────────────────────────────
8
+ *
9
+ * LLM-AI system design ✓ Maps cleanly to the unified context-
10
+ * engineering model: slot=system-prompt
11
+ * (+optional tools), role=system, timing=
12
+ * per-iteration, decision=rule.
13
+ * Performance ✓ Predicates run once per iteration (not
14
+ * per token / per event). O(N) in number
15
+ * of instructions; typical N ≤ 20.
16
+ * Scalability ✓ Stateless evaluator; many concurrent
17
+ * agents share the same instruction list
18
+ * via Object.freeze.
19
+ * Research alignment ✓ Mirrors v1 AgentInstruction's `activeWhen`
20
+ * shape (origin/main `c6e11d0`) but drops
21
+ * `onToolResult`, `safety`, decision-scope
22
+ * wrapping for v2 simplicity. Equivalent
23
+ * tool-result-driven behavior is expressed
24
+ * via `activeWhen: (ctx) =>
25
+ * ctx.lastToolResult?.toolName === 'X'`.
26
+ * Flexibility ✓ Same Instruction can be active across
27
+ * multiple iterations; can inject tools
28
+ * in addition to prompt; predicates can
29
+ * inspect history + last tool result.
30
+ * Abstraction-modular ✓ Three small files: types, builder,
31
+ * evaluator. Agent integration is one
32
+ * call into `evaluateInstructions()`.
33
+ * Software engineering ✓ Predicate errors are caught + surfaced
34
+ * (no crash). Frozen instructions prevent
35
+ * mutation. 7-pattern test coverage.
36
+ *
37
+ * ─── 7-pattern test coverage ────────────────────────────────────────
38
+ *
39
+ * See `test/lib/instructions/*.test.ts`.
40
+ */
41
+ export { defineInstruction, type DefineInstructionOptions, } from './defineInstruction.js';
42
+ export { evaluateInstructions, } from './evaluator.js';
43
+ export type { Instruction, InstructionContext, InstructionEvaluation, } from './types.js';
44
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/instructions/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,EACL,iBAAiB,EACjB,KAAK,wBAAwB,GAC9B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AAExB,YAAY,EACV,WAAW,EACX,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Instructions — types.
3
+ *
4
+ * An Instruction is a declarative rule for conditional system-prompt
5
+ * injection. The agent evaluates each Instruction's `activeWhen`
6
+ * predicate at the start of every iteration; matching instructions'
7
+ * `prompt` text is prepended to the system prompt for that iteration.
8
+ *
9
+ * This is the rule-based flavor of the unified context-engineering
10
+ * model: slot=system-prompt, role=system, timing=per-iteration,
11
+ * decision=rule. (Compare with Skills: timing=on-activation,
12
+ * decision=LLM-guided.)
13
+ *
14
+ * Pattern: Strategy (GoF) — each Instruction is a strategy for
15
+ * "should I add this prompt to the next iteration?"
16
+ * Role: Consumer-facing shape. Agent.create(...).instruction(...).
17
+ * Emits: `agentfootprint.context.injected` with source='instruction'
18
+ * when an instruction activates.
19
+ */
20
+ import type { Tool } from '../../core/tools.js';
21
+ /**
22
+ * Read-only snapshot of the agent's state that an Instruction can
23
+ * inspect to decide activation. Includes only the fields a predicate
24
+ * can safely depend on — internal mutable state is hidden.
25
+ */
26
+ export interface InstructionContext {
27
+ /** Current ReAct iteration (1-based). */
28
+ readonly iteration: number;
29
+ /** The current user message that started this turn. */
30
+ readonly userMessage: string;
31
+ /**
32
+ * Conversation history up to (but not including) the current
33
+ * iteration's LLM call. Includes system / user / assistant / tool
34
+ * messages from prior iterations of the same turn.
35
+ */
36
+ readonly history: ReadonlyArray<{
37
+ readonly role: 'system' | 'user' | 'assistant' | 'tool';
38
+ readonly content: string;
39
+ readonly toolName?: string;
40
+ }>;
41
+ /**
42
+ * The most recent tool result, if the previous iteration ended in a
43
+ * tool call. Undefined on the first iteration of a turn.
44
+ */
45
+ readonly lastToolResult?: {
46
+ readonly toolName: string;
47
+ readonly result: string;
48
+ };
49
+ /** Custom decision-scope state the consumer placed via Agent options. */
50
+ readonly decision?: Readonly<Record<string, unknown>>;
51
+ }
52
+ /**
53
+ * A single declarative instruction.
54
+ *
55
+ * @example
56
+ * const calmTone = defineInstruction({
57
+ * id: 'calm-tone',
58
+ * description: 'Use a calm, empathetic tone after the user expresses frustration.',
59
+ * activeWhen: (ctx) => ctx.userMessage.includes('frustrated')
60
+ * || ctx.userMessage.includes('angry'),
61
+ * prompt: 'The user is upset. Respond calmly. Acknowledge feelings before facts.',
62
+ * });
63
+ *
64
+ * const agent = Agent.create({ provider }).instruction(calmTone).build();
65
+ */
66
+ export interface Instruction {
67
+ /** Unique id — used for observability + de-duplication. */
68
+ readonly id: string;
69
+ /** Human-readable description (Lens / docs / debug). */
70
+ readonly description?: string;
71
+ /**
72
+ * Predicate to decide activation. Synchronous; side-effect free.
73
+ * If omitted, the instruction is always active. Predicates that
74
+ * throw are skipped (fail-open) and the error is surfaced via the
75
+ * emit channel for observability — they don't crash the run.
76
+ */
77
+ readonly activeWhen?: (ctx: InstructionContext) => boolean;
78
+ /** Text appended to the next iteration's system prompt when active. */
79
+ readonly prompt?: string;
80
+ /**
81
+ * Tools to add to the agent's tool registry when the instruction is
82
+ * active. Merged with the agent's base tools (later instructions win
83
+ * on duplicate ids). Empty by default.
84
+ */
85
+ readonly tools?: readonly Tool[];
86
+ }
87
+ /**
88
+ * @internal
89
+ * Branded result returned by `evaluateInstructions()`. Lets the
90
+ * agent's pre-LLM stage consume the projection without re-running
91
+ * the predicates.
92
+ */
93
+ export interface InstructionEvaluation {
94
+ readonly active: readonly Instruction[];
95
+ readonly skipped: ReadonlyArray<{
96
+ readonly id: string;
97
+ readonly error: string;
98
+ }>;
99
+ }
100
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/lib/instructions/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAEhD;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,yCAAyC;IACzC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,uDAAuD;IACvD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;QAC9B,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;QACxD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;KAC5B,CAAC,CAAC;IACH;;;OAGG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE;QACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,yEAAyE;IACzE,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACvD;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,WAAW;IAC1B,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,kBAAkB,KAAK,OAAO,CAAC;IAC3D,uEAAuE;IACvE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,IAAI,EAAE,CAAC;CAClC;AAED;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,CAAC;IACxC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAClF"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * MCP — Model Context Protocol client integration. Connect to an MCP
3
+ * server, register its tools on your Agent. Server-side support is
4
+ * separate (consumer exposes their agent as an MCP tool — different
5
+ * use case, not yet shipped).
6
+ */
7
+ export { mcpClient } from './mcpClient.js';
8
+ export { mockMcpClient, type MockMcpClientOptions, type MockMcpTool } from './mockMcpClient.js';
9
+ export type { McpClient, McpClientOptions, McpHttpTransport, McpStdioTransport, McpTransport, McpSdkClient, } from './types.js';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/mcp/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAChG,YAAY,EACV,SAAS,EACT,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EACZ,YAAY,GACb,MAAM,YAAY,CAAC"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * mcpClient — connect to an MCP server, expose its tools to your Agent.
3
+ *
4
+ * const slack = await mcpClient({
5
+ * name: 'slack',
6
+ * transport: { transport: 'stdio', command: 'npx', args: ['@example/slack-mcp'] },
7
+ * });
8
+ *
9
+ * const tools = await slack.tools(); // → readonly Tool[]
10
+ * const agent = Agent.create({ ... }).tools(tools).build();
11
+ *
12
+ * // ...
13
+ *
14
+ * await slack.close();
15
+ *
16
+ * Pattern: Adapter (GoF) — translates MCP `listTools()` / `callTool()`
17
+ * into agentfootprint's `Tool` interface (schema + execute).
18
+ * Each MCP tool becomes ONE agentfootprint Tool. The agent's
19
+ * existing tool-call handler invokes `client.callTool()`
20
+ * inside the wrapped `execute`.
21
+ *
22
+ * Role: Layer-3 integration. Sits next to `defineTool` — same
23
+ * shape, different source. Once tools land on the agent,
24
+ * the rest of the library doesn't know they came from MCP.
25
+ *
26
+ * Emits: N/A — wrapped tools emit the standard
27
+ * `agentfootprint.stream.tool_start` / `tool_end` events
28
+ * when the agent calls them. Add `name: '<mcp-server>'` to
29
+ * `McpClientOptions` so observability surfaces can group
30
+ * tool calls by server.
31
+ *
32
+ * Lazy-require pattern: the `@modelcontextprotocol/sdk` peer-dep
33
+ * loads only when a consumer actually constructs a client. Tests
34
+ * inject `_client` and skip the import path entirely.
35
+ */
36
+ import type { McpClient, McpClientOptions } from './types.js';
37
+ /**
38
+ * Connect to an MCP server. Returns an `McpClient` that exposes the
39
+ * server's tools as agentfootprint `Tool[]` and a `close()` to tear
40
+ * down the transport.
41
+ *
42
+ * @throws when `@modelcontextprotocol/sdk` is not installed (see
43
+ * error message for `npm install` hint), or when the transport
44
+ * fails to connect.
45
+ */
46
+ export declare function mcpClient(opts: McpClientOptions): Promise<McpClient>;
47
+ //# sourceMappingURL=mcpClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcpClient.d.ts","sourceRoot":"","sources":["../../../../src/lib/mcp/mcpClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAA8B,MAAM,YAAY,CAAC;AAU1F;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,SAAS,CAAC,CAyC1E"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * mockMcpClient — in-memory MCP client for development and tests.
3
+ *
4
+ * const slack = mockMcpClient({
5
+ * tools: [
6
+ * {
7
+ * name: 'send_message',
8
+ * description: 'Post a message to a channel',
9
+ * inputSchema: { type: 'object' },
10
+ * handler: async ({ text }) => `Posted: ${text}`,
11
+ * },
12
+ * ],
13
+ * });
14
+ *
15
+ * const agent = Agent.create({ provider: mock({ reply: 'ok' }) })
16
+ * .tools(await slack.tools())
17
+ * .build();
18
+ *
19
+ * Pattern: Adapter (GoF) — produces an `McpClient` with the same shape
20
+ * as `mcpClient(opts)` but driven by an in-memory tool table
21
+ * instead of the MCP SDK + transport. Drop-in for development:
22
+ * start with `mockMcpClient`, swap to `mcpClient` once the
23
+ * real server is ready.
24
+ *
25
+ * Why public: `mcpClient`'s `_client` injection is `@internal` because
26
+ * the SDK shape isn't a stable public surface. `mockMcpClient` exposes
27
+ * a curated tool-handler shape that's tied to OUR Tool contract instead
28
+ * — stable, documented, and the right level of abstraction for
29
+ * mock-first development.
30
+ */
31
+ import type { McpClient } from './types.js';
32
+ /** A scripted tool exposed by the mock MCP server. */
33
+ export interface MockMcpTool {
34
+ /** Tool name as the LLM sees it. */
35
+ readonly name: string;
36
+ /** Description surfaced to the LLM via the tool schema. */
37
+ readonly description?: string;
38
+ /**
39
+ * JSON-schema-like input schema. Passed through to the agent's tool
40
+ * registry verbatim — same as a real MCP server's `listTools()`.
41
+ */
42
+ readonly inputSchema: Readonly<Record<string, unknown>>;
43
+ /**
44
+ * Async handler that runs when the agent calls this tool. Receives
45
+ * the args the LLM produced; returns the string result the agent
46
+ * sees as the tool-result message.
47
+ *
48
+ * Defaults to `async () => '[mock result]'` when omitted — useful
49
+ * when the consumer cares about wiring not behavior.
50
+ */
51
+ readonly handler?: (args: Record<string, unknown>) => Promise<string>;
52
+ }
53
+ export interface MockMcpClientOptions {
54
+ /** Logical server name. Surfaces in observability + error messages. */
55
+ readonly name?: string;
56
+ /** Tools exposed by the mock server. */
57
+ readonly tools: readonly MockMcpTool[];
58
+ }
59
+ /**
60
+ * Build an in-memory `McpClient`. Useful when you want to develop
61
+ * against MCP semantics without spawning subprocesses, hitting the
62
+ * network, or installing `@modelcontextprotocol/sdk`. Same `McpClient`
63
+ * shape as `mcpClient(opts)` — code that consumes one accepts the other.
64
+ */
65
+ export declare function mockMcpClient(options: MockMcpClientOptions): McpClient;
66
+ //# sourceMappingURL=mockMcpClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mockMcpClient.d.ts","sourceRoot":"","sources":["../../../../src/lib/mcp/mockMcpClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,sDAAsD;AACtD,MAAM,WAAW,WAAW;IAC1B,oCAAoC;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,2DAA2D;IAC3D,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;;OAGG;IACH,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACxD;;;;;;;OAOG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CACvE;AAED,MAAM,WAAW,oBAAoB;IACnC,uEAAuE;IACvE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,wCAAwC;IACxC,QAAQ,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,CAAC;CACxC;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,SAAS,CAoCtE"}
@@ -0,0 +1,134 @@
1
+ /**
2
+ * MCP — Model Context Protocol client integration.
3
+ *
4
+ * MCP (https://modelcontextprotocol.io) is an open standard for
5
+ * connecting LLMs to external tools and data sources. agentfootprint's
6
+ * MCP adapter is **client-only** — it consumes MCP servers and exposes
7
+ * their tools as agentfootprint `Tool[]` so consumers can plug them
8
+ * straight into `agent.tool(...)`.
9
+ *
10
+ * Pattern: Adapter (GoF) — translates MCP wire format ↔ agentfootprint
11
+ * `Tool` interface. The MCP SDK does the protocol work; we
12
+ * just bridge.
13
+ * Role: Layer-3 tool integration. Pairs with `defineTool` (the
14
+ * inline alternative for non-MCP tools).
15
+ * Emits: N/A directly — wrapped tools emit the standard
16
+ * `agentfootprint.stream.tool_start` / `tool_end` events
17
+ * when the agent calls them.
18
+ *
19
+ * Server-side support (exposing an agent or LLMCall as an MCP tool)
20
+ * is a separate concern not yet shipped. This module covers the
21
+ * 80% case: pulling an existing MCP server's tools INTO an agent.
22
+ */
23
+ import type { Tool } from '../../core/tools.js';
24
+ /**
25
+ * `stdio` transport — spawns a local subprocess and speaks MCP over
26
+ * its stdin/stdout. Best for development, single-user scenarios, and
27
+ * testing against locally-installed MCP servers.
28
+ */
29
+ export interface McpStdioTransport {
30
+ readonly transport: 'stdio';
31
+ /** Executable to spawn (e.g., `'npx'`, `'node'`, `'python'`). */
32
+ readonly command: string;
33
+ /** CLI args passed to the executable. */
34
+ readonly args?: readonly string[];
35
+ /** Optional env vars set on the subprocess. */
36
+ readonly env?: Readonly<Record<string, string>>;
37
+ /** Working directory for the subprocess. */
38
+ readonly cwd?: string;
39
+ }
40
+ /**
41
+ * `http` transport — speaks MCP over Streamable HTTP. Best for remote
42
+ * servers, web environments, and multi-user scenarios.
43
+ */
44
+ export interface McpHttpTransport {
45
+ readonly transport: 'http';
46
+ /** MCP server endpoint URL. */
47
+ readonly url: string;
48
+ /** Optional auth headers (e.g., `Authorization: Bearer ...`). */
49
+ readonly headers?: Readonly<Record<string, string>>;
50
+ }
51
+ export type McpTransport = McpStdioTransport | McpHttpTransport;
52
+ export interface McpClientOptions {
53
+ /**
54
+ * Logical name for observability + tool-call routing. Surfaces in
55
+ * Lens chips and event payloads. Defaults to `'mcp'`. Recommend
56
+ * setting per-server (`'slack-mcp'`, `'github-mcp'`) when you
57
+ * connect to multiple servers.
58
+ */
59
+ readonly name?: string;
60
+ /** Transport configuration — stdio or http. */
61
+ readonly transport: McpTransport;
62
+ /**
63
+ * Optional client identity sent on connect. Default:
64
+ * `{ name: 'agentfootprint', version: <package version> }`.
65
+ */
66
+ readonly clientInfo?: {
67
+ readonly name: string;
68
+ readonly version: string;
69
+ };
70
+ /** Abort the connection / list / call paths. Honored by the SDK. */
71
+ readonly signal?: AbortSignal;
72
+ /**
73
+ * @internal Pre-built SDK client for tests. Skips SDK import +
74
+ * transport construction. Same convention as `AnthropicProvider._client`.
75
+ */
76
+ readonly _client?: McpSdkClient;
77
+ }
78
+ /**
79
+ * What `mcpClient(opts)` returns. Connect once; call `.tools()` to
80
+ * snapshot the tool list, `.refresh()` to re-list after the server's
81
+ * tools change, `.close()` when done.
82
+ */
83
+ export interface McpClient {
84
+ /** Logical name from options (or default `'mcp'`). */
85
+ readonly name: string;
86
+ /**
87
+ * List the server's tools as agentfootprint `Tool[]`. First call
88
+ * after `mcpClient(...)` is the snapshot used to register on the
89
+ * agent; subsequent calls re-fetch (cheap, in-memory cached by the
90
+ * SDK between fetches).
91
+ */
92
+ tools(): Promise<readonly Tool[]>;
93
+ /**
94
+ * Force a refresh from the server. Use when you suspect the server
95
+ * has dynamically added/removed tools mid-session (e.g., after the
96
+ * server processes a config update).
97
+ */
98
+ refresh(): Promise<readonly Tool[]>;
99
+ /** Close the underlying transport. After `close()` the client is unusable. */
100
+ close(): Promise<void>;
101
+ }
102
+ /**
103
+ * Minimal structural type capturing the parts of the MCP SDK client
104
+ * we touch. Defined locally so we can:
105
+ * 1. Inject a mock for tests (`McpClientOptions._client`)
106
+ * 2. Avoid a hard import on `@modelcontextprotocol/sdk` (which is
107
+ * a lazy peer-dep)
108
+ *
109
+ * The real SDK exports a richer surface; we narrow to what's needed.
110
+ */
111
+ export interface McpSdkClient {
112
+ connect(transport: unknown): Promise<void>;
113
+ listTools(): Promise<{
114
+ readonly tools: ReadonlyArray<{
115
+ readonly name: string;
116
+ readonly description?: string;
117
+ readonly inputSchema: Readonly<Record<string, unknown>>;
118
+ }>;
119
+ }>;
120
+ callTool(args: {
121
+ readonly name: string;
122
+ readonly arguments?: Readonly<Record<string, unknown>>;
123
+ /** Forwarded from `McpClientOptions.signal` so consumers can cancel hung tool calls. */
124
+ readonly signal?: AbortSignal;
125
+ }): Promise<{
126
+ readonly content: ReadonlyArray<{
127
+ readonly type: string;
128
+ readonly text?: string;
129
+ }>;
130
+ readonly isError?: boolean;
131
+ }>;
132
+ close(): Promise<void>;
133
+ }
134
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/lib/mcp/types.ts"],"names":[],"mappings":"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"}
@@ -29,24 +29,6 @@
29
29
  * `agentfootprint.context.injected` when retrieved chunks
30
30
  * land in the messages slot.
31
31
  *
32
- * 7-panel review (2026-04-29):
33
- * - LLM Systems ✅ injects as 'user' role by default — RAG chunks
34
- * land where the LLM treats them as authoritative
35
- * retrieved context, not behavior rules
36
- * - Architect ✅ composition over defineMemory; zero new engine
37
- * code; multi-RAG layering works via per-id keys
38
- * - API Designer ✅ one factory, mirrors defineMemory shape; consumer
39
- * ergonomics: `agent.rag(defineRAG({...}))`
40
- * - Performance ✅ embedding cost is one call per turn (TURN_START
41
- * timing, default); strict threshold prevents
42
- * injecting low-confidence noise
43
- * - Privacy ✅ multi-tenant via MemoryIdentity tuple; doc
44
- * content never crosses tenant boundaries
45
- * - ML / IR ✅ embedder version pinned via `embedderId`; cosine
46
- * score semantics inherited from MemoryStore
47
- * - SoftEng ✅ thin file (this one); existing memory tests
48
- * cover the underlying pipeline
49
- *
50
32
  * @see ./indexDocuments.ts for the seeding helper
51
33
  * @see ../../memory/define.ts for the underlying factory
52
34
  *
@@ -119,13 +101,28 @@ export interface DefineRAGOptions {
119
101
  * Minimum cosine similarity to inject. **Strict** — when no chunk
120
102
  * meets the threshold, NO injection happens (no fallback that would
121
103
  * pollute the prompt with weak matches). Default 0.7.
104
+ *
105
+ * Tuning note: 0.7 is a high bar for some embedders. Sentence-BERT
106
+ * relatives (`all-MiniLM-L6-v2`, etc.) often score 0.4–0.6 even on
107
+ * relevant chunks. If you see frequent zero-result silent skips,
108
+ * lower to ~0.5 and observe the `agentfootprint.context.injected`
109
+ * stream. OpenAI `text-embedding-3-*` and Cohere embed-v3 typically
110
+ * sit comfortably with 0.7.
122
111
  */
123
112
  readonly threshold?: number;
124
113
  /**
125
114
  * Role to use when injecting retrieved chunks into the messages
126
- * slot. Default `'user'` — RAG chunks are most often treated as
127
- * "context the user provided" by LLMs. Use `'system'` for
128
- * authoritative reference docs that should outweigh user instruction.
115
+ * slot. Default `'user'`.
116
+ *
117
+ * Why `'user'`: in tool-using ReAct loops, retrieved chunks
118
+ * conceptually "augment what the user asked." Anthropic's tool-use
119
+ * cookbook and OpenAI's RAG cookbook both show retrieved context
120
+ * inside user-turn messages.
121
+ *
122
+ * Use `'system'` for authoritative reference docs that should
123
+ * outweigh user instruction (policy / compliance / brand-voice
124
+ * corpora). Use `'assistant'` only if you've persisted prior agent
125
+ * turns as context — rare.
129
126
  */
130
127
  readonly asRole?: ContextRole;
131
128
  }
@@ -1 +1 @@
1
- {"version":3,"file":"defineRAG.d.ts","sourceRoot":"","sources":["../../../../src/lib/rag/defineRAG.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8EG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAIrE,MAAM,WAAW,gBAAgB;IAC/B,kEAAkE;IAClE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAE9B;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAE5B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAE5B;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAE7B;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAEvB;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAE5B;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,gBAAgB,CA8BlE"}
1
+ {"version":3,"file":"defineRAG.d.ts","sourceRoot":"","sources":["../../../../src/lib/rag/defineRAG.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAIrE,MAAM,WAAW,gBAAgB;IAC/B,kEAAkE;IAClE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAE9B;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAE5B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAE5B;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAE7B;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAEvB;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAE5B;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,gBAAgB,CA8BlE"}
@@ -41,7 +41,20 @@ export interface IndexDocumentsOptions {
41
41
  /**
42
42
  * Identity scope to write under. Default: a single shared
43
43
  * `{ conversationId: '_global' }` namespace, suitable for app-wide
44
- * corpora. Override for per-tenant document partitions.
44
+ * corpora.
45
+ *
46
+ * **Multi-tenant footgun:** the read side (`agent.run({ identity })`)
47
+ * queries within whichever identity is passed at request time.
48
+ * If you index here under `_global` but query under
49
+ * `{ tenant: 'acme' }`, you'll get ZERO results — silently. Either:
50
+ * 1. Index every document under each tenant's identity (duplicated
51
+ * storage, but isolated), or
52
+ * 2. Index under `_global` AND query under `_global` (shared
53
+ * corpus across tenants — fine for product docs, NOT for
54
+ * tenant-private data), or
55
+ * 3. Use a vector store adapter that supports multi-namespace
56
+ * reads at query time (Pinecone, Qdrant — outside this helper's
57
+ * scope).
45
58
  */
46
59
  readonly identity?: MemoryIdentity;
47
60
  /**
@@ -67,11 +80,27 @@ export interface IndexDocumentsOptions {
67
80
  * this through to abort batch indexing on shutdown / timeout.
68
81
  */
69
82
  readonly signal?: AbortSignal;
83
+ /**
84
+ * Max number of concurrent embed calls when the embedder doesn't
85
+ * implement `embedBatch`. Default `8`. Without this cap, a 10K-doc
86
+ * corpus would fire 10K parallel embed calls and trigger rate limits.
87
+ * Ignored when `embedBatch` is available (the embedder controls
88
+ * its own batching).
89
+ */
90
+ readonly maxConcurrency?: number;
70
91
  }
71
92
  /**
72
93
  * Embed + persist documents. Returns the count actually indexed
73
94
  * (skips duplicates if the store rejects them). Throws on embedder
74
95
  * failure or store error — fail loud at startup is desirable.
96
+ *
97
+ * **Re-indexing semantics:** entries are written with `version: 1` and
98
+ * `putMany` (most adapters: last-write-wins). Re-running this helper
99
+ * after the store has been mutated by other writers may stomp their
100
+ * versions. For idempotent corpus refresh, either delete-then-index
101
+ * or use a custom upsert via `store.putIfVersion()` per document. A
102
+ * first-class `mode: 'upsert' | 'replace'` API is planned for a
103
+ * future release.
75
104
  */
76
105
  export declare function indexDocuments(store: MemoryStore, embedder: Embedder, documents: readonly RagDocument[], options?: IndexDocumentsOptions): Promise<number>;
77
106
  //# sourceMappingURL=indexDocuments.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"indexDocuments.d.ts","sourceRoot":"","sources":["../../../../src/lib/rag/indexDocuments.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAEhE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAErE,4EAA4E;AAC5E,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACvD;AAED,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAC;IAEnC;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAE7B;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;IAExC;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AAID;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,SAAS,WAAW,EAAE,EACjC,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,MAAM,CAAC,CAwCjB"}
1
+ {"version":3,"file":"indexDocuments.d.ts","sourceRoot":"","sources":["../../../../src/lib/rag/indexDocuments.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAEhE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAErE,4EAA4E;AAC5E,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACvD;AAED,MAAM,WAAW,qBAAqB;IACpC;;;;;;;;;;;;;;;;;OAiBG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAC;IAEnC;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAE7B;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;IAExC;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAE9B;;;;;;OAMG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AAID;;;;;;;;;;;;GAYG;AACH,wBAAsB,cAAc,CAClC,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,SAAS,WAAW,EAAE,EACjC,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,MAAM,CAAC,CA6CjB"}
@@ -12,7 +12,7 @@
12
12
  * Strict-threshold semantics:
13
13
  * When `minScore` is set and no past snapshot meets it, returns an
14
14
  * empty `formatted`. NO fallback — garbage past context is worse than
15
- * no context. Aligns with the LLM-systems panel verdict in the design.
15
+ * no context.
16
16
  *
17
17
  * Empty-query handling:
18
18
  * No user message → no embedding → no search → empty result.
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Pure functions for conversation message management.
3
+ * No state — just transformations on message arrays.
4
+ */
5
+ import type { Message, AssistantMessage, ToolResultMessage } from '../types';
6
+ /** Append a message to the conversation. Returns new array. */
7
+ export declare function appendMessage(messages: Message[], message: Message): Message[];
8
+ /** Get the last message in the conversation. */
9
+ export declare function lastMessage(messages: Message[]): Message | undefined;
10
+ /** Get the last assistant message. */
11
+ export declare function lastAssistantMessage(messages: Message[]): AssistantMessage | undefined;
12
+ /** Check if the last assistant message has tool calls. */
13
+ export declare function lastMessageHasToolCalls(messages: Message[]): boolean;
14
+ /** Create tool result messages from a map of tool call ID → result. */
15
+ export declare function createToolResults(results: Array<{
16
+ toolCallId: string;
17
+ content: string;
18
+ }>): ToolResultMessage[];
19
+ //# sourceMappingURL=conversationHelpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversationHelpers.d.ts","sourceRoot":"","sources":["../../../src/memory/conversationHelpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAG7E,+DAA+D;AAC/D,wBAAgB,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,EAAE,CAE9E;AAED,gDAAgD;AAChD,wBAAgB,WAAW,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,GAAG,SAAS,CAEpE;AAED,sCAAsC;AACtC,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,gBAAgB,GAAG,SAAS,CAKtF;AAED,0DAA0D;AAC1D,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAGpE;AAED,uEAAuE;AACvE,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,KAAK,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,GACtD,iBAAiB,EAAE,CAErB"}
@@ -23,22 +23,8 @@
23
23
  * `agentfootprint.context.injected` with `source: 'memory'`
24
24
  * when their formatter writes to the messages slot.
25
25
  *
26
- * 8-panel review (2026-04-28):
27
- * - LLM Systems ✅ asRole knob honored when present, defaults to 'system'
28
- * - Architect ✅ per-id scope keys (`memoryInjectionKey(id)`)
29
- * - API Designer ✅ one factory; CAUSAL stays here, no separate snapshotMemory
30
- * - Performance ✅ default `MEMORY_TIMING.TURN_START`; pipelines compiled once
31
- * - Privacy ✅ redact field passes through
32
- * - ML / IR ✅ threshold maps to semantic.minScore strictly; no fallback
33
- * - SoftEng ✅ unsupported combos throw with clear remediation hint
34
- * - TS Engineer ✅ discriminated union narrowing preserved across switches
35
- *
36
- * Book reference: AI Agents — The Definitive Guide, Ch 10 (Memory,
37
- * Autonomy, Long-Horizon Use — chapter still unavailable in pre-pub).
38
- *
39
26
  * @see ./define.types.ts for the const-objects + types
40
27
  * @see ./pipeline/*.ts for the existing pipeline factories this dispatches to
41
- * @see MEMORY.md load-bearing design memory
42
28
  */
43
29
  import { type DefineMemoryOptions } from './define.types.js';
44
30
  import type { MemoryDefinition, ReadonlyMemoryFlowChart } from './define.types.js';
@@ -1 +1 @@
1
- {"version":3,"file":"define.d.ts","sourceRoot":"","sources":["../../../src/memory/define.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAaH,OAAO,EAIL,KAAK,mBAAmB,EAYzB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAInF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,gBAAgB,CAqB3E;AA6RD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,OAAO,EAAE,uBAAuB,CAAC,CAAC,CAAC,GAAG,OAAO,CAErF"}
1
+ {"version":3,"file":"define.d.ts","sourceRoot":"","sources":["../../../src/memory/define.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAaH,OAAO,EAIL,KAAK,mBAAmB,EAYzB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAInF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,gBAAgB,CAqB3E;AA6RD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,OAAO,EAAE,uBAAuB,CAAC,CAAC,CAAC,GAAG,OAAO,CAErF"}