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.
- package/AGENTS.md +80 -0
- package/CLAUDE.md +80 -0
- package/README.md +51 -1
- package/README.proposed.md +258 -0
- package/ai-instructions/claude-code/SKILL.md +56 -5
- package/ai-instructions/clinerules +44 -5
- package/ai-instructions/copilot-instructions.md +44 -5
- package/ai-instructions/cursor/agentfootprint.md +44 -5
- package/ai-instructions/kiro/agentfootprint.md +44 -5
- package/ai-instructions/windsurfrules +44 -5
- package/dist/adapters/llm/AnthropicProvider.js +0 -31
- package/dist/adapters/llm/AnthropicProvider.js.map +1 -1
- package/dist/adapters/llm/BedrockProvider.js +2 -28
- package/dist/adapters/llm/BedrockProvider.js.map +1 -1
- package/dist/adapters/llm/BrowserAnthropicProvider.js +1 -31
- package/dist/adapters/llm/BrowserAnthropicProvider.js.map +1 -1
- package/dist/adapters/llm/BrowserOpenAIProvider.js +1 -11
- package/dist/adapters/llm/BrowserOpenAIProvider.js.map +1 -1
- package/dist/adapters/llm/MockProvider.js +35 -1
- package/dist/adapters/llm/MockProvider.js.map +1 -1
- package/dist/adapters/llm/OpenAIProvider.js +3 -29
- package/dist/adapters/llm/OpenAIProvider.js.map +1 -1
- package/dist/adapters/memory/agentcore.js +305 -0
- package/dist/adapters/memory/agentcore.js.map +1 -0
- package/dist/adapters/memory/redis.js +287 -0
- package/dist/adapters/memory/redis.js.map +1 -0
- package/dist/core/Agent.js +11 -0
- package/dist/core/Agent.js.map +1 -1
- package/dist/esm/adapters/llm/AnthropicProvider.js +0 -31
- package/dist/esm/adapters/llm/AnthropicProvider.js.map +1 -1
- package/dist/esm/adapters/llm/BedrockProvider.js +2 -28
- package/dist/esm/adapters/llm/BedrockProvider.js.map +1 -1
- package/dist/esm/adapters/llm/BrowserAnthropicProvider.js +1 -31
- package/dist/esm/adapters/llm/BrowserAnthropicProvider.js.map +1 -1
- package/dist/esm/adapters/llm/BrowserOpenAIProvider.js +1 -11
- package/dist/esm/adapters/llm/BrowserOpenAIProvider.js.map +1 -1
- package/dist/esm/adapters/llm/MockProvider.js +35 -1
- package/dist/esm/adapters/llm/MockProvider.js.map +1 -1
- package/dist/esm/adapters/llm/OpenAIProvider.js +3 -29
- package/dist/esm/adapters/llm/OpenAIProvider.js.map +1 -1
- package/dist/esm/adapters/memory/agentcore.js +301 -0
- package/dist/esm/adapters/memory/agentcore.js.map +1 -0
- package/dist/esm/adapters/memory/redis.js +283 -0
- package/dist/esm/adapters/memory/redis.js.map +1 -0
- package/dist/esm/core/Agent.js +11 -0
- package/dist/esm/core/Agent.js.map +1 -1
- package/dist/esm/index.js +6 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/injection-engine/index.js +0 -54
- package/dist/esm/lib/injection-engine/index.js.map +1 -1
- package/dist/esm/lib/mcp/index.js +9 -0
- package/dist/esm/lib/mcp/index.js.map +1 -0
- package/dist/esm/lib/mcp/mcpClient.js +176 -0
- package/dist/esm/lib/mcp/mcpClient.js.map +1 -0
- package/dist/esm/lib/mcp/mockMcpClient.js +97 -0
- package/dist/esm/lib/mcp/mockMcpClient.js.map +1 -0
- package/dist/esm/lib/mcp/types.js +24 -0
- package/dist/esm/lib/mcp/types.js.map +1 -0
- package/dist/esm/lib/rag/defineRAG.js +0 -18
- package/dist/esm/lib/rag/defineRAG.js.map +1 -1
- package/dist/esm/lib/rag/indexDocuments.js +39 -4
- package/dist/esm/lib/rag/indexDocuments.js.map +1 -1
- package/dist/esm/memory/causal/loadSnapshot.js +1 -1
- package/dist/esm/memory/define.js +0 -14
- package/dist/esm/memory/define.js.map +1 -1
- package/dist/esm/memory/define.types.js +0 -10
- package/dist/esm/memory/define.types.js.map +1 -1
- package/dist/esm/resilience/index.js +0 -44
- package/dist/esm/resilience/index.js.map +1 -1
- package/dist/esm/stream.js +0 -29
- package/dist/esm/stream.js.map +1 -1
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -1
- package/dist/instructions.js +21 -0
- package/dist/instructions.js.map +1 -0
- package/dist/lib/injection-engine/index.js +0 -54
- package/dist/lib/injection-engine/index.js.map +1 -1
- package/dist/lib/instructions/defineInstruction.js +35 -0
- package/dist/lib/instructions/defineInstruction.js.map +1 -0
- package/dist/lib/instructions/evaluator.js +38 -0
- package/dist/lib/instructions/evaluator.js.map +1 -0
- package/dist/lib/instructions/index.js +48 -0
- package/dist/lib/instructions/index.js.map +1 -0
- package/dist/lib/instructions/types.js +22 -0
- package/dist/lib/instructions/types.js.map +1 -0
- package/dist/lib/mcp/index.js +14 -0
- package/dist/lib/mcp/index.js.map +1 -0
- package/dist/lib/mcp/mcpClient.js +180 -0
- package/dist/lib/mcp/mcpClient.js.map +1 -0
- package/dist/lib/mcp/mockMcpClient.js +101 -0
- package/dist/lib/mcp/mockMcpClient.js.map +1 -0
- package/dist/lib/mcp/types.js +25 -0
- package/dist/lib/mcp/types.js.map +1 -0
- package/dist/lib/rag/defineRAG.js +0 -18
- package/dist/lib/rag/defineRAG.js.map +1 -1
- package/dist/lib/rag/indexDocuments.js +39 -4
- package/dist/lib/rag/indexDocuments.js.map +1 -1
- package/dist/memory/causal/loadSnapshot.js +1 -1
- package/dist/memory/conversationHelpers.js +39 -0
- package/dist/memory/conversationHelpers.js.map +1 -0
- package/dist/memory/define.js +0 -14
- package/dist/memory/define.js.map +1 -1
- package/dist/memory/define.types.js +0 -10
- package/dist/memory/define.types.js.map +1 -1
- package/dist/resilience/index.js +0 -44
- package/dist/resilience/index.js.map +1 -1
- package/dist/stream.js +0 -29
- package/dist/stream.js.map +1 -1
- package/dist/types/adapters/llm/AnthropicProvider.d.ts +0 -31
- package/dist/types/adapters/llm/AnthropicProvider.d.ts.map +1 -1
- package/dist/types/adapters/llm/BedrockProvider.d.ts +2 -28
- package/dist/types/adapters/llm/BedrockProvider.d.ts.map +1 -1
- package/dist/types/adapters/llm/BrowserAnthropicProvider.d.ts +1 -31
- package/dist/types/adapters/llm/BrowserAnthropicProvider.d.ts.map +1 -1
- package/dist/types/adapters/llm/BrowserOpenAIProvider.d.ts +1 -11
- package/dist/types/adapters/llm/BrowserOpenAIProvider.d.ts.map +1 -1
- package/dist/types/adapters/llm/MockProvider.d.ts +45 -0
- package/dist/types/adapters/llm/MockProvider.d.ts.map +1 -1
- package/dist/types/adapters/llm/OpenAIProvider.d.ts +3 -29
- package/dist/types/adapters/llm/OpenAIProvider.d.ts.map +1 -1
- package/dist/types/adapters/memory/agentcore.d.ts +157 -0
- package/dist/types/adapters/memory/agentcore.d.ts.map +1 -0
- package/dist/types/adapters/memory/redis.d.ts +126 -0
- package/dist/types/adapters/memory/redis.d.ts.map +1 -0
- package/dist/types/core/Agent.d.ts +7 -0
- package/dist/types/core/Agent.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/instructions.d.ts +5 -0
- package/dist/types/instructions.d.ts.map +1 -0
- package/dist/types/lib/injection-engine/index.d.ts +0 -54
- package/dist/types/lib/injection-engine/index.d.ts.map +1 -1
- package/dist/types/lib/instructions/defineInstruction.d.ts +22 -0
- package/dist/types/lib/instructions/defineInstruction.d.ts.map +1 -0
- package/dist/types/lib/instructions/evaluator.d.ts +11 -0
- package/dist/types/lib/instructions/evaluator.d.ts.map +1 -0
- package/dist/types/lib/instructions/index.d.ts +44 -0
- package/dist/types/lib/instructions/index.d.ts.map +1 -0
- package/dist/types/lib/instructions/types.d.ts +100 -0
- package/dist/types/lib/instructions/types.d.ts.map +1 -0
- package/dist/types/lib/mcp/index.d.ts +10 -0
- package/dist/types/lib/mcp/index.d.ts.map +1 -0
- package/dist/types/lib/mcp/mcpClient.d.ts +47 -0
- package/dist/types/lib/mcp/mcpClient.d.ts.map +1 -0
- package/dist/types/lib/mcp/mockMcpClient.d.ts +66 -0
- package/dist/types/lib/mcp/mockMcpClient.d.ts.map +1 -0
- package/dist/types/lib/mcp/types.d.ts +134 -0
- package/dist/types/lib/mcp/types.d.ts.map +1 -0
- package/dist/types/lib/rag/defineRAG.d.ts +18 -21
- package/dist/types/lib/rag/defineRAG.d.ts.map +1 -1
- package/dist/types/lib/rag/indexDocuments.d.ts +30 -1
- package/dist/types/lib/rag/indexDocuments.d.ts.map +1 -1
- package/dist/types/memory/causal/loadSnapshot.d.ts +1 -1
- package/dist/types/memory/conversationHelpers.d.ts +19 -0
- package/dist/types/memory/conversationHelpers.d.ts.map +1 -0
- package/dist/types/memory/define.d.ts +0 -14
- package/dist/types/memory/define.d.ts.map +1 -1
- package/dist/types/memory/define.types.d.ts +2 -12
- package/dist/types/memory/define.types.d.ts.map +1 -1
- package/dist/types/resilience/index.d.ts +0 -44
- package/dist/types/resilience/index.d.ts.map +1 -1
- package/dist/types/stream.d.ts +0 -29
- package/dist/types/stream.d.ts.map +1 -1
- 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":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAIhD;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,iEAAiE;IACjE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,yCAAyC;IACzC,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,+CAA+C;IAC/C,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAChD,4CAA4C;IAC5C,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,+BAA+B;IAC/B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,iEAAiE;IACjE,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACrD;AAED,MAAM,MAAM,YAAY,GAAG,iBAAiB,GAAG,gBAAgB,CAAC;AAIhE,MAAM,WAAW,gBAAgB;IAC/B;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAEvB,+CAA+C;IAC/C,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;IAEjC;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAE1E,oEAAoE;IACpE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAE9B;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC;CACjC;AAID;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,sDAAsD;IACtD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;;;;OAKG;IACH,KAAK,IAAI,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;IAElC;;;;OAIG;IACH,OAAO,IAAI,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;IAEpC,8EAA8E;IAC9E,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAID;;;;;;;;GAQG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,SAAS,IAAI,OAAO,CAAC;QACnB,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;YAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;YACtB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;YAC9B,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;SACzD,CAAC,CAAC;KACJ,CAAC,CAAC;IACH,QAAQ,CAAC,IAAI,EAAE;QACb,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;QACvD,wFAAwF;QACxF,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;KAC/B,GAAG,OAAO,CAAC;QACV,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;YAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;YACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;SACxB,CAAC,CAAC;QACH,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;KAC5B,CAAC,CAAC;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB"}
|
|
@@ -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'
|
|
127
|
-
*
|
|
128
|
-
*
|
|
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
|
|
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.
|
|
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
|
|
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.
|
|
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
|
|
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"}
|