feat(palace): extract KG triples from entities + refresh L1 cache on note save

After storing memories, generate subject-predicate-object triples from
entity pairs found in extracted memories. Also trigger L1 critical facts
cache regeneration so wake-up context stays fresh.
This commit is contained in:
saravanakumardb1 2026-04-13 12:33:16 -07:00
parent 18b680ad53
commit 06590b9175

View File

@ -9,8 +9,9 @@
import { config } from '../../lib/config.js';
import { embedText, stripHtmlForEmbedding } from '../../lib/embeddings.js';
import { trackEvent } from '../../lib/telemetry.js';
import { ensureWing, ensureRoom, storeMemory, isNearDuplicate } from './repository.js';
import { ensureWing, ensureRoom, storeMemory, isNearDuplicate, addTriple } from './repository.js';
import { extractMemories } from './extractor.js';
import { regenerateCriticalFacts } from './wakeup.js';
import type { NoteDoc } from '../notes/types.js';
import type { FastifyBaseLogger } from 'fastify';
@ -61,13 +62,32 @@ export async function onNoteSavedToPalace(
}
if (stored > 0) {
// Extract KG triples from entities found in memories
let triplesStored = 0;
for (const mem of memories) {
if (mem.entities.length >= 2) {
for (let i = 0; i < mem.entities.length - 1; i++) {
await addTriple(
userId, productId, wing.id,
mem.entities[i], `related_via_${mem.hall}`, mem.entities[i + 1],
0.7, note.id,
).catch(() => {});
triplesStored++;
}
}
}
// Refresh L1 critical facts cache
void regenerateCriticalFacts(userId, productId, wing.id).catch(() => {});
trackEvent('palace.memories_extracted', userId, {
noteId: note.id,
wingId: wing.id,
stored: String(stored),
skippedDup: String(skippedDup),
triples: String(triplesStored),
});
log.info({ noteId: note.id, stored, skippedDup }, 'palace: memories extracted from note');
log.info({ noteId: note.id, stored, skippedDup, triplesStored }, 'palace: memories + triples extracted from note');
}
} catch (err) {
log.warn({ noteId: note.id, err }, 'palace: memory extraction failed');