Merge Memory V2 runtime facade
This commit is contained in:
@@ -0,0 +1,161 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
import {
|
||||
parseMemoryV2SessionFlowArgs,
|
||||
runMemoryV2SessionFlowCli,
|
||||
} from './check-memory-v2-session-flow.mjs';
|
||||
|
||||
function writableBuffer() {
|
||||
let value = '';
|
||||
return {
|
||||
write(chunk) {
|
||||
value += String(chunk);
|
||||
},
|
||||
value() {
|
||||
return value;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function jsonResponse(body, { status = 200, headers = {} } = {}) {
|
||||
return {
|
||||
ok: status >= 200 && status < 300,
|
||||
status,
|
||||
headers: {
|
||||
get(name) {
|
||||
return headers[name.toLowerCase()] ?? headers[name] ?? null;
|
||||
},
|
||||
},
|
||||
async text() {
|
||||
return JSON.stringify(body);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function sseResponse(chunks) {
|
||||
const encoded = chunks.map((chunk) => new TextEncoder().encode(chunk));
|
||||
return {
|
||||
ok: true,
|
||||
status: 200,
|
||||
headers: {
|
||||
get() {
|
||||
return 'text/event-stream';
|
||||
},
|
||||
},
|
||||
body: new ReadableStream({
|
||||
start(controller) {
|
||||
for (const chunk of encoded) controller.enqueue(chunk);
|
||||
controller.close();
|
||||
},
|
||||
}),
|
||||
async text() {
|
||||
return '';
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
test('parseMemoryV2SessionFlowArgs maps session flow options', () => {
|
||||
assert.deepEqual(
|
||||
parseMemoryV2SessionFlowArgs([
|
||||
'--base-url',
|
||||
'http://127.0.0.1:18081/',
|
||||
'--prompt',
|
||||
'hello',
|
||||
'--expect-backend',
|
||||
'pgvector',
|
||||
'--expect-selected-backend',
|
||||
'pgvector',
|
||||
'--timeout-ms',
|
||||
'5000',
|
||||
]),
|
||||
{
|
||||
baseUrl: 'http://127.0.0.1:18081',
|
||||
prompt: 'hello',
|
||||
expectedBackend: 'pgvector',
|
||||
expectedSelectedBackend: 'pgvector',
|
||||
timeoutMs: 5000,
|
||||
help: false,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test('runMemoryV2SessionFlowCli passes against a mocked live session flow', async () => {
|
||||
const stdout = writableBuffer();
|
||||
const code = await runMemoryV2SessionFlowCli({
|
||||
argv: [
|
||||
'--base-url',
|
||||
'http://app.local',
|
||||
'--expect-backend',
|
||||
'pgvector',
|
||||
'--expect-selected-backend',
|
||||
'pgvector',
|
||||
],
|
||||
stdout,
|
||||
async fetchImpl(url, init = {}) {
|
||||
if (url.endsWith('/auth/register')) {
|
||||
return jsonResponse({ ok: true, user: { id: 'user-1' } });
|
||||
}
|
||||
if (url.endsWith('/auth/login')) {
|
||||
return jsonResponse(
|
||||
{ authenticated: true, user: { id: 'user-1' } },
|
||||
{ headers: { 'set-cookie': 'session=abc; Path=/; HttpOnly' } },
|
||||
);
|
||||
}
|
||||
if (url.endsWith('/api/agent/start')) {
|
||||
return jsonResponse({ id: 'session-1' });
|
||||
}
|
||||
if (url.endsWith('/api/sessions/session-1/events')) {
|
||||
return sseResponse([
|
||||
'id: 1\ndata: {"type":"Message","message":{"role":"assistant","content":[{"type":"text","text":"hi"}],"metadata":{"userVisible":true}}}\n\n',
|
||||
'id: 2\ndata: {"type":"Finish","reason":"stop"}\n\n',
|
||||
]);
|
||||
}
|
||||
if (url.endsWith('/api/agent/runs')) {
|
||||
assert.equal(init.method, 'POST');
|
||||
return jsonResponse({ run: { id: 'run-1' } }, { status: 202 });
|
||||
}
|
||||
if (url.endsWith('/api/sessions/session-1')) {
|
||||
return jsonResponse({
|
||||
conversation: [
|
||||
{
|
||||
role: 'user',
|
||||
metadata: { userVisible: true },
|
||||
content: [{ type: 'text', text: 'hello' }],
|
||||
},
|
||||
{
|
||||
role: 'assistant',
|
||||
metadata: { userVisible: true },
|
||||
content: [{ type: 'text', text: 'hi' }],
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
if (url.endsWith('/api/user-memory/v1/remember-recent')) {
|
||||
return jsonResponse({ ok: true, analyzed: 1, memories: 0, totalMemories: 0, syncedToSession: true });
|
||||
}
|
||||
if (url.endsWith('/api/user-memory/v1/sync')) {
|
||||
return jsonResponse({ ok: true, analyzed: 1, memories: 0, totalMemories: 0, syncedToSession: true });
|
||||
}
|
||||
if (url.endsWith('/api/runtime/status')) {
|
||||
return jsonResponse({
|
||||
ok: true,
|
||||
memory: {
|
||||
enabled: true,
|
||||
backend: 'pgvector',
|
||||
selectedBackend: 'pgvector',
|
||||
failOpen: true,
|
||||
vectorEnabled: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
throw new Error(`unexpected url ${url}`);
|
||||
},
|
||||
});
|
||||
const report = JSON.parse(stdout.value());
|
||||
|
||||
assert.equal(code, 0);
|
||||
assert.equal(report.ok, true);
|
||||
assert.equal(report.sessionId, 'session-1');
|
||||
assert.equal(report.runId, 'run-1');
|
||||
assert.equal(report.summary.runtimeMemory.selectedBackend, 'pgvector');
|
||||
});
|
||||
Reference in New Issue
Block a user