feat(palace): add LLM memory extractor with regex fallback

This commit is contained in:
saravanakumardb1 2026-04-10 01:16:55 -07:00
parent 44d8867aa5
commit 13020bc72f

View File

@ -0,0 +1,73 @@
import {
buildExtractionPrompt,
parseExtractionResponse,
regexFallbackExtraction,
hallFromLabel,
HALL_PRESETS,
} from '@bytelyst/palace';
import type { ExtractedMemory } from '@bytelyst/palace';
import { llm } from '../../lib/llm.js';
import { config } from '../../lib/config.js';
import { HALL_TYPES } from './types.js';
import type { HallType } from './types.js';
export type { ExtractedMemory };
const NOTELETT_HALLS = HALL_PRESETS.notelett?.halls ?? HALL_TYPES;
export interface NoteLettExtractedMemory {
hall: HallType;
content: string;
roomSlug: string;
entities: string[];
}
/**
* Extract memories from note content using LLM with regex fallback.
*
* Uses @bytelyst/palace shared extraction prompt builder + parser.
* Falls back to regex extraction if LLM is unavailable or fails.
*/
export async function extractMemories(
noteBody: string,
noteTitle: string,
workspaceName: string,
): Promise<NoteLettExtractedMemory[]> {
if (!config.PALACE_EXTRACTION_ENABLED) return [];
if (!noteBody || noteBody.trim().length === 0) return [];
const content = noteBody.slice(0, 6000);
const prompt = buildExtractionPrompt(content, {
title: noteTitle,
context: workspaceName,
hallTypes: NOTELETT_HALLS,
});
let rawMemories: ExtractedMemory[];
try {
const provider = llm();
const result = await provider.chatCompletion({
model: config.LLM_DEFAULT_MODEL,
messages: [{ role: 'user', content: prompt }],
temperature: 0.1,
});
rawMemories = parseExtractionResponse(result.content);
} catch {
rawMemories = regexFallbackExtraction(content);
}
// Map to NoteLett halls, filtering out any that don't match
return rawMemories
.map(mem => {
const mappedHall = hallFromLabel(mem.hall, NOTELETT_HALLS as unknown as HallType[]) as HallType | undefined;
if (!mappedHall) return null;
return {
hall: mappedHall,
content: mem.content,
roomSlug: mem.roomSlug || 'general',
entities: mem.entities || [],
};
})
.filter((m): m is NoteLettExtractedMemory => m !== null);
}