feat(palace): add LLM memory extractor with regex fallback
This commit is contained in:
parent
44d8867aa5
commit
13020bc72f
73
backend/src/modules/palace/extractor.ts
Normal file
73
backend/src/modules/palace/extractor.ts
Normal 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);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user