Merge Memory V2 runtime facade
This commit is contained in:
@@ -0,0 +1,175 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
import {
|
||||
parseMemoryV2ExternalSmokeArgs,
|
||||
runMemoryV2ExternalSmokeCli,
|
||||
} from './smoke-memory-v2-external.mjs';
|
||||
|
||||
function writableBuffer() {
|
||||
let value = '';
|
||||
return {
|
||||
write(chunk) {
|
||||
value += String(chunk);
|
||||
},
|
||||
value() {
|
||||
return value;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
test('parseMemoryV2ExternalSmokeArgs validates backend and defaults operation', () => {
|
||||
assert.deepEqual(
|
||||
parseMemoryV2ExternalSmokeArgs(['--backend', 'redis-streams']),
|
||||
{
|
||||
backend: 'redis-streams',
|
||||
operation: 'write',
|
||||
query: 'memory-chain smoke',
|
||||
limit: 1,
|
||||
vector: null,
|
||||
userId: 'memory-v2-smoke-user',
|
||||
sessionId: 'memory-v2-smoke-session',
|
||||
help: false,
|
||||
},
|
||||
);
|
||||
assert.deepEqual(
|
||||
parseMemoryV2ExternalSmokeArgs([
|
||||
'--backend',
|
||||
'weaviate',
|
||||
'--operation',
|
||||
'resolve',
|
||||
'--vector',
|
||||
'0.1,0.2',
|
||||
'--limit',
|
||||
'2',
|
||||
]).vector,
|
||||
[0.1, 0.2],
|
||||
);
|
||||
assert.throws(
|
||||
() => parseMemoryV2ExternalSmokeArgs(['--backend', 'unknown']),
|
||||
/--backend must be one of/,
|
||||
);
|
||||
});
|
||||
|
||||
test('runMemoryV2ExternalSmokeCli smokes Qdrant through runtime HTTP wiring', async () => {
|
||||
const stdout = writableBuffer();
|
||||
const report = await runMemoryV2ExternalSmokeCli({
|
||||
argv: ['--backend', 'qdrant', '--operation', 'resolve', '--limit', '2'],
|
||||
env: {
|
||||
MEMORY_QDRANT_ENABLED: '1',
|
||||
MEMORY_QDRANT_URL: 'http://qdrant.local',
|
||||
MEMORY_QDRANT_COLLECTION: 'memind_memory',
|
||||
MEMORY_QDRANT_EMBEDDING_MODULE: './embed.mjs',
|
||||
},
|
||||
stdout,
|
||||
async importModule() {
|
||||
return { async embedQuery() { return [0.1, 0.2, 0.3]; } };
|
||||
},
|
||||
async fetchImpl(url, options) {
|
||||
assert.equal(url, 'http://qdrant.local/collections/memind_memory/points/search');
|
||||
assert.equal(JSON.parse(options.body).limit, 2);
|
||||
return {
|
||||
ok: true,
|
||||
async json() {
|
||||
return {
|
||||
result: [
|
||||
{
|
||||
id: 'q1',
|
||||
score: 0.9,
|
||||
payload: { content: 'semantic memory', type: 'semantic' },
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
const output = JSON.parse(stdout.value());
|
||||
|
||||
assert.equal(report.backendAvailable, true);
|
||||
assert.equal(output.selectedBackend, 'qdrant');
|
||||
assert.equal(output.result.source, 'qdrant');
|
||||
});
|
||||
|
||||
test('runMemoryV2ExternalSmokeCli smokes Weaviate through runtime HTTP wiring', async () => {
|
||||
const stdout = writableBuffer();
|
||||
const report = await runMemoryV2ExternalSmokeCli({
|
||||
argv: ['--backend', 'weaviate', '--operation', 'resolve', '--limit', '2'],
|
||||
env: {
|
||||
MEMORY_WEAVIATE_ENABLED: '1',
|
||||
MEMORY_WEAVIATE_URL: 'https://weaviate.local',
|
||||
MEMORY_WEAVIATE_EMBEDDING_MODULE: './embed.mjs',
|
||||
},
|
||||
stdout,
|
||||
async importModule() {
|
||||
return { async embedQuery() { return [0.1, 0.2]; } };
|
||||
},
|
||||
async fetchImpl(url, options) {
|
||||
assert.equal(url, 'https://weaviate.local/v1/graphql');
|
||||
assert.equal(JSON.parse(options.body).variables.limit, 2);
|
||||
return {
|
||||
ok: true,
|
||||
async json() {
|
||||
return {
|
||||
data: {
|
||||
Get: {
|
||||
MemindMemory: [{ content: 'semantic memory', _additional: { id: 'w1' } }],
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
const output = JSON.parse(stdout.value());
|
||||
|
||||
assert.equal(report.backendAvailable, true);
|
||||
assert.equal(output.selectedBackend, 'weaviate');
|
||||
assert.equal(output.result.source, 'weaviate');
|
||||
});
|
||||
|
||||
test('runMemoryV2ExternalSmokeCli smokes Redis Streams with injected redis module', async () => {
|
||||
const stdout = writableBuffer();
|
||||
const xAdds = [];
|
||||
let quitCalled = false;
|
||||
const report = await runMemoryV2ExternalSmokeCli({
|
||||
argv: ['--backend', 'redis-streams'],
|
||||
env: {
|
||||
MEMORY_REDIS_STREAMS_ENABLED: '1',
|
||||
MEMORY_REDIS_STREAMS_URL: 'redis://localhost:6379',
|
||||
},
|
||||
stdout,
|
||||
async importRedis() {
|
||||
return {
|
||||
createClient() {
|
||||
return {
|
||||
async connect() {},
|
||||
async xAdd(stream, id, fields) {
|
||||
xAdds.push({ stream, id, fields });
|
||||
},
|
||||
async quit() {
|
||||
quitCalled = true;
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
assert.equal(report.backendAvailable, true);
|
||||
assert.equal(report.result.source, 'redis-streams');
|
||||
assert.equal(xAdds[0].stream, 'memind:memory-events');
|
||||
assert.equal(quitCalled, true);
|
||||
});
|
||||
|
||||
test('runMemoryV2ExternalSmokeCli reports fallback when backend is not configured', async () => {
|
||||
const stdout = writableBuffer();
|
||||
const report = await runMemoryV2ExternalSmokeCli({
|
||||
argv: ['--backend', 'langgraph'],
|
||||
env: {},
|
||||
stdout,
|
||||
});
|
||||
|
||||
assert.equal(report.backendAvailable, false);
|
||||
assert.equal(report.selectedBackend, 'legacy-conversation-memory');
|
||||
assert.equal(report.backendReason, 'not_configured');
|
||||
});
|
||||
Reference in New Issue
Block a user