agentfootprint 2.0.1 → 2.1.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 +33 -0
- package/CLAUDE.md +33 -0
- package/README.md +1 -1
- package/ai-instructions/claude-code/SKILL.md +29 -0
- package/ai-instructions/clinerules +19 -0
- package/ai-instructions/copilot-instructions.md +19 -0
- package/ai-instructions/cursor/agentfootprint.md +19 -0
- package/ai-instructions/kiro/agentfootprint.md +19 -0
- package/ai-instructions/windsurfrules +19 -0
- package/dist/core/Agent.js +20 -0
- package/dist/core/Agent.js.map +1 -1
- package/dist/esm/core/Agent.js +20 -0
- package/dist/esm/core/Agent.js.map +1 -1
- package/dist/esm/index.js +4 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/rag/defineRAG.js +118 -0
- package/dist/esm/lib/rag/defineRAG.js.map +1 -0
- package/dist/esm/lib/rag/index.js +8 -0
- package/dist/esm/lib/rag/index.js.map +1 -0
- package/dist/esm/lib/rag/indexDocuments.js +73 -0
- package/dist/esm/lib/rag/indexDocuments.js.map +1 -0
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/rag/defineRAG.js +122 -0
- package/dist/lib/rag/defineRAG.js.map +1 -0
- package/dist/lib/rag/index.js +13 -0
- package/dist/lib/rag/index.js.map +1 -0
- package/dist/lib/rag/indexDocuments.js +77 -0
- package/dist/lib/rag/indexDocuments.js.map +1 -0
- package/dist/types/core/Agent.d.ts +18 -0
- package/dist/types/core/Agent.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/lib/rag/defineRAG.d.ts +141 -0
- package/dist/types/lib/rag/defineRAG.d.ts.map +1 -0
- package/dist/types/lib/rag/index.d.ts +8 -0
- package/dist/types/lib/rag/index.d.ts.map +1 -0
- package/dist/types/lib/rag/indexDocuments.d.ts +77 -0
- package/dist/types/lib/rag/indexDocuments.d.ts.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* defineRAG — sugar factory for retrieval-augmented generation.
|
|
3
|
+
*
|
|
4
|
+
* RAG is a context-engineering flavor: embed the user's question,
|
|
5
|
+
* retrieve top-K semantically similar chunks from a vector store,
|
|
6
|
+
* inject those chunks into the messages slot of the next LLM call.
|
|
7
|
+
* It's the same plumbing as `defineMemory({ type: SEMANTIC,
|
|
8
|
+
* strategy: TOP_K })` — the rename is for intent + ergonomics.
|
|
9
|
+
*
|
|
10
|
+
* defineMemory ─┬─► EPISODIC (raw conversation)
|
|
11
|
+
* ├─► SEMANTIC (extracted facts / RAG chunks)
|
|
12
|
+
* ├─► NARRATIVE (beats / summaries)
|
|
13
|
+
* └─► CAUSAL (footprintjs decision snapshots)
|
|
14
|
+
*
|
|
15
|
+
* defineRAG ─► SEMANTIC + TOP_K with RAG-specific defaults
|
|
16
|
+
* (asRole='user', threshold=0.7, no LLM-extract)
|
|
17
|
+
*
|
|
18
|
+
* Pattern: Composition over duplication — defineRAG returns a
|
|
19
|
+
* MemoryDefinition produced by defineMemory. No new engine
|
|
20
|
+
* code, no new slot subflow, no new event type.
|
|
21
|
+
*
|
|
22
|
+
* Role: Layer-3 context-engineering primitive. Lives next to
|
|
23
|
+
* defineSkill / defineSteering / defineInstruction / defineFact
|
|
24
|
+
* but resolves to a memory subflow rather than an Injection
|
|
25
|
+
* (RAG content is computed at runtime via async retrieval —
|
|
26
|
+
* can't fit the synchronous Injection.inject shape).
|
|
27
|
+
*
|
|
28
|
+
* Emits: Indirectly — the underlying memory pipeline emits
|
|
29
|
+
* `agentfootprint.context.injected` when retrieved chunks
|
|
30
|
+
* land in the messages slot.
|
|
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
|
+
* @see ./indexDocuments.ts for the seeding helper
|
|
51
|
+
* @see ../../memory/define.ts for the underlying factory
|
|
52
|
+
*
|
|
53
|
+
* @example Basic usage
|
|
54
|
+
* ```ts
|
|
55
|
+
* import {
|
|
56
|
+
* Agent, defineRAG, indexDocuments, InMemoryStore, mockEmbedder,
|
|
57
|
+
* } from 'agentfootprint';
|
|
58
|
+
*
|
|
59
|
+
* const embedder = mockEmbedder();
|
|
60
|
+
* const store = new InMemoryStore();
|
|
61
|
+
*
|
|
62
|
+
* // Seed the store once at startup
|
|
63
|
+
* await indexDocuments(store, embedder, [
|
|
64
|
+
* { id: 'doc1', content: 'Refunds are processed within 3 business days.' },
|
|
65
|
+
* { id: 'doc2', content: 'Pro plan costs $20/month.' },
|
|
66
|
+
* ]);
|
|
67
|
+
*
|
|
68
|
+
* const docs = defineRAG({
|
|
69
|
+
* id: 'product-docs',
|
|
70
|
+
* description: 'Retrieve product documentation chunks',
|
|
71
|
+
* store,
|
|
72
|
+
* embedder,
|
|
73
|
+
* topK: 3,
|
|
74
|
+
* threshold: 0.6,
|
|
75
|
+
* });
|
|
76
|
+
*
|
|
77
|
+
* const agent = Agent.create({ provider }).rag(docs).build();
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
import type { ContextRole } from '../../events/types.js';
|
|
81
|
+
import type { Embedder } from '../../memory/embedding/index.js';
|
|
82
|
+
import type { MemoryStore } from '../../memory/store/index.js';
|
|
83
|
+
import type { MemoryDefinition } from '../../memory/define.types.js';
|
|
84
|
+
export interface DefineRAGOptions {
|
|
85
|
+
/** Stable id. Becomes the scope-key suffix and the Lens label. */
|
|
86
|
+
readonly id: string;
|
|
87
|
+
/**
|
|
88
|
+
* Human-readable description. Surfaces in narrative + Lens hover.
|
|
89
|
+
* Recommend describing the *corpus* (e.g., "Product documentation
|
|
90
|
+
* chunks indexed weekly from docs.example.com").
|
|
91
|
+
*/
|
|
92
|
+
readonly description?: string;
|
|
93
|
+
/**
|
|
94
|
+
* Vector-capable store containing the indexed corpus. Must implement
|
|
95
|
+
* `search()`. Use `indexDocuments(store, embedder, docs)` at startup
|
|
96
|
+
* to populate it. Ships with `InMemoryStore` for dev/tests; swap to
|
|
97
|
+
* `pgvector` / Pinecone / Qdrant adapters in production.
|
|
98
|
+
*/
|
|
99
|
+
readonly store: MemoryStore;
|
|
100
|
+
/**
|
|
101
|
+
* Embedder used for the read-side query. Pass the SAME embedder
|
|
102
|
+
* instance (or one with the same `name`) that was used for indexing
|
|
103
|
+
* — cross-model similarity scores are not comparable.
|
|
104
|
+
*/
|
|
105
|
+
readonly embedder: Embedder;
|
|
106
|
+
/**
|
|
107
|
+
* Stable id of the embedder. Stored on entries during indexing
|
|
108
|
+
* (via `indexDocuments`) and filtered at search time so a later
|
|
109
|
+
* embedder swap doesn't pollute results.
|
|
110
|
+
*/
|
|
111
|
+
readonly embedderId?: string;
|
|
112
|
+
/**
|
|
113
|
+
* Top-K chunks to retrieve per turn. Default 3 (balanced —
|
|
114
|
+
* defends against lost-in-the-middle while giving multiple
|
|
115
|
+
* perspectives). Increase for richer context, decrease for cost.
|
|
116
|
+
*/
|
|
117
|
+
readonly topK?: number;
|
|
118
|
+
/**
|
|
119
|
+
* Minimum cosine similarity to inject. **Strict** — when no chunk
|
|
120
|
+
* meets the threshold, NO injection happens (no fallback that would
|
|
121
|
+
* pollute the prompt with weak matches). Default 0.7.
|
|
122
|
+
*/
|
|
123
|
+
readonly threshold?: number;
|
|
124
|
+
/**
|
|
125
|
+
* 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.
|
|
129
|
+
*/
|
|
130
|
+
readonly asRole?: ContextRole;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Build a RAG context-engineering definition. The returned
|
|
134
|
+
* `MemoryDefinition` is registered on the Agent via `.rag(definition)`
|
|
135
|
+
* (or, equivalently, `.memory(definition)` — same plumbing).
|
|
136
|
+
*
|
|
137
|
+
* @throws when `store` does not implement `search()`. RAG requires a
|
|
138
|
+
* vector-capable adapter.
|
|
139
|
+
*/
|
|
140
|
+
export declare function defineRAG(opts: DefineRAGOptions): MemoryDefinition;
|
|
141
|
+
//# sourceMappingURL=defineRAG.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RAG — retrieval-augmented generation as a context-engineering
|
|
3
|
+
* flavor. ONE factory + ONE seeding helper. Composes over the memory
|
|
4
|
+
* subsystem (semantic + top-K + strict threshold).
|
|
5
|
+
*/
|
|
6
|
+
export { defineRAG, type DefineRAGOptions } from './defineRAG.js';
|
|
7
|
+
export { indexDocuments, type IndexDocumentsOptions, type RagDocument } from './indexDocuments.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/rag/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* indexDocuments — seed a vector-capable MemoryStore with documents.
|
|
3
|
+
*
|
|
4
|
+
* Embeds each document, builds a `MemoryEntry<{content, metadata?}>`,
|
|
5
|
+
* batches into `store.putMany()`. Used at application startup to
|
|
6
|
+
* populate a RAG store before the first agent run.
|
|
7
|
+
*
|
|
8
|
+
* Pattern: Bulk-write helper. Not a flowchart stage — it runs once
|
|
9
|
+
* at boot, not per-iteration.
|
|
10
|
+
* Role: Layer-3 RAG pipeline starter. Pairs with `defineRAG()`
|
|
11
|
+
* which only does the read side.
|
|
12
|
+
* Emits: N/A — startup-time batch write, not part of the agent run.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { InMemoryStore, mockEmbedder, indexDocuments, defineRAG } from 'agentfootprint';
|
|
17
|
+
*
|
|
18
|
+
* const store = new InMemoryStore();
|
|
19
|
+
* const embedder = mockEmbedder();
|
|
20
|
+
*
|
|
21
|
+
* await indexDocuments(store, embedder, [
|
|
22
|
+
* { id: 'doc1', content: 'Refunds processed within 3 business days.' },
|
|
23
|
+
* { id: 'doc2', content: 'Pro plan: $20/mo, includes priority support.', metadata: { tier: 'pro' } },
|
|
24
|
+
* { id: 'doc3', content: 'Free plan: limited to 100 calls/month.' },
|
|
25
|
+
* ]);
|
|
26
|
+
*
|
|
27
|
+
* const docs = defineRAG({ id: 'product-docs', store, embedder });
|
|
28
|
+
* agent.rag(docs);
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
import type { Embedder } from '../../memory/embedding/index.js';
|
|
32
|
+
import type { MemoryStore } from '../../memory/store/index.js';
|
|
33
|
+
import type { MemoryIdentity } from '../../memory/identity/index.js';
|
|
34
|
+
/** A document to index. `id` must be unique within the store + identity. */
|
|
35
|
+
export interface RagDocument {
|
|
36
|
+
readonly id: string;
|
|
37
|
+
readonly content: string;
|
|
38
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
39
|
+
}
|
|
40
|
+
export interface IndexDocumentsOptions {
|
|
41
|
+
/**
|
|
42
|
+
* Identity scope to write under. Default: a single shared
|
|
43
|
+
* `{ conversationId: '_global' }` namespace, suitable for app-wide
|
|
44
|
+
* corpora. Override for per-tenant document partitions.
|
|
45
|
+
*/
|
|
46
|
+
readonly identity?: MemoryIdentity;
|
|
47
|
+
/**
|
|
48
|
+
* Stable id of the embedder. Stored on each entry so a future
|
|
49
|
+
* embedder swap doesn't silently mix similarity scores. Default:
|
|
50
|
+
* `'default-embedder'` — pass an explicit id when you may rotate
|
|
51
|
+
* embedders.
|
|
52
|
+
*/
|
|
53
|
+
readonly embedderId?: string;
|
|
54
|
+
/**
|
|
55
|
+
* Optional tier tag to attach to indexed entries (`'hot'` /
|
|
56
|
+
* `'warm'` / `'cold'`). Useful when read-side `defineRAG` should
|
|
57
|
+
* filter to a subset of the corpus.
|
|
58
|
+
*/
|
|
59
|
+
readonly tier?: 'hot' | 'warm' | 'cold';
|
|
60
|
+
/**
|
|
61
|
+
* Optional TTL in milliseconds from indexing time. Useful for
|
|
62
|
+
* compliance retention windows (e.g., re-index quarterly).
|
|
63
|
+
*/
|
|
64
|
+
readonly ttlMs?: number;
|
|
65
|
+
/**
|
|
66
|
+
* Optional abort signal — embedders making network calls thread
|
|
67
|
+
* this through to abort batch indexing on shutdown / timeout.
|
|
68
|
+
*/
|
|
69
|
+
readonly signal?: AbortSignal;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Embed + persist documents. Returns the count actually indexed
|
|
73
|
+
* (skips duplicates if the store rejects them). Throws on embedder
|
|
74
|
+
* failure or store error — fail loud at startup is desirable.
|
|
75
|
+
*/
|
|
76
|
+
export declare function indexDocuments(store: MemoryStore, embedder: Embedder, documents: readonly RagDocument[], options?: IndexDocumentsOptions): Promise<number>;
|
|
77
|
+
//# sourceMappingURL=indexDocuments.d.ts.map
|
|
@@ -0,0 +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"}
|
package/package.json
CHANGED