Files
readest/apps/readest-app/src/services/reedy/context/layers/MemoryLayers.ts
T

58 lines
1.7 KiB
TypeScript

import type { PromptLayer } from './types';
/**
* Memory layers — placeholders for Phase 3. Each takes a `provider()`
* callback so Phase 3's MemoryService implementations can plug in without
* touching this file or the builder. Today the providers usually return
* empty strings; the layer renders null in that case and the builder
* skips it.
*
* Shrink priorities per plan §2.5:
* ToolCatalog (10) → Reading (20) → BookMemory (30) → UserMemory (40).
*
* Both memory layers are expendable but BookMemory shrinks first because
* book-specific facts are more easily re-derived (lookupPassage can
* rebuild them) than user-stable preferences.
*/
export type MemoryProvider = () => string;
export function createBookMemoryLayer(provider: MemoryProvider): PromptLayer {
return memoryLayer('bookMemory', 40, 30, 'Book memory', provider);
}
export function createUserMemoryLayer(provider: MemoryProvider): PromptLayer {
return memoryLayer('userMemory', 50, 40, 'User memory', provider);
}
function memoryLayer(
name: string,
renderPriority: number,
shrinkPriority: number,
headline: string,
provider: MemoryProvider,
): PromptLayer {
return {
name,
renderPriority,
shrinkPriority,
expendable: true,
render() {
const body = provider().trim();
return body.length > 0 ? `${headline}:\n${body}` : null;
},
shrink(level) {
const body = provider().trim();
if (body.length === 0) return null;
if (level <= 0) return `${headline}:\n${body}`;
if (level === 1) return `${headline}: ${truncateForTerse(body)}`;
return null;
},
};
}
function truncateForTerse(s: string): string {
const max = 200;
return s.length <= max ? s : `${s.slice(0, max - 1)}…`;
}