#!/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); }); }