import type { EngineerContext, Collision, Intervention, InterventionOutcome } from '@podman/shared'; import { collections } from './db.js'; import { enrichCollisionMemory } from './vectors.js'; /** * Continual-learning memory: persist observations, collisions, interventions, * and outcomes to MongoDB so later sessions get sharper. Writes are best-effort * — a Mongo hiccup logs a warning rather than crashing the agent/server. */ async function persist(name: string, fn: () => Promise): Promise { try { await fn(); } catch (err) { console.warn(`[memory] ${name} persist failed: ${(err as Error).message}`); } } export async function recordObservation(ctx: EngineerContext): Promise { await persist('observation', async () => (await collections()).observations.insertOne({ ...ctx }), ); } export async function recordCollision(collision: Collision): Promise { await persist('collision', async () => (await collections()).collisions.insertOne(await enrichCollisionMemory(collision)), ); } export async function recordIntervention(intervention: Intervention): Promise { await persist('intervention', async () => (await collections()).interventions.insertOne({ ...intervention }), ); } export async function recordOutcome(outcome: InterventionOutcome): Promise { await persist('outcome', async () => (await collections()).outcomes.insertOne({ ...outcome })); } /** Document counts per collection — used by the /api/memory/stats endpoint. */ export async function memoryStats(): Promise> { const c = await collections(); const [observations, collisions, interventions, outcomes] = await Promise.all([ c.observations.estimatedDocumentCount(), c.collisions.estimatedDocumentCount(), c.interventions.estimatedDocumentCount(), c.outcomes.estimatedDocumentCount(), ]); return { observations, collisions, interventions, outcomes }; }