agentic-memory 0.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/LICENSE +21 -0
- package/README.md +446 -0
- package/dist/adapters/openai.d.mts +33 -0
- package/dist/adapters/openai.d.ts +33 -0
- package/dist/adapters/openai.js +85 -0
- package/dist/adapters/openai.mjs +60 -0
- package/dist/adapters/voyageai.d.mts +30 -0
- package/dist/adapters/voyageai.d.ts +30 -0
- package/dist/adapters/voyageai.js +64 -0
- package/dist/adapters/voyageai.mjs +39 -0
- package/dist/index.d.mts +246 -0
- package/dist/index.d.ts +246 -0
- package/dist/index.js +724 -0
- package/dist/index.mjs +689 -0
- package/dist/types-CQ8Hcoqw.d.mts +131 -0
- package/dist/types-CQ8Hcoqw.d.ts +131 -0
- package/package.json +76 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { E as Embedder } from '../types-CQ8Hcoqw.mjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Voyage AI embedder adapter (high-quality, cheaper than OpenAI).
|
|
5
|
+
* Requires: VOYAGE_API_KEY
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* import { AgentMemory } from 'agentic-memory';
|
|
9
|
+
* import { VoyageEmbedder } from 'agentic-memory/adapters/voyageai';
|
|
10
|
+
*
|
|
11
|
+
* const memory = new AgentMemory({
|
|
12
|
+
* embedder: new VoyageEmbedder({ apiKey: process.env.VOYAGE_API_KEY }),
|
|
13
|
+
* });
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
interface VoyageEmbedderConfig {
|
|
17
|
+
apiKey: string;
|
|
18
|
+
model?: string;
|
|
19
|
+
}
|
|
20
|
+
declare class VoyageEmbedder implements Embedder {
|
|
21
|
+
private apiKey;
|
|
22
|
+
private model;
|
|
23
|
+
constructor(config: VoyageEmbedderConfig);
|
|
24
|
+
dimensions(): number;
|
|
25
|
+
embed(text: string): Promise<number[]>;
|
|
26
|
+
embedBatch(texts: string[]): Promise<number[][]>;
|
|
27
|
+
private _call;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export { VoyageEmbedder, type VoyageEmbedderConfig };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { E as Embedder } from '../types-CQ8Hcoqw.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Voyage AI embedder adapter (high-quality, cheaper than OpenAI).
|
|
5
|
+
* Requires: VOYAGE_API_KEY
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* import { AgentMemory } from 'agentic-memory';
|
|
9
|
+
* import { VoyageEmbedder } from 'agentic-memory/adapters/voyageai';
|
|
10
|
+
*
|
|
11
|
+
* const memory = new AgentMemory({
|
|
12
|
+
* embedder: new VoyageEmbedder({ apiKey: process.env.VOYAGE_API_KEY }),
|
|
13
|
+
* });
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
interface VoyageEmbedderConfig {
|
|
17
|
+
apiKey: string;
|
|
18
|
+
model?: string;
|
|
19
|
+
}
|
|
20
|
+
declare class VoyageEmbedder implements Embedder {
|
|
21
|
+
private apiKey;
|
|
22
|
+
private model;
|
|
23
|
+
constructor(config: VoyageEmbedderConfig);
|
|
24
|
+
dimensions(): number;
|
|
25
|
+
embed(text: string): Promise<number[]>;
|
|
26
|
+
embedBatch(texts: string[]): Promise<number[][]>;
|
|
27
|
+
private _call;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export { VoyageEmbedder, type VoyageEmbedderConfig };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/adapters/voyageai.ts
|
|
21
|
+
var voyageai_exports = {};
|
|
22
|
+
__export(voyageai_exports, {
|
|
23
|
+
VoyageEmbedder: () => VoyageEmbedder
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(voyageai_exports);
|
|
26
|
+
var VoyageEmbedder = class {
|
|
27
|
+
apiKey;
|
|
28
|
+
model;
|
|
29
|
+
constructor(config) {
|
|
30
|
+
this.apiKey = config.apiKey;
|
|
31
|
+
this.model = config.model ?? "voyage-3-lite";
|
|
32
|
+
}
|
|
33
|
+
dimensions() {
|
|
34
|
+
return this.model.includes("lite") ? 512 : 1024;
|
|
35
|
+
}
|
|
36
|
+
async embed(text) {
|
|
37
|
+
const result = await this._call([text]);
|
|
38
|
+
return result[0];
|
|
39
|
+
}
|
|
40
|
+
async embedBatch(texts) {
|
|
41
|
+
if (texts.length === 0) return [];
|
|
42
|
+
return this._call(texts);
|
|
43
|
+
}
|
|
44
|
+
async _call(input) {
|
|
45
|
+
const res = await fetch("https://api.voyageai.com/v1/embeddings", {
|
|
46
|
+
method: "POST",
|
|
47
|
+
headers: {
|
|
48
|
+
"Content-Type": "application/json",
|
|
49
|
+
"Authorization": `Bearer ${this.apiKey}`
|
|
50
|
+
},
|
|
51
|
+
body: JSON.stringify({ model: this.model, input })
|
|
52
|
+
});
|
|
53
|
+
if (!res.ok) {
|
|
54
|
+
const err = await res.text();
|
|
55
|
+
throw new Error(`Voyage AI embedding failed (${res.status}): ${err}`);
|
|
56
|
+
}
|
|
57
|
+
const data = await res.json();
|
|
58
|
+
return data.data.map((d) => d.embedding);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
62
|
+
0 && (module.exports = {
|
|
63
|
+
VoyageEmbedder
|
|
64
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// src/adapters/voyageai.ts
|
|
2
|
+
var VoyageEmbedder = class {
|
|
3
|
+
apiKey;
|
|
4
|
+
model;
|
|
5
|
+
constructor(config) {
|
|
6
|
+
this.apiKey = config.apiKey;
|
|
7
|
+
this.model = config.model ?? "voyage-3-lite";
|
|
8
|
+
}
|
|
9
|
+
dimensions() {
|
|
10
|
+
return this.model.includes("lite") ? 512 : 1024;
|
|
11
|
+
}
|
|
12
|
+
async embed(text) {
|
|
13
|
+
const result = await this._call([text]);
|
|
14
|
+
return result[0];
|
|
15
|
+
}
|
|
16
|
+
async embedBatch(texts) {
|
|
17
|
+
if (texts.length === 0) return [];
|
|
18
|
+
return this._call(texts);
|
|
19
|
+
}
|
|
20
|
+
async _call(input) {
|
|
21
|
+
const res = await fetch("https://api.voyageai.com/v1/embeddings", {
|
|
22
|
+
method: "POST",
|
|
23
|
+
headers: {
|
|
24
|
+
"Content-Type": "application/json",
|
|
25
|
+
"Authorization": `Bearer ${this.apiKey}`
|
|
26
|
+
},
|
|
27
|
+
body: JSON.stringify({ model: this.model, input })
|
|
28
|
+
});
|
|
29
|
+
if (!res.ok) {
|
|
30
|
+
const err = await res.text();
|
|
31
|
+
throw new Error(`Voyage AI embedding failed (${res.status}): ${err}`);
|
|
32
|
+
}
|
|
33
|
+
const data = await res.json();
|
|
34
|
+
return data.data.map((d) => d.embedding);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
export {
|
|
38
|
+
VoyageEmbedder
|
|
39
|
+
};
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { A as AgentMemoryConfig, M as MemoryType, I as ImportanceLevel, a as MemoryEntry, R as RetrievalQuery, b as RetrievalResult, C as ConflictResult, T as TaskNode, c as Checkpoint, D as DecayConfig, S as StorageBackend, E as Embedder, d as RetrievalSignal } from './types-CQ8Hcoqw.mjs';
|
|
2
|
+
export { e as DecayPolicy } from './types-CQ8Hcoqw.mjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* AgentMemory - the main entry point.
|
|
6
|
+
*
|
|
7
|
+
* Framework-agnostic memory layer for AI agents.
|
|
8
|
+
* Handles storage, multi-signal retrieval, conflict detection,
|
|
9
|
+
* typed decay, and checkpointing.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const memory = new AgentMemory();
|
|
14
|
+
*
|
|
15
|
+
* await memory.store({
|
|
16
|
+
* content: 'User prefers dark mode',
|
|
17
|
+
* type: 'preference',
|
|
18
|
+
* scope: 'user:123',
|
|
19
|
+
* });
|
|
20
|
+
*
|
|
21
|
+
* const results = await memory.retrieve({ query: 'UI preferences' });
|
|
22
|
+
* const conflicts = await memory.checkConflicts('User prefers light mode', 'user:123');
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
declare class AgentMemory {
|
|
26
|
+
private backend;
|
|
27
|
+
private embedder;
|
|
28
|
+
private retriever;
|
|
29
|
+
private conflictDetector;
|
|
30
|
+
private decayEngine;
|
|
31
|
+
private checkpoints;
|
|
32
|
+
private defaultScope;
|
|
33
|
+
private maxCheckpoints;
|
|
34
|
+
constructor(config?: AgentMemoryConfig);
|
|
35
|
+
/**
|
|
36
|
+
* Store a new memory entry.
|
|
37
|
+
* Automatically generates ID, timestamps, and embedding.
|
|
38
|
+
*/
|
|
39
|
+
store(params: {
|
|
40
|
+
content: string;
|
|
41
|
+
type?: MemoryType;
|
|
42
|
+
scope?: string;
|
|
43
|
+
importance?: ImportanceLevel;
|
|
44
|
+
confidence?: number;
|
|
45
|
+
metadata?: Record<string, unknown>;
|
|
46
|
+
}): Promise<MemoryEntry>;
|
|
47
|
+
/**
|
|
48
|
+
* Update an existing memory entry.
|
|
49
|
+
* Increments version and updates timestamp.
|
|
50
|
+
*/
|
|
51
|
+
update(id: string, updates: Partial<Pick<MemoryEntry, 'content' | 'type' | 'importance' | 'confidence' | 'metadata'>>): Promise<MemoryEntry | null>;
|
|
52
|
+
/** Get a memory by ID */
|
|
53
|
+
get(id: string): Promise<MemoryEntry | null>;
|
|
54
|
+
/** Delete a memory by ID */
|
|
55
|
+
delete(id: string): Promise<boolean>;
|
|
56
|
+
/** Get all memories, optionally filtered by scope */
|
|
57
|
+
getAll(scope?: string): Promise<MemoryEntry[]>;
|
|
58
|
+
/** Clear all memories, optionally for a specific scope only */
|
|
59
|
+
clear(scope?: string): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Multi-signal retrieval.
|
|
62
|
+
* Combines similarity, recency, importance, and task-relevance.
|
|
63
|
+
*/
|
|
64
|
+
retrieve(query: RetrievalQuery): Promise<RetrievalResult[]>;
|
|
65
|
+
/**
|
|
66
|
+
* Check if content conflicts with stored memories.
|
|
67
|
+
* Returns conflicts sorted by confidence.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```typescript
|
|
71
|
+
* const conflicts = await memory.checkConflicts('User likes meat', 'user:123');
|
|
72
|
+
* if (conflicts.length > 0 && conflicts[0].action === 'clarify') {
|
|
73
|
+
* // Ask user to confirm preference change
|
|
74
|
+
* }
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
checkConflicts(content: string, scope?: string): Promise<ConflictResult[]>;
|
|
78
|
+
/**
|
|
79
|
+
* Get the current effective confidence of a memory after decay.
|
|
80
|
+
*/
|
|
81
|
+
getDecayedConfidence(entry: MemoryEntry): number;
|
|
82
|
+
/**
|
|
83
|
+
* Clean up expired memories (decayed below threshold).
|
|
84
|
+
* Returns the number of deleted entries.
|
|
85
|
+
*/
|
|
86
|
+
cleanup(scope?: string, threshold?: number): Promise<number>;
|
|
87
|
+
/**
|
|
88
|
+
* Create a checkpoint of current task state.
|
|
89
|
+
* Use this before context overflow to preserve state.
|
|
90
|
+
*/
|
|
91
|
+
checkpoint(params: {
|
|
92
|
+
taskGraph: TaskNode[];
|
|
93
|
+
summary: string;
|
|
94
|
+
toolOutputs?: Record<string, unknown>;
|
|
95
|
+
activeMemoryIds?: string[];
|
|
96
|
+
}): Promise<Checkpoint>;
|
|
97
|
+
/**
|
|
98
|
+
* Rehydrate from a checkpoint.
|
|
99
|
+
* Returns the checkpoint data + relevant memories.
|
|
100
|
+
*/
|
|
101
|
+
rehydrate(checkpointId: string): Promise<{
|
|
102
|
+
checkpoint: Checkpoint;
|
|
103
|
+
memories: MemoryEntry[];
|
|
104
|
+
} | null>;
|
|
105
|
+
/** Get the latest checkpoint */
|
|
106
|
+
getLatestCheckpoint(): Checkpoint | null;
|
|
107
|
+
/** List all checkpoints */
|
|
108
|
+
listCheckpoints(): Checkpoint[];
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Typed decay engine.
|
|
113
|
+
* Different memory types decay at different rates.
|
|
114
|
+
* Hard constraints (allergies, legal requirements) never decay.
|
|
115
|
+
* Ephemeral task state decays fast.
|
|
116
|
+
*/
|
|
117
|
+
declare class DecayEngine {
|
|
118
|
+
private config;
|
|
119
|
+
constructor(config?: Partial<DecayConfig>);
|
|
120
|
+
/**
|
|
121
|
+
* Compute the current effective confidence of a memory entry
|
|
122
|
+
* after applying temporal decay.
|
|
123
|
+
* Returns a value between 0 and original confidence.
|
|
124
|
+
*/
|
|
125
|
+
computeDecayedConfidence(entry: MemoryEntry): number;
|
|
126
|
+
/**
|
|
127
|
+
* Filter out memories that have decayed below a threshold.
|
|
128
|
+
* Useful for periodic cleanup.
|
|
129
|
+
*/
|
|
130
|
+
filterDecayed(entries: MemoryEntry[], threshold?: number): MemoryEntry[];
|
|
131
|
+
/**
|
|
132
|
+
* Get entries that should be cleaned up (decayed to near-zero).
|
|
133
|
+
*/
|
|
134
|
+
getExpired(entries: MemoryEntry[], threshold?: number): MemoryEntry[];
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* In-memory storage backend. Zero dependencies.
|
|
139
|
+
* Perfect for development, testing, and single-process agents.
|
|
140
|
+
* Data is lost when the process exits.
|
|
141
|
+
*/
|
|
142
|
+
declare class LocalStore implements StorageBackend {
|
|
143
|
+
private entries;
|
|
144
|
+
get(id: string): Promise<MemoryEntry | null>;
|
|
145
|
+
getAll(scope?: string): Promise<MemoryEntry[]>;
|
|
146
|
+
set(entry: MemoryEntry): Promise<void>;
|
|
147
|
+
delete(id: string): Promise<boolean>;
|
|
148
|
+
clear(scope?: string): Promise<void>;
|
|
149
|
+
search(query: RetrievalQuery): Promise<MemoryEntry[]>;
|
|
150
|
+
/** Get the number of stored entries */
|
|
151
|
+
get size(): number;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* File-based storage backend. Persists to a JSON file on disk.
|
|
156
|
+
* Good for single-process agents that need persistence across restarts.
|
|
157
|
+
* Not suitable for concurrent multi-agent access - use Redis/Postgres for that.
|
|
158
|
+
*/
|
|
159
|
+
declare class FileStore implements StorageBackend {
|
|
160
|
+
private entries;
|
|
161
|
+
private filePath;
|
|
162
|
+
private dirty;
|
|
163
|
+
constructor(filePath: string);
|
|
164
|
+
private load;
|
|
165
|
+
private persist;
|
|
166
|
+
get(id: string): Promise<MemoryEntry | null>;
|
|
167
|
+
getAll(scope?: string): Promise<MemoryEntry[]>;
|
|
168
|
+
set(entry: MemoryEntry): Promise<void>;
|
|
169
|
+
delete(id: string): Promise<boolean>;
|
|
170
|
+
clear(scope?: string): Promise<void>;
|
|
171
|
+
search(query: RetrievalQuery): Promise<MemoryEntry[]>;
|
|
172
|
+
get size(): number;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Multi-signal retriever.
|
|
177
|
+
* Combines similarity, recency, importance, and task-relevance
|
|
178
|
+
* into a single ranked result set.
|
|
179
|
+
*/
|
|
180
|
+
declare class MultiSignalRetriever {
|
|
181
|
+
private store;
|
|
182
|
+
private embedder;
|
|
183
|
+
private weights;
|
|
184
|
+
constructor(store: StorageBackend, embedder: Embedder, weights?: Partial<Record<RetrievalSignal, number>>);
|
|
185
|
+
retrieve(query: RetrievalQuery): Promise<RetrievalResult[]>;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Conflict detector.
|
|
190
|
+
* Compares new content against stored memories to find contradictions.
|
|
191
|
+
* Uses semantic similarity + negation detection, not just keyword matching.
|
|
192
|
+
*/
|
|
193
|
+
declare class ConflictDetector {
|
|
194
|
+
private store;
|
|
195
|
+
private embedder;
|
|
196
|
+
/** Similarity threshold to consider two entries as "same topic" */
|
|
197
|
+
private topicThreshold;
|
|
198
|
+
constructor(store: StorageBackend, embedder: Embedder, topicThreshold?: number);
|
|
199
|
+
/**
|
|
200
|
+
* Check if new content conflicts with any stored memories.
|
|
201
|
+
* Returns conflicts sorted by confidence (highest first).
|
|
202
|
+
*/
|
|
203
|
+
check(content: string, scope?: string): Promise<ConflictResult[]>;
|
|
204
|
+
/**
|
|
205
|
+
* Score how contradictory two pieces of text are.
|
|
206
|
+
* Returns 0 (no contradiction) to 1 (strong contradiction).
|
|
207
|
+
*/
|
|
208
|
+
private scoreContradiction;
|
|
209
|
+
/** Check for common antonym pairs */
|
|
210
|
+
private checkAntonyms;
|
|
211
|
+
private suggestAction;
|
|
212
|
+
private generateReason;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Built-in lightweight embedder using bag-of-words TF-IDF.
|
|
217
|
+
* No external dependencies, no API calls.
|
|
218
|
+
* Good enough for conflict detection and basic similarity.
|
|
219
|
+
* For production, plug in OpenAI/Cohere/local embeddings.
|
|
220
|
+
*/
|
|
221
|
+
declare class BuiltinEmbedder implements Embedder {
|
|
222
|
+
private readonly dim;
|
|
223
|
+
private vocabulary;
|
|
224
|
+
private idfCache;
|
|
225
|
+
private documentCount;
|
|
226
|
+
private documentFreq;
|
|
227
|
+
constructor(dimensions?: number);
|
|
228
|
+
dimensions(): number;
|
|
229
|
+
embed(text: string): Promise<number[]>;
|
|
230
|
+
embedBatch(texts: string[]): Promise<number[][]>;
|
|
231
|
+
/**
|
|
232
|
+
* Feed documents to build vocabulary and IDF stats.
|
|
233
|
+
* Call this when adding memories to improve embedding quality.
|
|
234
|
+
*/
|
|
235
|
+
train(documents: string[]): void;
|
|
236
|
+
private tokenize;
|
|
237
|
+
private tokensToVector;
|
|
238
|
+
private hashToken;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/** Generate a unique ID */
|
|
242
|
+
declare function generateId(): string;
|
|
243
|
+
/** Cosine similarity between two vectors */
|
|
244
|
+
declare function cosineSimilarity(a: number[], b: number[]): number;
|
|
245
|
+
|
|
246
|
+
export { AgentMemory, AgentMemoryConfig, BuiltinEmbedder, Checkpoint, ConflictDetector, ConflictResult, DecayConfig, DecayEngine, Embedder, FileStore, ImportanceLevel, LocalStore, MemoryEntry, MemoryType, MultiSignalRetriever, RetrievalQuery, RetrievalResult, RetrievalSignal, StorageBackend, TaskNode, cosineSimilarity, generateId };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { A as AgentMemoryConfig, M as MemoryType, I as ImportanceLevel, a as MemoryEntry, R as RetrievalQuery, b as RetrievalResult, C as ConflictResult, T as TaskNode, c as Checkpoint, D as DecayConfig, S as StorageBackend, E as Embedder, d as RetrievalSignal } from './types-CQ8Hcoqw.js';
|
|
2
|
+
export { e as DecayPolicy } from './types-CQ8Hcoqw.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* AgentMemory - the main entry point.
|
|
6
|
+
*
|
|
7
|
+
* Framework-agnostic memory layer for AI agents.
|
|
8
|
+
* Handles storage, multi-signal retrieval, conflict detection,
|
|
9
|
+
* typed decay, and checkpointing.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const memory = new AgentMemory();
|
|
14
|
+
*
|
|
15
|
+
* await memory.store({
|
|
16
|
+
* content: 'User prefers dark mode',
|
|
17
|
+
* type: 'preference',
|
|
18
|
+
* scope: 'user:123',
|
|
19
|
+
* });
|
|
20
|
+
*
|
|
21
|
+
* const results = await memory.retrieve({ query: 'UI preferences' });
|
|
22
|
+
* const conflicts = await memory.checkConflicts('User prefers light mode', 'user:123');
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
declare class AgentMemory {
|
|
26
|
+
private backend;
|
|
27
|
+
private embedder;
|
|
28
|
+
private retriever;
|
|
29
|
+
private conflictDetector;
|
|
30
|
+
private decayEngine;
|
|
31
|
+
private checkpoints;
|
|
32
|
+
private defaultScope;
|
|
33
|
+
private maxCheckpoints;
|
|
34
|
+
constructor(config?: AgentMemoryConfig);
|
|
35
|
+
/**
|
|
36
|
+
* Store a new memory entry.
|
|
37
|
+
* Automatically generates ID, timestamps, and embedding.
|
|
38
|
+
*/
|
|
39
|
+
store(params: {
|
|
40
|
+
content: string;
|
|
41
|
+
type?: MemoryType;
|
|
42
|
+
scope?: string;
|
|
43
|
+
importance?: ImportanceLevel;
|
|
44
|
+
confidence?: number;
|
|
45
|
+
metadata?: Record<string, unknown>;
|
|
46
|
+
}): Promise<MemoryEntry>;
|
|
47
|
+
/**
|
|
48
|
+
* Update an existing memory entry.
|
|
49
|
+
* Increments version and updates timestamp.
|
|
50
|
+
*/
|
|
51
|
+
update(id: string, updates: Partial<Pick<MemoryEntry, 'content' | 'type' | 'importance' | 'confidence' | 'metadata'>>): Promise<MemoryEntry | null>;
|
|
52
|
+
/** Get a memory by ID */
|
|
53
|
+
get(id: string): Promise<MemoryEntry | null>;
|
|
54
|
+
/** Delete a memory by ID */
|
|
55
|
+
delete(id: string): Promise<boolean>;
|
|
56
|
+
/** Get all memories, optionally filtered by scope */
|
|
57
|
+
getAll(scope?: string): Promise<MemoryEntry[]>;
|
|
58
|
+
/** Clear all memories, optionally for a specific scope only */
|
|
59
|
+
clear(scope?: string): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Multi-signal retrieval.
|
|
62
|
+
* Combines similarity, recency, importance, and task-relevance.
|
|
63
|
+
*/
|
|
64
|
+
retrieve(query: RetrievalQuery): Promise<RetrievalResult[]>;
|
|
65
|
+
/**
|
|
66
|
+
* Check if content conflicts with stored memories.
|
|
67
|
+
* Returns conflicts sorted by confidence.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```typescript
|
|
71
|
+
* const conflicts = await memory.checkConflicts('User likes meat', 'user:123');
|
|
72
|
+
* if (conflicts.length > 0 && conflicts[0].action === 'clarify') {
|
|
73
|
+
* // Ask user to confirm preference change
|
|
74
|
+
* }
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
checkConflicts(content: string, scope?: string): Promise<ConflictResult[]>;
|
|
78
|
+
/**
|
|
79
|
+
* Get the current effective confidence of a memory after decay.
|
|
80
|
+
*/
|
|
81
|
+
getDecayedConfidence(entry: MemoryEntry): number;
|
|
82
|
+
/**
|
|
83
|
+
* Clean up expired memories (decayed below threshold).
|
|
84
|
+
* Returns the number of deleted entries.
|
|
85
|
+
*/
|
|
86
|
+
cleanup(scope?: string, threshold?: number): Promise<number>;
|
|
87
|
+
/**
|
|
88
|
+
* Create a checkpoint of current task state.
|
|
89
|
+
* Use this before context overflow to preserve state.
|
|
90
|
+
*/
|
|
91
|
+
checkpoint(params: {
|
|
92
|
+
taskGraph: TaskNode[];
|
|
93
|
+
summary: string;
|
|
94
|
+
toolOutputs?: Record<string, unknown>;
|
|
95
|
+
activeMemoryIds?: string[];
|
|
96
|
+
}): Promise<Checkpoint>;
|
|
97
|
+
/**
|
|
98
|
+
* Rehydrate from a checkpoint.
|
|
99
|
+
* Returns the checkpoint data + relevant memories.
|
|
100
|
+
*/
|
|
101
|
+
rehydrate(checkpointId: string): Promise<{
|
|
102
|
+
checkpoint: Checkpoint;
|
|
103
|
+
memories: MemoryEntry[];
|
|
104
|
+
} | null>;
|
|
105
|
+
/** Get the latest checkpoint */
|
|
106
|
+
getLatestCheckpoint(): Checkpoint | null;
|
|
107
|
+
/** List all checkpoints */
|
|
108
|
+
listCheckpoints(): Checkpoint[];
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Typed decay engine.
|
|
113
|
+
* Different memory types decay at different rates.
|
|
114
|
+
* Hard constraints (allergies, legal requirements) never decay.
|
|
115
|
+
* Ephemeral task state decays fast.
|
|
116
|
+
*/
|
|
117
|
+
declare class DecayEngine {
|
|
118
|
+
private config;
|
|
119
|
+
constructor(config?: Partial<DecayConfig>);
|
|
120
|
+
/**
|
|
121
|
+
* Compute the current effective confidence of a memory entry
|
|
122
|
+
* after applying temporal decay.
|
|
123
|
+
* Returns a value between 0 and original confidence.
|
|
124
|
+
*/
|
|
125
|
+
computeDecayedConfidence(entry: MemoryEntry): number;
|
|
126
|
+
/**
|
|
127
|
+
* Filter out memories that have decayed below a threshold.
|
|
128
|
+
* Useful for periodic cleanup.
|
|
129
|
+
*/
|
|
130
|
+
filterDecayed(entries: MemoryEntry[], threshold?: number): MemoryEntry[];
|
|
131
|
+
/**
|
|
132
|
+
* Get entries that should be cleaned up (decayed to near-zero).
|
|
133
|
+
*/
|
|
134
|
+
getExpired(entries: MemoryEntry[], threshold?: number): MemoryEntry[];
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* In-memory storage backend. Zero dependencies.
|
|
139
|
+
* Perfect for development, testing, and single-process agents.
|
|
140
|
+
* Data is lost when the process exits.
|
|
141
|
+
*/
|
|
142
|
+
declare class LocalStore implements StorageBackend {
|
|
143
|
+
private entries;
|
|
144
|
+
get(id: string): Promise<MemoryEntry | null>;
|
|
145
|
+
getAll(scope?: string): Promise<MemoryEntry[]>;
|
|
146
|
+
set(entry: MemoryEntry): Promise<void>;
|
|
147
|
+
delete(id: string): Promise<boolean>;
|
|
148
|
+
clear(scope?: string): Promise<void>;
|
|
149
|
+
search(query: RetrievalQuery): Promise<MemoryEntry[]>;
|
|
150
|
+
/** Get the number of stored entries */
|
|
151
|
+
get size(): number;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* File-based storage backend. Persists to a JSON file on disk.
|
|
156
|
+
* Good for single-process agents that need persistence across restarts.
|
|
157
|
+
* Not suitable for concurrent multi-agent access - use Redis/Postgres for that.
|
|
158
|
+
*/
|
|
159
|
+
declare class FileStore implements StorageBackend {
|
|
160
|
+
private entries;
|
|
161
|
+
private filePath;
|
|
162
|
+
private dirty;
|
|
163
|
+
constructor(filePath: string);
|
|
164
|
+
private load;
|
|
165
|
+
private persist;
|
|
166
|
+
get(id: string): Promise<MemoryEntry | null>;
|
|
167
|
+
getAll(scope?: string): Promise<MemoryEntry[]>;
|
|
168
|
+
set(entry: MemoryEntry): Promise<void>;
|
|
169
|
+
delete(id: string): Promise<boolean>;
|
|
170
|
+
clear(scope?: string): Promise<void>;
|
|
171
|
+
search(query: RetrievalQuery): Promise<MemoryEntry[]>;
|
|
172
|
+
get size(): number;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Multi-signal retriever.
|
|
177
|
+
* Combines similarity, recency, importance, and task-relevance
|
|
178
|
+
* into a single ranked result set.
|
|
179
|
+
*/
|
|
180
|
+
declare class MultiSignalRetriever {
|
|
181
|
+
private store;
|
|
182
|
+
private embedder;
|
|
183
|
+
private weights;
|
|
184
|
+
constructor(store: StorageBackend, embedder: Embedder, weights?: Partial<Record<RetrievalSignal, number>>);
|
|
185
|
+
retrieve(query: RetrievalQuery): Promise<RetrievalResult[]>;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Conflict detector.
|
|
190
|
+
* Compares new content against stored memories to find contradictions.
|
|
191
|
+
* Uses semantic similarity + negation detection, not just keyword matching.
|
|
192
|
+
*/
|
|
193
|
+
declare class ConflictDetector {
|
|
194
|
+
private store;
|
|
195
|
+
private embedder;
|
|
196
|
+
/** Similarity threshold to consider two entries as "same topic" */
|
|
197
|
+
private topicThreshold;
|
|
198
|
+
constructor(store: StorageBackend, embedder: Embedder, topicThreshold?: number);
|
|
199
|
+
/**
|
|
200
|
+
* Check if new content conflicts with any stored memories.
|
|
201
|
+
* Returns conflicts sorted by confidence (highest first).
|
|
202
|
+
*/
|
|
203
|
+
check(content: string, scope?: string): Promise<ConflictResult[]>;
|
|
204
|
+
/**
|
|
205
|
+
* Score how contradictory two pieces of text are.
|
|
206
|
+
* Returns 0 (no contradiction) to 1 (strong contradiction).
|
|
207
|
+
*/
|
|
208
|
+
private scoreContradiction;
|
|
209
|
+
/** Check for common antonym pairs */
|
|
210
|
+
private checkAntonyms;
|
|
211
|
+
private suggestAction;
|
|
212
|
+
private generateReason;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Built-in lightweight embedder using bag-of-words TF-IDF.
|
|
217
|
+
* No external dependencies, no API calls.
|
|
218
|
+
* Good enough for conflict detection and basic similarity.
|
|
219
|
+
* For production, plug in OpenAI/Cohere/local embeddings.
|
|
220
|
+
*/
|
|
221
|
+
declare class BuiltinEmbedder implements Embedder {
|
|
222
|
+
private readonly dim;
|
|
223
|
+
private vocabulary;
|
|
224
|
+
private idfCache;
|
|
225
|
+
private documentCount;
|
|
226
|
+
private documentFreq;
|
|
227
|
+
constructor(dimensions?: number);
|
|
228
|
+
dimensions(): number;
|
|
229
|
+
embed(text: string): Promise<number[]>;
|
|
230
|
+
embedBatch(texts: string[]): Promise<number[][]>;
|
|
231
|
+
/**
|
|
232
|
+
* Feed documents to build vocabulary and IDF stats.
|
|
233
|
+
* Call this when adding memories to improve embedding quality.
|
|
234
|
+
*/
|
|
235
|
+
train(documents: string[]): void;
|
|
236
|
+
private tokenize;
|
|
237
|
+
private tokensToVector;
|
|
238
|
+
private hashToken;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/** Generate a unique ID */
|
|
242
|
+
declare function generateId(): string;
|
|
243
|
+
/** Cosine similarity between two vectors */
|
|
244
|
+
declare function cosineSimilarity(a: number[], b: number[]): number;
|
|
245
|
+
|
|
246
|
+
export { AgentMemory, AgentMemoryConfig, BuiltinEmbedder, Checkpoint, ConflictDetector, ConflictResult, DecayConfig, DecayEngine, Embedder, FileStore, ImportanceLevel, LocalStore, MemoryEntry, MemoryType, MultiSignalRetriever, RetrievalQuery, RetrievalResult, RetrievalSignal, StorageBackend, TaskNode, cosineSimilarity, generateId };
|