feat(memory-v2): close Phase A with auto-review, product events, and H5 recall UI.
Add candidate auto-review pipeline, shadow audit tooling, admin metrics page, and user-visible memory recall hints in chat with phase-a readiness checks. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env node
|
||||
import { pathToFileURL } from 'node:url';
|
||||
import { ensurePgvectorMemorySchema } from '../memory-v2-pgvector-schema.mjs';
|
||||
import { runPgvectorMemorySmoke } from '../memory-v2-pgvector-smoke.mjs';
|
||||
import { loadMemindEnvFiles } from './memind-runtime-profile.mjs';
|
||||
|
||||
function usage() {
|
||||
return [
|
||||
'Usage: node scripts/setup-memory-v2-pgvector-local.mjs [--dimensions 3] [--skip-smoke]',
|
||||
'',
|
||||
'Ensures local pgvector schema exists and runs a read/write smoke test.',
|
||||
].join('\n');
|
||||
}
|
||||
|
||||
function parseArgs(argv) {
|
||||
const args = { dimensions: 3, skipSmoke: false };
|
||||
for (let i = 2; i < argv.length; i += 1) {
|
||||
const arg = argv[i];
|
||||
if (arg === '--dimensions' && argv[i + 1]) args.dimensions = Number(argv[++i]);
|
||||
else if (arg === '--skip-smoke') args.skipSmoke = true;
|
||||
else if (arg === '--help' || arg === '-h') {
|
||||
console.log(usage());
|
||||
process.exit(0);
|
||||
} else {
|
||||
console.error(`Unknown argument: ${arg}`);
|
||||
console.error(usage());
|
||||
process.exit(2);
|
||||
}
|
||||
}
|
||||
return args;
|
||||
}
|
||||
|
||||
async function createPgPool(connectionString) {
|
||||
const imported = await import('pg');
|
||||
const PgPool = imported?.Pool ?? imported?.default?.Pool;
|
||||
if (typeof PgPool !== 'function') throw new Error('pg module does not export Pool');
|
||||
return new PgPool({ connectionString, max: 3 });
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const args = parseArgs(process.argv);
|
||||
loadMemindEnvFiles(process.cwd());
|
||||
const connectionString = String(process.env.MEMORY_PGVECTOR_DATABASE_URL ?? '').trim()
|
||||
|| 'postgresql://john@127.0.0.1:5432/memind_memory';
|
||||
const tableName = String(process.env.MEMORY_PGVECTOR_TABLE ?? 'memory_embeddings').trim()
|
||||
|| 'memory_embeddings';
|
||||
const pool = await createPgPool(connectionString);
|
||||
try {
|
||||
const schema = await ensurePgvectorMemorySchema(pool, {
|
||||
tableName,
|
||||
dimensions: args.dimensions,
|
||||
createExtension: true,
|
||||
});
|
||||
console.log(`pgvector schema ready: table=${schema.tableName} dimensions=${schema.dimensions}`);
|
||||
if (!args.skipSmoke) {
|
||||
const smoke = await runPgvectorMemorySmoke({
|
||||
pool,
|
||||
tableName,
|
||||
dimensions: args.dimensions,
|
||||
cleanup: true,
|
||||
embedQuery: async () => Array.from({ length: args.dimensions }, (_, index) => (index + 1) * 0.1),
|
||||
});
|
||||
console.log(`pgvector smoke: ${smoke.ok ? 'ok' : 'failed'} inserted=${smoke.inserted} queried=${smoke.queried}`);
|
||||
if (!smoke.ok) process.exit(1);
|
||||
}
|
||||
} finally {
|
||||
await pool.end();
|
||||
}
|
||||
}
|
||||
|
||||
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
||||
main().catch((err) => {
|
||||
console.error(err instanceof Error ? err.message : err);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user