feat(memory-v2): restore personal shadow pipeline and candidate store

Recover WIP modules from stash so admin can persist capability config,
observe chat writes in shadow mode, and review persisted candidates.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-07-13 13:59:51 +08:00
parent 249b0697cb
commit e90a2da6cb
9 changed files with 773 additions and 1 deletions
+47
View File
@@ -0,0 +1,47 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import {
buildPersonalMemoryCandidateSchemaSql,
createPersonalMemoryCandidateStore,
ensurePersonalMemoryCandidateSchema,
} from './memory-v2-personal-store.mjs';
test('candidate schema is explicit and idempotent', async () => {
const calls = [];
const pool = { async query(sql, params) { calls.push({ sql, params }); return [[], []]; } };
await ensurePersonalMemoryCandidateSchema(pool);
assert.match(calls[0].sql, /CREATE TABLE IF NOT EXISTS/);
assert.match(calls[0].sql, /h5_memory_v2_candidates/);
assert.throws(() => buildPersonalMemoryCandidateSchemaSql({ table: 'bad-name' }), /Invalid/);
});
test('candidate store saves, lists, counts, and reviews with parameterized SQL', async () => {
const calls = [];
const pool = {
async query(sql, params = []) {
calls.push({ sql, params });
if (sql.startsWith('INSERT')) return [{ affectedRows: 1 }, []];
if (sql.startsWith('SELECT *')) return [[{
id: 'pmc_1', user_id: 'u1', session_id: 's1', memory_type: 'episodic',
content: '决定使用 main 发布', importance: '0.9', confidence: '0.9', status: 'candidate',
policy_reason: 'decision_signal', evidence_json: '{"sourceId":"s1:0"}',
reviewed_by: null, reviewed_at: null, created_at: 1, updated_at: 1,
}], []];
if (sql.startsWith('SELECT status')) return [[{ status: 'candidate', count: 1 }], []];
if (sql.startsWith('UPDATE')) return [{ affectedRows: 1 }, []];
throw new Error(`Unexpected SQL: ${sql}`);
},
};
const store = createPersonalMemoryCandidateStore(pool, { now: () => 10 });
assert.deepEqual(await store.saveCandidate({
id: 'pmc_1', userId: 'u1', sessionId: 's1', memoryType: 'episodic',
content: '决定使用 main 发布', importance: 0.9, confidence: 0.9,
policyReason: 'decision_signal', evidence: { sourceId: 's1:0' }, createdAt: 1,
}), { inserted: true });
const rows = await store.listCandidates({ limit: 20 });
assert.equal(rows[0].evidence.sourceId, 's1:0');
assert.deepEqual(await store.countByStatus(), { candidate: 1 });
assert.equal((await store.reviewCandidate('pmc_1', 'accepted', { reviewedBy: 'admin-1' })).updated, true);
assert.ok(calls.every((call) => !call.sql.includes('admin-1')));
});