Merge Memory V2 runtime facade
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
import { createMemoryV2 } from './memory-v2.mjs';
|
||||
import { createPgvectorMemoryBackend } from './memory-v2-pgvector.mjs';
|
||||
|
||||
test('pgvector backend is disabled by default and does not query storage', async () => {
|
||||
let queried = false;
|
||||
const backend = createPgvectorMemoryBackend({
|
||||
pool: {
|
||||
async query() {
|
||||
queried = true;
|
||||
return { rows: [] };
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
assert.equal(backend.isAvailable(), false);
|
||||
assert.deepEqual(await backend.resolve({
|
||||
userId: 'user-1',
|
||||
embedding: [0.1, 0.2],
|
||||
}), {
|
||||
memories: [],
|
||||
semanticMemories: [],
|
||||
});
|
||||
assert.equal(queried, false);
|
||||
});
|
||||
|
||||
test('pgvector backend returns empty semantic result when embedding is unavailable', async () => {
|
||||
let queried = false;
|
||||
const backend = createPgvectorMemoryBackend({
|
||||
enabled: true,
|
||||
pool: {
|
||||
async query() {
|
||||
queried = true;
|
||||
return { rows: [] };
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const result = await backend.resolve({
|
||||
userId: 'user-1',
|
||||
query: 'memory-chain',
|
||||
});
|
||||
|
||||
assert.deepEqual(result, {
|
||||
memories: [],
|
||||
semanticMemories: [],
|
||||
});
|
||||
assert.equal(queried, false);
|
||||
});
|
||||
|
||||
test('pgvector backend performs parameterized vector lookup when explicitly enabled', async () => {
|
||||
const queries = [];
|
||||
const backend = createPgvectorMemoryBackend({
|
||||
enabled: true,
|
||||
tableName: 'memory_embeddings',
|
||||
pool: {
|
||||
async query(sql, params) {
|
||||
queries.push({ sql, params });
|
||||
return {
|
||||
rows: [
|
||||
{
|
||||
id: 7,
|
||||
content: '用户关注 Memory V2 的 facade 边界',
|
||||
type: 'fact',
|
||||
score: '0.87',
|
||||
created_at: '2026-07-02T00:00:00.000Z',
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
},
|
||||
embedQuery: async (query) => {
|
||||
assert.equal(query, 'memory-chain');
|
||||
return [0.25, 0.5, 0.75];
|
||||
},
|
||||
});
|
||||
|
||||
assert.equal(backend.isAvailable(), true);
|
||||
const result = await backend.resolve({
|
||||
userId: 'user-1',
|
||||
query: 'memory-chain',
|
||||
limit: 5,
|
||||
});
|
||||
|
||||
assert.equal(queries.length, 1);
|
||||
assert.match(queries[0].sql, /FROM memory_embeddings/);
|
||||
assert.deepEqual(queries[0].params, ['user-1', '[0.25,0.5,0.75]', 5]);
|
||||
assert.deepEqual(result.semanticMemories, ['用户关注 Memory V2 的 facade 边界']);
|
||||
assert.deepEqual(result.memories, [
|
||||
{
|
||||
id: '7',
|
||||
label: 'fact',
|
||||
text: '用户关注 Memory V2 的 facade 边界',
|
||||
score: 0.87,
|
||||
createdAt: '2026-07-02T00:00:00.000Z',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
test('pgvector backend validates table names before building SQL', () => {
|
||||
assert.throws(
|
||||
() => createPgvectorMemoryBackend({ tableName: 'memory_embeddings;DROP TABLE users' }),
|
||||
/Invalid pgvector table name/,
|
||||
);
|
||||
});
|
||||
|
||||
test('Memory V2 can expose pgvector as unavailable plugin without selecting it', async () => {
|
||||
const memory = createMemoryV2({
|
||||
logger: { warn() {} },
|
||||
backends: [
|
||||
createPgvectorMemoryBackend({ enabled: false }),
|
||||
{
|
||||
name: 'legacy-conversation-memory',
|
||||
async resolve() {
|
||||
return { memories: [{ label: 'fact', text: 'legacy survives' }] };
|
||||
},
|
||||
},
|
||||
],
|
||||
env: {
|
||||
MEMORY_ENABLED: '1',
|
||||
MEMORY_BACKEND: 'pgvector',
|
||||
MEMORY_VECTOR_ENABLED: '1',
|
||||
},
|
||||
});
|
||||
|
||||
const status = memory.getStatus();
|
||||
const result = await memory.resolve({ userId: 'user-1', query: 'memory-chain' });
|
||||
|
||||
assert.equal(status.vectorEnabled, true);
|
||||
assert.equal(status.selectedBackend, 'legacy-conversation-memory');
|
||||
assert.equal(status.backends.find((item) => item.name === 'pgvector')?.available, false);
|
||||
assert.deepEqual(result.memories, [{ label: 'fact', text: 'legacy survives' }]);
|
||||
});
|
||||
Reference in New Issue
Block a user