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