family-ai-agent 1.0.5 → 1.0.7
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/.letta/settings.local.json +3 -0
- package/dist/cli/index.js +6 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/database/adapters/base-adapter.d.ts +81 -0
- package/dist/database/adapters/base-adapter.d.ts.map +1 -0
- package/dist/database/adapters/base-adapter.js +105 -0
- package/dist/database/adapters/base-adapter.js.map +1 -0
- package/dist/database/adapters/index.d.ts +49 -0
- package/dist/database/adapters/index.d.ts.map +1 -0
- package/dist/database/adapters/index.js +200 -0
- package/dist/database/adapters/index.js.map +1 -0
- package/dist/database/adapters/postgres-adapter.d.ts +75 -0
- package/dist/database/adapters/postgres-adapter.d.ts.map +1 -0
- package/dist/database/adapters/postgres-adapter.js +225 -0
- package/dist/database/adapters/postgres-adapter.js.map +1 -0
- package/dist/database/adapters/sqlite-adapter.d.ts +72 -0
- package/dist/database/adapters/sqlite-adapter.d.ts.map +1 -0
- package/dist/database/adapters/sqlite-adapter.js +368 -0
- package/dist/database/adapters/sqlite-adapter.js.map +1 -0
- package/dist/database/cache/cache-keys.d.ts +180 -0
- package/dist/database/cache/cache-keys.d.ts.map +1 -0
- package/dist/database/cache/cache-keys.js +107 -0
- package/dist/database/cache/cache-keys.js.map +1 -0
- package/dist/database/cache/index.d.ts +24 -0
- package/dist/database/cache/index.d.ts.map +1 -0
- package/dist/database/cache/index.js +34 -0
- package/dist/database/cache/index.js.map +1 -0
- package/dist/database/cache/query-cache.d.ts +67 -0
- package/dist/database/cache/query-cache.d.ts.map +1 -0
- package/dist/database/cache/query-cache.js +177 -0
- package/dist/database/cache/query-cache.js.map +1 -0
- package/dist/database/client.d.ts +63 -4
- package/dist/database/client.d.ts.map +1 -1
- package/dist/database/client.js +147 -59
- package/dist/database/client.js.map +1 -1
- package/dist/database/db-config.d.ts +104 -0
- package/dist/database/db-config.d.ts.map +1 -0
- package/dist/database/db-config.js +167 -0
- package/dist/database/db-config.js.map +1 -0
- package/dist/database/drizzle/index.d.ts +42 -0
- package/dist/database/drizzle/index.d.ts.map +1 -0
- package/dist/database/drizzle/index.js +48 -0
- package/dist/database/drizzle/index.js.map +1 -0
- package/dist/database/drizzle/schema/audit.d.ts +533 -0
- package/dist/database/drizzle/schema/audit.d.ts.map +1 -0
- package/dist/database/drizzle/schema/audit.js +71 -0
- package/dist/database/drizzle/schema/audit.js.map +1 -0
- package/dist/database/drizzle/schema/checkpoints.d.ts +665 -0
- package/dist/database/drizzle/schema/checkpoints.d.ts.map +1 -0
- package/dist/database/drizzle/schema/checkpoints.js +110 -0
- package/dist/database/drizzle/schema/checkpoints.js.map +1 -0
- package/dist/database/drizzle/schema/conversations.d.ts +449 -0
- package/dist/database/drizzle/schema/conversations.d.ts.map +1 -0
- package/dist/database/drizzle/schema/conversations.js +91 -0
- package/dist/database/drizzle/schema/conversations.js.map +1 -0
- package/dist/database/drizzle/schema/documents.d.ts +600 -0
- package/dist/database/drizzle/schema/documents.d.ts.map +1 -0
- package/dist/database/drizzle/schema/documents.js +100 -0
- package/dist/database/drizzle/schema/documents.js.map +1 -0
- package/dist/database/drizzle/schema/index.d.ts +3084 -0
- package/dist/database/drizzle/schema/index.d.ts.map +1 -0
- package/dist/database/drizzle/schema/index.js +46 -0
- package/dist/database/drizzle/schema/index.js.map +1 -0
- package/dist/database/drizzle/schema/memories.d.ts +435 -0
- package/dist/database/drizzle/schema/memories.d.ts.map +1 -0
- package/dist/database/drizzle/schema/memories.js +73 -0
- package/dist/database/drizzle/schema/memories.js.map +1 -0
- package/dist/database/drizzle/schema/tasks.d.ts +565 -0
- package/dist/database/drizzle/schema/tasks.d.ts.map +1 -0
- package/dist/database/drizzle/schema/tasks.js +84 -0
- package/dist/database/drizzle/schema/tasks.js.map +1 -0
- package/dist/database/health/circuit-breaker.d.ts +81 -0
- package/dist/database/health/circuit-breaker.d.ts.map +1 -0
- package/dist/database/health/circuit-breaker.js +184 -0
- package/dist/database/health/circuit-breaker.js.map +1 -0
- package/dist/database/health/health-monitor.d.ts +69 -0
- package/dist/database/health/health-monitor.d.ts.map +1 -0
- package/dist/database/health/health-monitor.js +174 -0
- package/dist/database/health/health-monitor.js.map +1 -0
- package/dist/database/health/index.d.ts +27 -0
- package/dist/database/health/index.d.ts.map +1 -0
- package/dist/database/health/index.js +23 -0
- package/dist/database/health/index.js.map +1 -0
- package/dist/database/index.d.ts +16 -0
- package/dist/database/index.d.ts.map +1 -0
- package/dist/database/index.js +41 -0
- package/dist/database/index.js.map +1 -0
- package/dist/database/migrations/index.d.ts +34 -0
- package/dist/database/migrations/index.d.ts.map +1 -0
- package/dist/database/migrations/index.js +45 -0
- package/dist/database/migrations/index.js.map +1 -0
- package/dist/database/migrations/migrator.d.ts +77 -0
- package/dist/database/migrations/migrator.d.ts.map +1 -0
- package/dist/database/migrations/migrator.js +258 -0
- package/dist/database/migrations/migrator.js.map +1 -0
- package/dist/database/migrations/versions/001_initial.d.ts +9 -0
- package/dist/database/migrations/versions/001_initial.d.ts.map +1 -0
- package/dist/database/migrations/versions/001_initial.js +183 -0
- package/dist/database/migrations/versions/001_initial.js.map +1 -0
- package/dist/database/types.d.ts +255 -0
- package/dist/database/types.d.ts.map +1 -0
- package/dist/database/types.js +8 -0
- package/dist/database/types.js.map +1 -0
- package/dist/database/vector/embedding-cache.d.ts +92 -0
- package/dist/database/vector/embedding-cache.d.ts.map +1 -0
- package/dist/database/vector/embedding-cache.js +185 -0
- package/dist/database/vector/embedding-cache.js.map +1 -0
- package/dist/database/vector/hnsw-index.d.ts +111 -0
- package/dist/database/vector/hnsw-index.d.ts.map +1 -0
- package/dist/database/vector/hnsw-index.js +337 -0
- package/dist/database/vector/hnsw-index.js.map +1 -0
- package/dist/database/vector/index.d.ts +75 -0
- package/dist/database/vector/index.d.ts.map +1 -0
- package/dist/database/vector/index.js +213 -0
- package/dist/database/vector/index.js.map +1 -0
- package/dist/database/vector/similarity.d.ts +67 -0
- package/dist/database/vector/similarity.d.ts.map +1 -0
- package/dist/database/vector/similarity.js +176 -0
- package/dist/database/vector/similarity.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +6 -3
- package/src/cli/index.ts +5 -5
- package/src/database/adapters/base-adapter.ts +171 -0
- package/src/database/adapters/index.ts +224 -0
- package/src/database/adapters/postgres-adapter.ts +285 -0
- package/src/database/adapters/sqlite-adapter.ts +420 -0
- package/src/database/cache/cache-keys.ts +150 -0
- package/src/database/cache/index.ts +44 -0
- package/src/database/cache/query-cache.ts +213 -0
- package/src/database/client.ts +166 -64
- package/src/database/db-config.ts +194 -0
- package/src/database/drizzle/index.ts +66 -0
- package/src/database/drizzle/schema/audit.ts +127 -0
- package/src/database/drizzle/schema/checkpoints.ts +164 -0
- package/src/database/drizzle/schema/conversations.ts +138 -0
- package/src/database/drizzle/schema/documents.ts +157 -0
- package/src/database/drizzle/schema/index.ts +139 -0
- package/src/database/drizzle/schema/memories.ts +127 -0
- package/src/database/drizzle/schema/tasks.ts +129 -0
- package/src/database/health/circuit-breaker.ts +214 -0
- package/src/database/health/health-monitor.ts +224 -0
- package/src/database/health/index.ts +41 -0
- package/src/database/index.ts +157 -0
- package/src/database/migrations/index.ts +52 -0
- package/src/database/migrations/migrator.ts +325 -0
- package/src/database/migrations/versions/001_initial.ts +198 -0
- package/src/database/types.ts +324 -0
- package/src/database/vector/embedding-cache.ts +234 -0
- package/src/database/vector/hnsw-index.ts +452 -0
- package/src/database/vector/index.ts +292 -0
- package/src/database/vector/similarity.ts +198 -0
- package/src/index.ts +1 -1
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HNSW (Hierarchical Navigable Small World) Index
|
|
3
|
+
*
|
|
4
|
+
* In-memory approximate nearest neighbor search for SQLite mode.
|
|
5
|
+
* Provides fast vector similarity search without pgvector.
|
|
6
|
+
*/
|
|
7
|
+
import { cosineSimilarity, euclideanDistance } from './similarity.js';
|
|
8
|
+
import { createLogger } from '../../utils/logger.js';
|
|
9
|
+
const logger = createLogger('HNSWIndex');
|
|
10
|
+
/**
|
|
11
|
+
* Default HNSW configuration
|
|
12
|
+
*/
|
|
13
|
+
const DEFAULT_CONFIG = {
|
|
14
|
+
dimension: 1536,
|
|
15
|
+
similarity: 'cosine',
|
|
16
|
+
M: 16,
|
|
17
|
+
M0: 32,
|
|
18
|
+
efConstruction: 200,
|
|
19
|
+
mL: 1 / Math.log(16),
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* HNSW Index for fast approximate nearest neighbor search
|
|
23
|
+
*/
|
|
24
|
+
export class HNSWIndex {
|
|
25
|
+
nodes = new Map();
|
|
26
|
+
entryPoint = null;
|
|
27
|
+
maxLevel = 0;
|
|
28
|
+
config;
|
|
29
|
+
constructor(config = {}) {
|
|
30
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Get similarity function based on config
|
|
34
|
+
*/
|
|
35
|
+
getSimilarity() {
|
|
36
|
+
if (this.config.similarity === 'euclidean') {
|
|
37
|
+
// Convert distance to similarity (higher is better)
|
|
38
|
+
return (a, b) => 1 / (1 + euclideanDistance(a, b));
|
|
39
|
+
}
|
|
40
|
+
return cosineSimilarity;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Generate random level for new node
|
|
44
|
+
*/
|
|
45
|
+
randomLevel() {
|
|
46
|
+
let level = 0;
|
|
47
|
+
while (Math.random() < this.config.mL && level < 32) {
|
|
48
|
+
level++;
|
|
49
|
+
}
|
|
50
|
+
return level;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Get maximum connections for a level
|
|
54
|
+
*/
|
|
55
|
+
getMaxConnections(level) {
|
|
56
|
+
return level === 0 ? this.config.M0 : this.config.M;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Add a vector to the index
|
|
60
|
+
*/
|
|
61
|
+
add(id, vector) {
|
|
62
|
+
if (vector.length !== this.config.dimension) {
|
|
63
|
+
throw new Error(`Expected dimension ${this.config.dimension}, got ${vector.length}`);
|
|
64
|
+
}
|
|
65
|
+
// Check if already exists
|
|
66
|
+
if (this.nodes.has(id)) {
|
|
67
|
+
// Update existing node
|
|
68
|
+
const existingNode = this.nodes.get(id);
|
|
69
|
+
existingNode.vector = vector;
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const level = this.randomLevel();
|
|
73
|
+
const node = {
|
|
74
|
+
id,
|
|
75
|
+
vector,
|
|
76
|
+
neighbors: new Map(),
|
|
77
|
+
level,
|
|
78
|
+
};
|
|
79
|
+
// Initialize neighbor sets for each level
|
|
80
|
+
for (let l = 0; l <= level; l++) {
|
|
81
|
+
node.neighbors.set(l, new Set());
|
|
82
|
+
}
|
|
83
|
+
this.nodes.set(id, node);
|
|
84
|
+
// First node becomes entry point
|
|
85
|
+
if (!this.entryPoint) {
|
|
86
|
+
this.entryPoint = id;
|
|
87
|
+
this.maxLevel = level;
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const similarity = this.getSimilarity();
|
|
91
|
+
let currentNode = this.entryPoint;
|
|
92
|
+
// Traverse from top level down to level + 1
|
|
93
|
+
for (let l = this.maxLevel; l > level; l--) {
|
|
94
|
+
currentNode = this.searchLayer(vector, currentNode, 1, l, similarity)[0]?.id ?? currentNode;
|
|
95
|
+
}
|
|
96
|
+
// Insert at each level from level down to 0
|
|
97
|
+
for (let l = Math.min(level, this.maxLevel); l >= 0; l--) {
|
|
98
|
+
const candidates = this.searchLayer(vector, currentNode, this.config.efConstruction, l, similarity);
|
|
99
|
+
const neighbors = this.selectNeighbors(candidates, this.getMaxConnections(l));
|
|
100
|
+
// Connect new node to neighbors
|
|
101
|
+
for (const neighbor of neighbors) {
|
|
102
|
+
node.neighbors.get(l).add(neighbor.id);
|
|
103
|
+
// Connect neighbors back to new node (bidirectional)
|
|
104
|
+
const neighborNode = this.nodes.get(neighbor.id);
|
|
105
|
+
if (neighborNode) {
|
|
106
|
+
neighborNode.neighbors.get(l)?.add(id);
|
|
107
|
+
// Prune if too many connections
|
|
108
|
+
const maxConn = this.getMaxConnections(l);
|
|
109
|
+
if ((neighborNode.neighbors.get(l)?.size ?? 0) > maxConn) {
|
|
110
|
+
this.pruneConnections(neighborNode, l, maxConn, similarity);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (candidates.length > 0) {
|
|
115
|
+
currentNode = candidates[0].id;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// Update entry point if new node has higher level
|
|
119
|
+
if (level > this.maxLevel) {
|
|
120
|
+
this.entryPoint = id;
|
|
121
|
+
this.maxLevel = level;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Search for k nearest neighbors
|
|
126
|
+
*/
|
|
127
|
+
search(query, k, ef) {
|
|
128
|
+
if (query.length !== this.config.dimension) {
|
|
129
|
+
throw new Error(`Expected dimension ${this.config.dimension}, got ${query.length}`);
|
|
130
|
+
}
|
|
131
|
+
if (!this.entryPoint) {
|
|
132
|
+
return [];
|
|
133
|
+
}
|
|
134
|
+
const effectiveEf = ef ?? Math.max(k, 100);
|
|
135
|
+
const similarity = this.getSimilarity();
|
|
136
|
+
let currentNode = this.entryPoint;
|
|
137
|
+
// Traverse from top level down to level 1
|
|
138
|
+
for (let l = this.maxLevel; l > 0; l--) {
|
|
139
|
+
currentNode = this.searchLayer(query, currentNode, 1, l, similarity)[0]?.id ?? currentNode;
|
|
140
|
+
}
|
|
141
|
+
// Search at level 0 with ef candidates
|
|
142
|
+
const candidates = this.searchLayer(query, currentNode, effectiveEf, 0, similarity);
|
|
143
|
+
// Return top k
|
|
144
|
+
return candidates.slice(0, k);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Search within a layer
|
|
148
|
+
*/
|
|
149
|
+
searchLayer(query, entryId, ef, level, similarity) {
|
|
150
|
+
const entryNode = this.nodes.get(entryId);
|
|
151
|
+
if (!entryNode)
|
|
152
|
+
return [];
|
|
153
|
+
const visited = new Set([entryId]);
|
|
154
|
+
const candidates = [
|
|
155
|
+
{ id: entryId, similarity: similarity(query, entryNode.vector) },
|
|
156
|
+
];
|
|
157
|
+
// Priority queue (sorted by similarity descending)
|
|
158
|
+
const toExplore = [...candidates];
|
|
159
|
+
while (toExplore.length > 0) {
|
|
160
|
+
// Get best candidate
|
|
161
|
+
toExplore.sort((a, b) => b.similarity - a.similarity);
|
|
162
|
+
const current = toExplore.shift();
|
|
163
|
+
// Get worst in results
|
|
164
|
+
candidates.sort((a, b) => b.similarity - a.similarity);
|
|
165
|
+
const worstSimilarity = candidates.length >= ef
|
|
166
|
+
? candidates[candidates.length - 1].similarity
|
|
167
|
+
: -Infinity;
|
|
168
|
+
// Stop if current is worse than worst result
|
|
169
|
+
if (current.similarity < worstSimilarity) {
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
// Explore neighbors
|
|
173
|
+
const currentNode = this.nodes.get(current.id);
|
|
174
|
+
const neighbors = currentNode?.neighbors.get(level) ?? new Set();
|
|
175
|
+
for (const neighborId of neighbors) {
|
|
176
|
+
if (visited.has(neighborId))
|
|
177
|
+
continue;
|
|
178
|
+
visited.add(neighborId);
|
|
179
|
+
const neighborNode = this.nodes.get(neighborId);
|
|
180
|
+
if (!neighborNode)
|
|
181
|
+
continue;
|
|
182
|
+
const sim = similarity(query, neighborNode.vector);
|
|
183
|
+
const result = { id: neighborId, similarity: sim };
|
|
184
|
+
if (candidates.length < ef || sim > worstSimilarity) {
|
|
185
|
+
candidates.push(result);
|
|
186
|
+
candidates.sort((a, b) => b.similarity - a.similarity);
|
|
187
|
+
if (candidates.length > ef) {
|
|
188
|
+
candidates.pop();
|
|
189
|
+
}
|
|
190
|
+
toExplore.push(result);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return candidates;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Select best neighbors from candidates
|
|
198
|
+
*/
|
|
199
|
+
selectNeighbors(candidates, maxNeighbors) {
|
|
200
|
+
// Simple approach: take top maxNeighbors by similarity
|
|
201
|
+
return candidates
|
|
202
|
+
.sort((a, b) => b.similarity - a.similarity)
|
|
203
|
+
.slice(0, maxNeighbors);
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Prune connections to maintain max connections
|
|
207
|
+
*/
|
|
208
|
+
pruneConnections(node, level, maxConnections, similarity) {
|
|
209
|
+
const neighbors = node.neighbors.get(level);
|
|
210
|
+
if (!neighbors || neighbors.size <= maxConnections)
|
|
211
|
+
return;
|
|
212
|
+
// Calculate similarities and keep best
|
|
213
|
+
const scored = [];
|
|
214
|
+
for (const neighborId of neighbors) {
|
|
215
|
+
const neighborNode = this.nodes.get(neighborId);
|
|
216
|
+
if (neighborNode) {
|
|
217
|
+
scored.push({
|
|
218
|
+
id: neighborId,
|
|
219
|
+
similarity: similarity(node.vector, neighborNode.vector),
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
scored.sort((a, b) => b.similarity - a.similarity);
|
|
224
|
+
const keep = new Set(scored.slice(0, maxConnections).map((s) => s.id));
|
|
225
|
+
// Remove excess connections
|
|
226
|
+
for (const neighborId of neighbors) {
|
|
227
|
+
if (!keep.has(neighborId)) {
|
|
228
|
+
neighbors.delete(neighborId);
|
|
229
|
+
// Also remove back-link
|
|
230
|
+
this.nodes.get(neighborId)?.neighbors.get(level)?.delete(node.id);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Remove a vector from the index
|
|
236
|
+
*/
|
|
237
|
+
remove(id) {
|
|
238
|
+
const node = this.nodes.get(id);
|
|
239
|
+
if (!node)
|
|
240
|
+
return false;
|
|
241
|
+
// Remove from all neighbors
|
|
242
|
+
for (const [level, neighbors] of node.neighbors) {
|
|
243
|
+
for (const neighborId of neighbors) {
|
|
244
|
+
this.nodes.get(neighborId)?.neighbors.get(level)?.delete(id);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
this.nodes.delete(id);
|
|
248
|
+
// Update entry point if needed
|
|
249
|
+
if (this.entryPoint === id) {
|
|
250
|
+
if (this.nodes.size === 0) {
|
|
251
|
+
this.entryPoint = null;
|
|
252
|
+
this.maxLevel = 0;
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
// Find new entry point with highest level
|
|
256
|
+
let maxLvl = 0;
|
|
257
|
+
let newEntry = null;
|
|
258
|
+
for (const [nodeId, n] of this.nodes) {
|
|
259
|
+
if (n.level >= maxLvl) {
|
|
260
|
+
maxLvl = n.level;
|
|
261
|
+
newEntry = nodeId;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
this.entryPoint = newEntry;
|
|
265
|
+
this.maxLevel = maxLvl;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return true;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Check if an ID exists in the index
|
|
272
|
+
*/
|
|
273
|
+
has(id) {
|
|
274
|
+
return this.nodes.has(id);
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Get vector by ID
|
|
278
|
+
*/
|
|
279
|
+
get(id) {
|
|
280
|
+
return this.nodes.get(id)?.vector;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Get index size
|
|
284
|
+
*/
|
|
285
|
+
get size() {
|
|
286
|
+
return this.nodes.size;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Get index statistics
|
|
290
|
+
*/
|
|
291
|
+
getStats() {
|
|
292
|
+
let totalConnections = 0;
|
|
293
|
+
let connectionCount = 0;
|
|
294
|
+
for (const node of this.nodes.values()) {
|
|
295
|
+
for (const neighbors of node.neighbors.values()) {
|
|
296
|
+
totalConnections += neighbors.size;
|
|
297
|
+
connectionCount++;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
return {
|
|
301
|
+
size: this.nodes.size,
|
|
302
|
+
dimension: this.config.dimension,
|
|
303
|
+
maxLevel: this.maxLevel,
|
|
304
|
+
avgConnections: connectionCount > 0 ? totalConnections / connectionCount : 0,
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Clear the index
|
|
309
|
+
*/
|
|
310
|
+
clear() {
|
|
311
|
+
this.nodes.clear();
|
|
312
|
+
this.entryPoint = null;
|
|
313
|
+
this.maxLevel = 0;
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Get all IDs in the index
|
|
317
|
+
*/
|
|
318
|
+
getAllIds() {
|
|
319
|
+
return Array.from(this.nodes.keys());
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Rebuild index from scratch (for optimization)
|
|
323
|
+
*/
|
|
324
|
+
rebuild() {
|
|
325
|
+
const vectors = Array.from(this.nodes.entries()).map(([id, node]) => ({
|
|
326
|
+
id,
|
|
327
|
+
vector: node.vector,
|
|
328
|
+
}));
|
|
329
|
+
this.clear();
|
|
330
|
+
for (const { id, vector } of vectors) {
|
|
331
|
+
this.add(id, vector);
|
|
332
|
+
}
|
|
333
|
+
logger.debug('Index rebuilt', { size: this.size });
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
export default HNSWIndex;
|
|
337
|
+
//# sourceMappingURL=hnsw-index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hnsw-index.js","sourceRoot":"","sources":["../../../src/database/vector/hnsw-index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vector Search Engine
|
|
3
|
+
*
|
|
4
|
+
* Unified interface for vector similarity search.
|
|
5
|
+
* PostgreSQL uses pgvector, SQLite uses in-memory HNSW.
|
|
6
|
+
*/
|
|
7
|
+
import type { DatabaseAdapter, VectorSearchOptions, VectorSearchResult, VectorSearchEngine } from '../types.js';
|
|
8
|
+
export { HNSWIndex, type SearchResult } from './hnsw-index.js';
|
|
9
|
+
export { EmbeddingCache, type EmbeddingCacheStats } from './embedding-cache.js';
|
|
10
|
+
export * from './similarity.js';
|
|
11
|
+
/**
|
|
12
|
+
* PostgreSQL vector search engine using pgvector
|
|
13
|
+
*/
|
|
14
|
+
export declare class PgVectorSearchEngine implements VectorSearchEngine {
|
|
15
|
+
private adapter;
|
|
16
|
+
private tableName;
|
|
17
|
+
private embeddingColumn;
|
|
18
|
+
private dimension;
|
|
19
|
+
constructor(adapter: DatabaseAdapter, options: {
|
|
20
|
+
tableName: string;
|
|
21
|
+
embeddingColumn?: string;
|
|
22
|
+
dimension?: number;
|
|
23
|
+
});
|
|
24
|
+
initialize(): Promise<void>;
|
|
25
|
+
store(id: string, embedding: number[], metadata?: Record<string, unknown>): Promise<void>;
|
|
26
|
+
search(queryEmbedding: number[], options?: VectorSearchOptions): Promise<VectorSearchResult[]>;
|
|
27
|
+
remove(id: string): Promise<void>;
|
|
28
|
+
rebuildIndex(): Promise<void>;
|
|
29
|
+
getStats(): {
|
|
30
|
+
size: number;
|
|
31
|
+
dimension: number;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* SQLite vector search engine using in-memory HNSW
|
|
36
|
+
*/
|
|
37
|
+
export declare class SqliteVectorSearchEngine implements VectorSearchEngine {
|
|
38
|
+
private adapter;
|
|
39
|
+
private tableName;
|
|
40
|
+
private index;
|
|
41
|
+
private cache;
|
|
42
|
+
private dimension;
|
|
43
|
+
private initialized;
|
|
44
|
+
constructor(adapter: DatabaseAdapter, options: {
|
|
45
|
+
tableName: string;
|
|
46
|
+
dimension?: number;
|
|
47
|
+
cacheSize?: number;
|
|
48
|
+
});
|
|
49
|
+
initialize(): Promise<void>;
|
|
50
|
+
store(id: string, embedding: number[], metadata?: Record<string, unknown>): Promise<void>;
|
|
51
|
+
search(queryEmbedding: number[], options?: VectorSearchOptions): Promise<VectorSearchResult[]>;
|
|
52
|
+
remove(id: string): Promise<void>;
|
|
53
|
+
rebuildIndex(): Promise<void>;
|
|
54
|
+
getStats(): {
|
|
55
|
+
size: number;
|
|
56
|
+
dimension: number;
|
|
57
|
+
};
|
|
58
|
+
getCacheStats(): import("./embedding-cache.js").EmbeddingCacheStats;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Create vector search engine based on adapter type
|
|
62
|
+
*/
|
|
63
|
+
export declare function createVectorSearchEngine(adapter: DatabaseAdapter, options: {
|
|
64
|
+
tableName: string;
|
|
65
|
+
embeddingColumn?: string;
|
|
66
|
+
dimension?: number;
|
|
67
|
+
cacheSize?: number;
|
|
68
|
+
}): VectorSearchEngine;
|
|
69
|
+
declare const _default: {
|
|
70
|
+
PgVectorSearchEngine: typeof PgVectorSearchEngine;
|
|
71
|
+
SqliteVectorSearchEngine: typeof SqliteVectorSearchEngine;
|
|
72
|
+
createVectorSearchEngine: typeof createVectorSearchEngine;
|
|
73
|
+
};
|
|
74
|
+
export default _default;
|
|
75
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/database/vector/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAMhH,OAAO,EAAE,SAAS,EAAE,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAChF,cAAc,iBAAiB,CAAC;AAEhC;;GAEG;AACH,qBAAa,oBAAqB,YAAW,kBAAkB;IAC7D,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,SAAS,CAAS;gBAGxB,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE;QACP,SAAS,EAAE,MAAM,CAAC;QAClB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB;IAQG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAK3B,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAKzF,MAAM,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IA6ClG,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKjC,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAKnC,QAAQ,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE;CAGhD;AAED;;GAEG;AACH,qBAAa,wBAAyB,YAAW,kBAAkB;IACjE,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,KAAK,CAAY;IACzB,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAkB;gBAGnC,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE;QACP,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB;IAiBG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IA0B3B,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAKzF,MAAM,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAkElG,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKjC,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAOnC,QAAQ,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE;IAQ/C,aAAa;CAGd;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE;IACP,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GACA,kBAAkB,CAKpB;;;;;;AAED,wBAIE"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vector Search Engine
|
|
3
|
+
*
|
|
4
|
+
* Unified interface for vector similarity search.
|
|
5
|
+
* PostgreSQL uses pgvector, SQLite uses in-memory HNSW.
|
|
6
|
+
*/
|
|
7
|
+
import { HNSWIndex } from './hnsw-index.js';
|
|
8
|
+
import { EmbeddingCache } from './embedding-cache.js';
|
|
9
|
+
import { parseEmbedding } from './similarity.js';
|
|
10
|
+
import { createLogger } from '../../utils/logger.js';
|
|
11
|
+
const logger = createLogger('VectorSearch');
|
|
12
|
+
// Re-export components
|
|
13
|
+
export { HNSWIndex } from './hnsw-index.js';
|
|
14
|
+
export { EmbeddingCache } from './embedding-cache.js';
|
|
15
|
+
export * from './similarity.js';
|
|
16
|
+
/**
|
|
17
|
+
* PostgreSQL vector search engine using pgvector
|
|
18
|
+
*/
|
|
19
|
+
export class PgVectorSearchEngine {
|
|
20
|
+
adapter;
|
|
21
|
+
tableName;
|
|
22
|
+
embeddingColumn;
|
|
23
|
+
dimension;
|
|
24
|
+
constructor(adapter, options) {
|
|
25
|
+
this.adapter = adapter;
|
|
26
|
+
this.tableName = options.tableName;
|
|
27
|
+
this.embeddingColumn = options.embeddingColumn ?? 'embedding';
|
|
28
|
+
this.dimension = options.dimension ?? 1536;
|
|
29
|
+
}
|
|
30
|
+
async initialize() {
|
|
31
|
+
// pgvector is initialized at adapter level
|
|
32
|
+
logger.debug('PgVectorSearchEngine initialized', { table: this.tableName });
|
|
33
|
+
}
|
|
34
|
+
async store(id, embedding, metadata) {
|
|
35
|
+
// This is handled by the memory layer, not directly by vector engine
|
|
36
|
+
logger.debug('Store called on PgVectorSearchEngine', { id });
|
|
37
|
+
}
|
|
38
|
+
async search(queryEmbedding, options = {}) {
|
|
39
|
+
const { limit = 5, minSimilarity = 0.7, userId, memoryType } = options;
|
|
40
|
+
const embeddingStr = `[${queryEmbedding.join(',')}]`;
|
|
41
|
+
let sql = `
|
|
42
|
+
SELECT id, content, memory_type, metadata,
|
|
43
|
+
1 - (${this.embeddingColumn} <=> $1::vector) as similarity
|
|
44
|
+
FROM ${this.tableName}
|
|
45
|
+
WHERE 1 - (${this.embeddingColumn} <=> $1::vector) >= $2
|
|
46
|
+
`;
|
|
47
|
+
const params = [embeddingStr, minSimilarity];
|
|
48
|
+
let paramIdx = 3;
|
|
49
|
+
if (userId) {
|
|
50
|
+
sql += ` AND user_id = $${paramIdx}`;
|
|
51
|
+
params.push(userId);
|
|
52
|
+
paramIdx++;
|
|
53
|
+
}
|
|
54
|
+
if (memoryType) {
|
|
55
|
+
sql += ` AND memory_type = $${paramIdx}`;
|
|
56
|
+
params.push(memoryType);
|
|
57
|
+
paramIdx++;
|
|
58
|
+
}
|
|
59
|
+
sql += ` ORDER BY similarity DESC LIMIT $${paramIdx}`;
|
|
60
|
+
params.push(limit);
|
|
61
|
+
const result = await this.adapter.query(sql, params);
|
|
62
|
+
return result.rows.map((row) => ({
|
|
63
|
+
id: row.id,
|
|
64
|
+
content: row.content,
|
|
65
|
+
similarity: row.similarity,
|
|
66
|
+
memoryType: row.memory_type,
|
|
67
|
+
metadata: row.metadata,
|
|
68
|
+
}));
|
|
69
|
+
}
|
|
70
|
+
async remove(id) {
|
|
71
|
+
// Handled by memory layer
|
|
72
|
+
logger.debug('Remove called on PgVectorSearchEngine', { id });
|
|
73
|
+
}
|
|
74
|
+
async rebuildIndex() {
|
|
75
|
+
// pgvector indexes are managed by PostgreSQL
|
|
76
|
+
logger.debug('Rebuild index called on PgVectorSearchEngine');
|
|
77
|
+
}
|
|
78
|
+
getStats() {
|
|
79
|
+
return { size: 0, dimension: this.dimension }; // Would need a count query
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* SQLite vector search engine using in-memory HNSW
|
|
84
|
+
*/
|
|
85
|
+
export class SqliteVectorSearchEngine {
|
|
86
|
+
adapter;
|
|
87
|
+
tableName;
|
|
88
|
+
index;
|
|
89
|
+
cache;
|
|
90
|
+
dimension;
|
|
91
|
+
initialized = false;
|
|
92
|
+
constructor(adapter, options) {
|
|
93
|
+
this.adapter = adapter;
|
|
94
|
+
this.tableName = options.tableName;
|
|
95
|
+
this.dimension = options.dimension ?? 1536;
|
|
96
|
+
this.index = new HNSWIndex({
|
|
97
|
+
dimension: this.dimension,
|
|
98
|
+
similarity: 'cosine',
|
|
99
|
+
M: 16,
|
|
100
|
+
efConstruction: 200,
|
|
101
|
+
});
|
|
102
|
+
this.cache = new EmbeddingCache({
|
|
103
|
+
maxSize: options.cacheSize ?? 10000,
|
|
104
|
+
dimension: this.dimension,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
async initialize() {
|
|
108
|
+
if (this.initialized)
|
|
109
|
+
return;
|
|
110
|
+
// Load all embeddings from database into memory
|
|
111
|
+
const result = await this.adapter.query(`SELECT id, embedding, memory_type, content FROM ${this.tableName}`);
|
|
112
|
+
for (const row of result.rows) {
|
|
113
|
+
const embedding = parseEmbedding(row.embedding);
|
|
114
|
+
if (embedding && embedding.length === this.dimension) {
|
|
115
|
+
this.index.add(row.id, embedding);
|
|
116
|
+
this.cache.set(row.id, embedding);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
this.initialized = true;
|
|
120
|
+
logger.info('SqliteVectorSearchEngine initialized', {
|
|
121
|
+
table: this.tableName,
|
|
122
|
+
vectorCount: this.index.size,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
async store(id, embedding, metadata) {
|
|
126
|
+
this.index.add(id, embedding);
|
|
127
|
+
this.cache.set(id, embedding, metadata);
|
|
128
|
+
}
|
|
129
|
+
async search(queryEmbedding, options = {}) {
|
|
130
|
+
const { limit = 5, minSimilarity = 0.7, userId, memoryType } = options;
|
|
131
|
+
// Use HNSW for initial candidates (get more than needed for filtering)
|
|
132
|
+
const candidates = this.index.search(queryEmbedding, limit * 3);
|
|
133
|
+
// Filter candidates that don't meet similarity threshold
|
|
134
|
+
const filtered = candidates.filter((c) => c.similarity >= minSimilarity);
|
|
135
|
+
if (filtered.length === 0) {
|
|
136
|
+
return [];
|
|
137
|
+
}
|
|
138
|
+
// Get full records from database
|
|
139
|
+
const ids = filtered.map((c) => c.id);
|
|
140
|
+
const placeholders = ids.map((_, i) => `$${i + 1}`).join(',');
|
|
141
|
+
let sql = `SELECT id, content, memory_type, metadata FROM ${this.tableName} WHERE id IN (${placeholders})`;
|
|
142
|
+
const params = [...ids];
|
|
143
|
+
if (userId) {
|
|
144
|
+
sql = sql.replace('WHERE', `WHERE user_id = $${params.length + 1} AND`);
|
|
145
|
+
params.push(userId);
|
|
146
|
+
}
|
|
147
|
+
if (memoryType) {
|
|
148
|
+
sql = sql.replace('WHERE', `WHERE memory_type = $${params.length + 1} AND`);
|
|
149
|
+
params.push(memoryType);
|
|
150
|
+
}
|
|
151
|
+
const result = await this.adapter.query(sql, params);
|
|
152
|
+
// Create a map for quick lookup
|
|
153
|
+
const recordMap = new Map();
|
|
154
|
+
for (const row of result.rows) {
|
|
155
|
+
recordMap.set(row.id, row);
|
|
156
|
+
}
|
|
157
|
+
// Build results with similarity scores
|
|
158
|
+
const results = [];
|
|
159
|
+
for (const candidate of filtered) {
|
|
160
|
+
const record = recordMap.get(candidate.id);
|
|
161
|
+
if (record) {
|
|
162
|
+
results.push({
|
|
163
|
+
id: record.id,
|
|
164
|
+
content: record.content,
|
|
165
|
+
similarity: candidate.similarity,
|
|
166
|
+
memoryType: record.memory_type,
|
|
167
|
+
metadata: typeof record.metadata === 'string'
|
|
168
|
+
? JSON.parse(record.metadata)
|
|
169
|
+
: record.metadata,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// Sort by similarity and limit
|
|
174
|
+
return results
|
|
175
|
+
.sort((a, b) => b.similarity - a.similarity)
|
|
176
|
+
.slice(0, limit);
|
|
177
|
+
}
|
|
178
|
+
async remove(id) {
|
|
179
|
+
this.index.remove(id);
|
|
180
|
+
this.cache.delete(id);
|
|
181
|
+
}
|
|
182
|
+
async rebuildIndex() {
|
|
183
|
+
this.initialized = false;
|
|
184
|
+
this.index.clear();
|
|
185
|
+
this.cache.clear();
|
|
186
|
+
await this.initialize();
|
|
187
|
+
}
|
|
188
|
+
getStats() {
|
|
189
|
+
const indexStats = this.index.getStats();
|
|
190
|
+
return {
|
|
191
|
+
size: indexStats.size,
|
|
192
|
+
dimension: indexStats.dimension,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
getCacheStats() {
|
|
196
|
+
return this.cache.getStats();
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Create vector search engine based on adapter type
|
|
201
|
+
*/
|
|
202
|
+
export function createVectorSearchEngine(adapter, options) {
|
|
203
|
+
if (adapter.type === 'postgresql') {
|
|
204
|
+
return new PgVectorSearchEngine(adapter, options);
|
|
205
|
+
}
|
|
206
|
+
return new SqliteVectorSearchEngine(adapter, options);
|
|
207
|
+
}
|
|
208
|
+
export default {
|
|
209
|
+
PgVectorSearchEngine,
|
|
210
|
+
SqliteVectorSearchEngine,
|
|
211
|
+
createVectorSearchEngine,
|
|
212
|
+
};
|
|
213
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/database/vector/index.ts"],"names":[],"mappings":"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"}
|