@claude-flow/memory 3.0.7 → 3.0.8
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/dist/agentdb-backend-hnsw.test.d.ts +2 -0
- package/dist/agentdb-backend-hnsw.test.d.ts.map +1 -0
- package/dist/agentdb-backend-hnsw.test.js +269 -0
- package/dist/agentdb-backend-hnsw.test.js.map +1 -0
- package/dist/agentdb-backend-optional.test.d.ts +2 -0
- package/dist/agentdb-backend-optional.test.d.ts.map +1 -0
- package/dist/agentdb-backend-optional.test.js +49 -0
- package/dist/agentdb-backend-optional.test.js.map +1 -0
- package/dist/agentdb-backend.d.ts +13 -33
- package/dist/agentdb-backend.d.ts.map +1 -1
- package/dist/agentdb-backend.js +136 -161
- package/dist/agentdb-backend.js.map +1 -1
- package/dist/agentdb-hnsw-adapter.d.ts +36 -0
- package/dist/agentdb-hnsw-adapter.d.ts.map +1 -0
- package/dist/agentdb-hnsw-adapter.js +151 -0
- package/dist/agentdb-hnsw-adapter.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentdb-backend-hnsw.test.d.ts","sourceRoot":"","sources":["../src/agentdb-backend-hnsw.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { HNSWIndex, isHnswlibAvailable } from 'agentdb';
|
|
3
|
+
import { AgentDBBackend } from './agentdb-backend.js';
|
|
4
|
+
import { createDefaultEntry } from './types.js';
|
|
5
|
+
const nativeAvailable = await isHnswlibAvailable();
|
|
6
|
+
const required = process.env.RUFLO_REQUIRE_NATIVE_HNSW === '1';
|
|
7
|
+
const vector = (...values) => new Float32Array(values);
|
|
8
|
+
const entry = (id, embedding, namespace = 'test') => ({ ...createDefaultEntry({ key: id, content: id, namespace }), id, embedding });
|
|
9
|
+
// A normal install can omit the optional native addon. The verification job
|
|
10
|
+
// sets RUFLO_REQUIRE_NATIVE_HNSW=1 so absence is a failure, never a silent skip.
|
|
11
|
+
describe.skipIf(!nativeAvailable && !required)('AgentDBBackend real native HNSW', () => {
|
|
12
|
+
let backend;
|
|
13
|
+
beforeEach(async () => {
|
|
14
|
+
expect(nativeAvailable).toBe(true);
|
|
15
|
+
vi.stubEnv('AGENTDB_DISABLE_TRANSFORMERS', '1');
|
|
16
|
+
backend = new AgentDBBackend({
|
|
17
|
+
dbPath: ':memory:',
|
|
18
|
+
vectorDimension: 3,
|
|
19
|
+
vectorBackend: 'hnswlib',
|
|
20
|
+
embeddingGenerator: async (content) => content === 'changed' ? vector(0, 1, 0) : vector(1, 0, 0),
|
|
21
|
+
});
|
|
22
|
+
await backend.initialize();
|
|
23
|
+
expect(backend.isAvailable()).toBe(true);
|
|
24
|
+
});
|
|
25
|
+
afterEach(async () => {
|
|
26
|
+
await backend?.shutdown();
|
|
27
|
+
vi.restoreAllMocks();
|
|
28
|
+
vi.unstubAllEnvs();
|
|
29
|
+
});
|
|
30
|
+
it('builds and searches the real export without asking for an imaginary controller', async () => {
|
|
31
|
+
const nativeSearch = vi.spyOn(HNSWIndex.prototype, 'search');
|
|
32
|
+
const getController = vi.spyOn(backend.getAgentDB(), 'getController');
|
|
33
|
+
const errors = vi.spyOn(console, 'error');
|
|
34
|
+
await backend.bulkInsert([
|
|
35
|
+
entry('east', vector(1, 0, 0)),
|
|
36
|
+
entry('near-east', vector(0.9, 0.1, 0)),
|
|
37
|
+
entry('north', vector(0, 1, 0)),
|
|
38
|
+
entry('west', vector(-1, 0, 0)),
|
|
39
|
+
]);
|
|
40
|
+
const results = await backend.search(vector(1, 0, 0), { k: 2 });
|
|
41
|
+
expect(results.map((r) => r.entry.id)).toEqual(['east', 'near-east']);
|
|
42
|
+
expect(results[0]).toMatchObject({ score: 1, distance: 0 });
|
|
43
|
+
expect(results[1].score).toBeCloseTo(0.993883734, 6);
|
|
44
|
+
expect(nativeSearch).toHaveBeenCalledOnce();
|
|
45
|
+
expect(getController).not.toHaveBeenCalledWith('hnsw');
|
|
46
|
+
expect(errors.mock.calls.some(([message]) => String(message).includes('HNSW search failed'))).toBe(false);
|
|
47
|
+
expect((await backend.getStats()).hnswStats?.vectorCount).toBe(4);
|
|
48
|
+
expect((await backend.healthCheck()).components.index.status).toBe('healthy');
|
|
49
|
+
});
|
|
50
|
+
it('reuses a built index, but rebuilds on append, replacement, update and deletion', async () => {
|
|
51
|
+
const build = vi.spyOn(HNSWIndex.prototype, 'buildIndex');
|
|
52
|
+
await backend.store(entry('a', vector(1, 0, 0)));
|
|
53
|
+
await backend.store(entry('b', vector(0.9, 0.1, 0)));
|
|
54
|
+
await backend.search(vector(1, 0, 0), { k: 1 });
|
|
55
|
+
await backend.search(vector(1, 0, 0), { k: 1 });
|
|
56
|
+
expect(build).toHaveBeenCalledTimes(1);
|
|
57
|
+
await backend.store(entry('c', vector(0, 0, 1)));
|
|
58
|
+
expect((await backend.search(vector(0, 0, 1), { k: 1 }))[0].entry.id).toBe('c');
|
|
59
|
+
await backend.store(entry('a', vector(-1, 0, 0), 'moved'));
|
|
60
|
+
expect(await backend.getByKey('test', 'a')).toBeNull();
|
|
61
|
+
expect((await backend.search(vector(1, 0, 0), { k: 1 }))[0].entry.id).toBe('b');
|
|
62
|
+
await backend.update('b', { content: 'changed' });
|
|
63
|
+
expect((await backend.search(vector(0, 1, 0), { k: 1 }))[0].entry.id).toBe('b');
|
|
64
|
+
await backend.delete('b');
|
|
65
|
+
const results = await backend.search(vector(0, 1, 0), { k: 99 });
|
|
66
|
+
expect(results.map((r) => r.entry.id).sort()).toEqual(['a', 'c']);
|
|
67
|
+
expect(new Set(results.map((r) => r.entry.id)).size).toBe(2);
|
|
68
|
+
expect((await backend.getStats()).hnswStats?.vectorCount).toBe(2);
|
|
69
|
+
expect(build).toHaveBeenCalledTimes(5);
|
|
70
|
+
});
|
|
71
|
+
it('clears the last point and rebuilds from entries on same-instance reinitialize', async () => {
|
|
72
|
+
await backend.store(entry('a', vector(1, 0, 0)));
|
|
73
|
+
await backend.search(vector(1, 0, 0), { k: 1 });
|
|
74
|
+
await backend.clearNamespace('test');
|
|
75
|
+
expect(await backend.search(vector(1, 0, 0), { k: 1 })).toEqual([]);
|
|
76
|
+
expect((await backend.getStats()).hnswStats).toBeUndefined();
|
|
77
|
+
await backend.store(entry('loaded', vector(0, 1, 0)));
|
|
78
|
+
await backend.shutdown();
|
|
79
|
+
expect((await backend.getStats()).hnswStats).toBeUndefined();
|
|
80
|
+
await backend.initialize();
|
|
81
|
+
expect((await backend.search(vector(0, 1, 0), { k: 1 }))[0].entry.id).toBe('loaded');
|
|
82
|
+
});
|
|
83
|
+
it('keeps filtered top-k exact and honors zero thresholds', async () => {
|
|
84
|
+
const search = vi.spyOn(HNSWIndex.prototype, 'search');
|
|
85
|
+
await backend.bulkInsert([
|
|
86
|
+
entry('outside-1', vector(1, 0, 0), 'other'),
|
|
87
|
+
entry('outside-2', vector(0.99, 0.01, 0), 'other'),
|
|
88
|
+
entry('inside', vector(0.8, 0.2, 0)),
|
|
89
|
+
entry('opposite', vector(-1, 0, 0)),
|
|
90
|
+
]);
|
|
91
|
+
const filtered = await backend.search(vector(1, 0, 0), {
|
|
92
|
+
k: 1, filters: { type: 'semantic', namespace: 'test', limit: 1 },
|
|
93
|
+
});
|
|
94
|
+
expect(filtered.map((r) => r.entry.id)).toEqual(['inside']);
|
|
95
|
+
expect(search).not.toHaveBeenCalled();
|
|
96
|
+
const threshold = await backend.search(vector(1, 0, 0), { k: 10, threshold: 0 });
|
|
97
|
+
expect(threshold.map((r) => r.entry.id)).not.toContain('opposite');
|
|
98
|
+
expect(search).toHaveBeenCalledOnce();
|
|
99
|
+
});
|
|
100
|
+
it('uses native search for semantic queries without filtering constraints', async () => {
|
|
101
|
+
const search = vi.spyOn(HNSWIndex.prototype, 'search');
|
|
102
|
+
await backend.store(entry('a', vector(1, 0, 0)));
|
|
103
|
+
expect((await backend.query({
|
|
104
|
+
type: 'semantic', embedding: vector(1, 0, 0), limit: 1,
|
|
105
|
+
}))[0].id).toBe('a');
|
|
106
|
+
expect(search).toHaveBeenCalledOnce();
|
|
107
|
+
});
|
|
108
|
+
it('keeps default expiry eligibility consistent with exact semantic search', async () => {
|
|
109
|
+
const search = vi.spyOn(HNSWIndex.prototype, 'search');
|
|
110
|
+
await backend.store({ ...entry('expired', vector(1, 0, 0)), expiresAt: Date.now() - 1 });
|
|
111
|
+
await backend.store(entry('live', vector(0.9, 0.1, 0)));
|
|
112
|
+
const query = { type: 'semantic', embedding: vector(1, 0, 0), limit: 1 };
|
|
113
|
+
expect((await backend.query(query)).map((r) => r.id)).toEqual(['live']);
|
|
114
|
+
expect(search).not.toHaveBeenCalled();
|
|
115
|
+
expect((await backend.query({ ...query, includeExpired: true })).map((r) => r.id)).toEqual(['expired']);
|
|
116
|
+
await backend.delete('expired');
|
|
117
|
+
expect((await backend.query(query)).map((r) => r.id)).toEqual(['live']);
|
|
118
|
+
expect(search).toHaveBeenCalledOnce();
|
|
119
|
+
await backend.update('live', { expiresAt: Date.now() - 1 });
|
|
120
|
+
expect(await backend.query(query)).toEqual([]);
|
|
121
|
+
// Replacing a TTL entry with an entry without expiry restores native use.
|
|
122
|
+
await backend.store(entry('live', vector(0.9, 0.1, 0)));
|
|
123
|
+
expect((await backend.query(query)).map((r) => r.id)).toEqual(['live']);
|
|
124
|
+
expect(search).toHaveBeenCalledTimes(2);
|
|
125
|
+
});
|
|
126
|
+
it('owns indexed vectors instead of exposing mutable input or result aliases', async () => {
|
|
127
|
+
const a = entry('a', vector(1, 0, 0));
|
|
128
|
+
const b = entry('b', vector(0, 1, 0));
|
|
129
|
+
await backend.bulkInsert([a, b]);
|
|
130
|
+
const east = () => backend.search(vector(1, 0, 0), { k: 1 });
|
|
131
|
+
expect((await east())[0].entry.id).toBe('a');
|
|
132
|
+
a.embedding.set([-1, 0, 0]);
|
|
133
|
+
b.embedding.set([1, 0, 0]);
|
|
134
|
+
a.expiresAt = 0;
|
|
135
|
+
(await backend.get('a')).embedding.set([-1, 0, 0]);
|
|
136
|
+
(await east())[0].entry.embedding.set([-1, 0, 0]);
|
|
137
|
+
(await backend.query({ type: 'exact', key: 'a', limit: 1 }))[0].embedding.set([-1, 0, 0]);
|
|
138
|
+
const result = await east();
|
|
139
|
+
expect(result[0]).toMatchObject({ entry: { id: 'a' }, score: 1 });
|
|
140
|
+
expect((await backend.query({ type: 'semantic', embedding: vector(1, 0, 0), limit: 1 }))[0].id).toBe('a');
|
|
141
|
+
await backend.delete('b');
|
|
142
|
+
const updated = await backend.update('a', { content: 'changed' });
|
|
143
|
+
updated.embedding.set([0, -1, 0]);
|
|
144
|
+
expect((await backend.search(vector(0, 1, 0), { k: 1 }))[0].score).toBe(1);
|
|
145
|
+
});
|
|
146
|
+
it('normalizes extreme finite values before native cosine search', async () => {
|
|
147
|
+
await backend.bulkInsert([
|
|
148
|
+
entry('huge', vector(3e38, 1e38, 0)),
|
|
149
|
+
entry('tiny', vector(0, 1e-38, 0)),
|
|
150
|
+
entry('other', vector(0, 0, 1)),
|
|
151
|
+
]);
|
|
152
|
+
expect((await backend.search(vector(3e38, 1e38, 0), { k: 1 }))[0].entry.id).toBe('huge');
|
|
153
|
+
expect((await backend.search(vector(0, 1e-38, 0), { k: 1 }))[0].entry.id).toBe('tiny');
|
|
154
|
+
});
|
|
155
|
+
it('rejects unsafe native tuning without constructing an index', async () => {
|
|
156
|
+
await backend.shutdown();
|
|
157
|
+
backend = new AgentDBBackend({
|
|
158
|
+
dbPath: ':memory:', vectorDimension: 3, hnswM: 0,
|
|
159
|
+
});
|
|
160
|
+
await backend.initialize();
|
|
161
|
+
const build = vi.spyOn(HNSWIndex.prototype, 'buildIndex');
|
|
162
|
+
await backend.store(entry('a', vector(1, 0, 0)));
|
|
163
|
+
expect((await backend.search(vector(1, 0, 0), { k: 1 }))[0].entry.id).toBe('a');
|
|
164
|
+
expect(build).not.toHaveBeenCalled();
|
|
165
|
+
expect((await backend.getStats()).hnswStats).toBeUndefined();
|
|
166
|
+
});
|
|
167
|
+
it('serializes per-query ef changes across concurrent native searches', async () => {
|
|
168
|
+
await backend.store(entry('a', vector(1, 0, 0)));
|
|
169
|
+
await backend.search(vector(1, 0, 0), { k: 1 });
|
|
170
|
+
const original = HNSWIndex.prototype.search;
|
|
171
|
+
const observed = [];
|
|
172
|
+
vi.spyOn(HNSWIndex.prototype, 'search').mockImplementation(async function (...args) {
|
|
173
|
+
await Promise.resolve();
|
|
174
|
+
observed.push(this.getStats().efSearch);
|
|
175
|
+
return original.apply(this, args);
|
|
176
|
+
});
|
|
177
|
+
await Promise.all([
|
|
178
|
+
backend.search(vector(1, 0, 0), { k: 1, ef: 20 }),
|
|
179
|
+
backend.search(vector(1, 0, 0), { k: 1, ef: 200 }),
|
|
180
|
+
]);
|
|
181
|
+
expect(observed).toEqual([20, 200]);
|
|
182
|
+
});
|
|
183
|
+
it('handles empty, oversized-k, zero vectors and mismatched dimensions safely', async () => {
|
|
184
|
+
expect(await backend.search(vector(1, 0, 0), { k: 1 })).toEqual([]);
|
|
185
|
+
await backend.store(entry('zero', vector(0, 0, 0)));
|
|
186
|
+
const results = await backend.search(vector(1, 0, 0), { k: 100 });
|
|
187
|
+
expect(results).toHaveLength(1);
|
|
188
|
+
expect(results[0]).toMatchObject({ score: 0, distance: 1 });
|
|
189
|
+
expect(await backend.search(vector(1, 0, 0), { k: 0 })).toEqual([]);
|
|
190
|
+
await backend.store(entry('legacy-dimension', vector(1, 0)));
|
|
191
|
+
const legacy = await backend.search(vector(1, 0), { k: 2 });
|
|
192
|
+
expect(legacy.some((r) => r.entry.id === 'legacy-dimension')).toBe(true);
|
|
193
|
+
expect((await backend.getStats()).hnswStats).toBeUndefined();
|
|
194
|
+
});
|
|
195
|
+
it('falls back after native build failure, without retrying on every query', async () => {
|
|
196
|
+
const build = vi.spyOn(HNSWIndex.prototype, 'buildIndex').mockRejectedValueOnce(new Error('native unavailable'));
|
|
197
|
+
await backend.store(entry('a', vector(1, 0, 0)));
|
|
198
|
+
for (let i = 0; i < 2; i++) {
|
|
199
|
+
expect((await backend.search(vector(1, 0, 0), { k: 1 }))[0].entry.id).toBe('a');
|
|
200
|
+
}
|
|
201
|
+
expect(build).toHaveBeenCalledOnce();
|
|
202
|
+
expect((await backend.getStats()).hnswStats).toBeUndefined();
|
|
203
|
+
expect((await backend.healthCheck()).components.index.status).toBe('degraded');
|
|
204
|
+
});
|
|
205
|
+
it('falls back after native search failure and stops advertising a live index', async () => {
|
|
206
|
+
const search = vi.spyOn(HNSWIndex.prototype, 'search').mockRejectedValueOnce(new Error('native failure'));
|
|
207
|
+
await backend.store(entry('a', vector(1, 0, 0)));
|
|
208
|
+
for (let i = 0; i < 2; i++) {
|
|
209
|
+
expect((await backend.search(vector(1, 0, 0), { k: 1 }))[0].entry.id).toBe('a');
|
|
210
|
+
}
|
|
211
|
+
expect(search).toHaveBeenCalledOnce();
|
|
212
|
+
expect((await backend.getStats()).hnswStats).toBeUndefined();
|
|
213
|
+
});
|
|
214
|
+
it('rejects snapshots invalidated during asynchronous index construction', async () => {
|
|
215
|
+
const original = HNSWIndex.prototype.buildIndex;
|
|
216
|
+
let release;
|
|
217
|
+
const gate = new Promise((resolve) => { release = resolve; });
|
|
218
|
+
const build = vi.spyOn(HNSWIndex.prototype, 'buildIndex').mockImplementationOnce(async function (...args) {
|
|
219
|
+
await gate;
|
|
220
|
+
return original.apply(this, args);
|
|
221
|
+
});
|
|
222
|
+
await backend.store(entry('old', vector(1, 0, 0)));
|
|
223
|
+
const pending = backend.search(vector(1, 0, 0), { k: 1 });
|
|
224
|
+
await vi.waitFor(() => expect(build).toHaveBeenCalledOnce());
|
|
225
|
+
await backend.delete('old');
|
|
226
|
+
await backend.store(entry('new', vector(0.9, 0.1, 0)));
|
|
227
|
+
release();
|
|
228
|
+
expect((await pending).map((r) => r.entry.id)).toEqual(['new']);
|
|
229
|
+
expect((await backend.search(vector(1, 0, 0), { k: 1 }))[0].entry.id).toBe('new');
|
|
230
|
+
});
|
|
231
|
+
it('snapshots query vectors before asynchronous native construction', async () => {
|
|
232
|
+
const original = HNSWIndex.prototype.buildIndex;
|
|
233
|
+
let release;
|
|
234
|
+
const gate = new Promise((resolve) => { release = resolve; });
|
|
235
|
+
const build = vi.spyOn(HNSWIndex.prototype, 'buildIndex').mockImplementationOnce(async function (...args) {
|
|
236
|
+
await gate;
|
|
237
|
+
return original.apply(this, args);
|
|
238
|
+
});
|
|
239
|
+
await backend.store(entry('a', vector(1, 0, 0)));
|
|
240
|
+
await backend.store(entry('b', vector(0, 1, 0)));
|
|
241
|
+
const query = vector(1, 0, 0);
|
|
242
|
+
const pending = backend.search(query, { k: 1 });
|
|
243
|
+
await vi.waitFor(() => expect(build).toHaveBeenCalledOnce());
|
|
244
|
+
query.fill(Number.NaN);
|
|
245
|
+
release();
|
|
246
|
+
expect((await pending)[0]).toMatchObject({ entry: { id: 'a' }, score: 1, distance: 0 });
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
describe('AgentDBBackend explicit non-native mode', () => {
|
|
250
|
+
it('uses exact fallback under forceWasm with no HNSW capability claim', async () => {
|
|
251
|
+
vi.stubEnv('AGENTDB_DISABLE_TRANSFORMERS', '1');
|
|
252
|
+
const search = vi.spyOn(HNSWIndex.prototype, 'search');
|
|
253
|
+
const backend = new AgentDBBackend({ dbPath: ':memory:', forceWasm: true, vectorDimension: 3 });
|
|
254
|
+
try {
|
|
255
|
+
await backend.initialize();
|
|
256
|
+
await backend.store(entry('a', vector(1, 0, 0)));
|
|
257
|
+
expect((await backend.search(vector(1, 0, 0), { k: 1 }))[0].entry.id).toBe('a');
|
|
258
|
+
expect(search).not.toHaveBeenCalled();
|
|
259
|
+
expect((await backend.getStats()).hnswStats).toBeUndefined();
|
|
260
|
+
expect((await backend.healthCheck()).components.index.status).toBe('degraded');
|
|
261
|
+
}
|
|
262
|
+
finally {
|
|
263
|
+
await backend.shutdown();
|
|
264
|
+
vi.restoreAllMocks();
|
|
265
|
+
vi.unstubAllEnvs();
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
//# sourceMappingURL=agentdb-backend-hnsw.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentdb-backend-hnsw.test.js","sourceRoot":"","sources":["../src/agentdb-backend-hnsw.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentdb-backend-optional.test.d.ts","sourceRoot":"","sources":["../src/agentdb-backend-optional.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { createDefaultEntry } from './types.js';
|
|
3
|
+
const optional = vi.hoisted(() => ({ mode: 'missing-export' }));
|
|
4
|
+
vi.mock('agentdb', async (importOriginal) => {
|
|
5
|
+
if (optional.mode === 'missing-package')
|
|
6
|
+
throw new Error('agentdb is not installed');
|
|
7
|
+
const actual = await importOriginal();
|
|
8
|
+
return {
|
|
9
|
+
...actual,
|
|
10
|
+
HNSWIndex: optional.mode === 'missing-export' ? undefined : actual.HNSWIndex,
|
|
11
|
+
isHnswlibAvailable: async () => false,
|
|
12
|
+
};
|
|
13
|
+
});
|
|
14
|
+
describe('AgentDBBackend optional native capability', () => {
|
|
15
|
+
beforeEach(() => {
|
|
16
|
+
vi.resetModules();
|
|
17
|
+
vi.stubEnv('AGENTDB_DISABLE_TRANSFORMERS', '1');
|
|
18
|
+
});
|
|
19
|
+
afterEach(() => {
|
|
20
|
+
vi.restoreAllMocks();
|
|
21
|
+
vi.unstubAllEnvs();
|
|
22
|
+
});
|
|
23
|
+
for (const mode of ['missing-export', 'unavailable-addon', 'missing-package']) {
|
|
24
|
+
it(`returns exact neighbors with ${mode} rather than empty results or false HNSW stats`, async () => {
|
|
25
|
+
optional.mode = mode;
|
|
26
|
+
const { AgentDBBackend } = await import('./agentdb-backend.js');
|
|
27
|
+
const backend = new AgentDBBackend({ dbPath: ':memory:', vectorDimension: 2 });
|
|
28
|
+
try {
|
|
29
|
+
await backend.initialize();
|
|
30
|
+
const entry = {
|
|
31
|
+
...createDefaultEntry({ key: 'kept', content: 'kept' }),
|
|
32
|
+
embedding: new Float32Array([1, 0]),
|
|
33
|
+
};
|
|
34
|
+
await backend.store(entry);
|
|
35
|
+
const errors = vi.spyOn(console, 'error');
|
|
36
|
+
expect((await backend.search(new Float32Array([1, 0]), { k: 1 }))[0]).toMatchObject({
|
|
37
|
+
entry: { id: entry.id }, score: 1, distance: 0,
|
|
38
|
+
});
|
|
39
|
+
expect((await backend.getStats()).hnswStats).toBeUndefined();
|
|
40
|
+
expect((await backend.healthCheck()).components.index.status).toBe('degraded');
|
|
41
|
+
expect(errors.mock.calls.some(([message]) => String(message).includes('HNSW search failed'))).toBe(false);
|
|
42
|
+
}
|
|
43
|
+
finally {
|
|
44
|
+
await backend.shutdown();
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
//# sourceMappingURL=agentdb-backend-optional.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentdb-backend-optional.test.js","sourceRoot":"","sources":["../src/agentdb-backend-optional.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* AgentDB Backend - Integration with agentdb@
|
|
2
|
+
* AgentDB Backend - Integration with agentdb@3.0.0-alpha.20
|
|
3
3
|
*
|
|
4
4
|
* Provides IMemoryBackend implementation using AgentDB with:
|
|
5
|
-
* - HNSW vector search
|
|
6
|
-
* -
|
|
5
|
+
* - Optional native HNSW vector search through the real HNSWIndex export
|
|
6
|
+
* - Exact cosine fallback when native search is unavailable
|
|
7
7
|
* - Optional dependency handling (works without hnswlib-node)
|
|
8
8
|
* - Seamless integration with HybridBackend
|
|
9
9
|
*
|
|
@@ -22,7 +22,7 @@ export interface AgentDBBackendConfig {
|
|
|
22
22
|
namespace?: string;
|
|
23
23
|
/** Force WASM backend (skip native hnswlib) */
|
|
24
24
|
forceWasm?: boolean;
|
|
25
|
-
/**
|
|
25
|
+
/** AgentDB controller backend. Native memory search uses hnswlib in auto/hnswlib mode. */
|
|
26
26
|
vectorBackend?: 'auto' | 'ruvector' | 'hnswlib';
|
|
27
27
|
/** Vector dimensions (default: 1536) */
|
|
28
28
|
vectorDimension?: number;
|
|
@@ -50,11 +50,11 @@ export interface AgentDBBackendConfig {
|
|
|
50
50
|
* AgentDB Backend
|
|
51
51
|
*
|
|
52
52
|
* Integrates AgentDB for vector search with the V3 memory system.
|
|
53
|
-
*
|
|
53
|
+
* Native HNSW is an approximate search optimization, not a persistence layer.
|
|
54
54
|
*
|
|
55
55
|
* Features:
|
|
56
56
|
* - HNSW indexing for fast approximate nearest neighbor search
|
|
57
|
-
* -
|
|
57
|
+
* - Exact cosine fallback without native hnswlib, in forceWasm mode, or for filters
|
|
58
58
|
* - Graceful handling of optional native dependencies
|
|
59
59
|
* - Semantic search with filtering
|
|
60
60
|
* - Compatible with HybridBackend for combined SQLite+AgentDB queries
|
|
@@ -64,12 +64,12 @@ export declare class AgentDBBackend extends EventEmitter implements IMemoryBacke
|
|
|
64
64
|
private agentdb;
|
|
65
65
|
private initialized;
|
|
66
66
|
private available;
|
|
67
|
+
private hnsw?;
|
|
67
68
|
private readonly retrievalGuard;
|
|
68
69
|
private entries;
|
|
69
70
|
private namespaceIndex;
|
|
70
71
|
private keyIndex;
|
|
71
|
-
private
|
|
72
|
-
private stringToNumericIdMap;
|
|
72
|
+
private expiringEntryIds;
|
|
73
73
|
private stats;
|
|
74
74
|
constructor(config?: AgentDBBackendConfig);
|
|
75
75
|
/**
|
|
@@ -146,6 +146,7 @@ export declare class AgentDBBackend extends EventEmitter implements IMemoryBacke
|
|
|
146
146
|
* Health check
|
|
147
147
|
*/
|
|
148
148
|
healthCheck(): Promise<HealthCheckResult>;
|
|
149
|
+
private copyEntry;
|
|
149
150
|
/**
|
|
150
151
|
* Create database schema
|
|
151
152
|
*/
|
|
@@ -194,32 +195,11 @@ export declare class AgentDBBackend extends EventEmitter implements IMemoryBacke
|
|
|
194
195
|
* Convert DB row to MemoryEntry
|
|
195
196
|
*/
|
|
196
197
|
private rowToEntry;
|
|
198
|
+
private hasSearchFilters;
|
|
199
|
+
/** Apply semantic-search filters before selecting top-k, not after. */
|
|
200
|
+
private matchesFilters;
|
|
197
201
|
/**
|
|
198
|
-
*
|
|
199
|
-
*/
|
|
200
|
-
private stringIdToNumeric;
|
|
201
|
-
/**
|
|
202
|
-
* Pure hash function for string ID (no map lookup).
|
|
203
|
-
* Used by registerIdMapping for initial hash before collision probing.
|
|
204
|
-
*/
|
|
205
|
-
private hashStringId;
|
|
206
|
-
/**
|
|
207
|
-
* Convert numeric ID back to string using O(1) reverse lookup
|
|
208
|
-
* PERFORMANCE FIX: Uses pre-built reverse map instead of O(n) linear scan
|
|
209
|
-
*/
|
|
210
|
-
private numericIdToString;
|
|
211
|
-
/**
|
|
212
|
-
* Register string ID in reverse lookup map
|
|
213
|
-
* Called when storing entries to maintain bidirectional mapping
|
|
214
|
-
*/
|
|
215
|
-
private registerIdMapping;
|
|
216
|
-
/**
|
|
217
|
-
* Unregister string ID from reverse lookup map
|
|
218
|
-
* Called when deleting entries
|
|
219
|
-
*/
|
|
220
|
-
private unregisterIdMapping;
|
|
221
|
-
/**
|
|
222
|
-
* Cosine similarity (returns value in range [0, 1] where 1 = identical)
|
|
202
|
+
* Cosine similarity (returns value in range [-1, 1] where 1 = identical)
|
|
223
203
|
*/
|
|
224
204
|
private cosineSimilarity;
|
|
225
205
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agentdb-backend.d.ts","sourceRoot":"","sources":["../src/agentdb-backend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"agentdb-backend.d.ts","sourceRoot":"","sources":["../src/agentdb-backend.ts"],"names":[],"mappings":"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"}
|