/** * Pure content utilities for the Hindsight backend. * * Ports the semantics of the upstream OpenCode plugin * (vectorize-io/hindsight @ hindsight-integrations/opencode/src/content.ts): * - tag stripping for anti-feedback (a recalled block must * never end up retained as a new memory) * - recall query composition + truncation under a character budget * - retention transcript framing */ export interface HindsightMessage { role: string; content: string; } export interface RecallResultLike { text: string; type?: string | null; mentioned_at?: string | null; } /** * Strip ``, ``, and legacy memory blocks. * * Both `` (per-turn recall) and `` (curated semantic * memory) are injected into the system prompt. If either leaks into the * retention transcript, every retain becomes a tighter feedback loop — * paraphrased memories feed the next consolidation, which feeds the next * mental-model refresh, which feeds the next retain. Always strip before * retaining. */ export declare function stripMemoryTags(content: string): string; /** Format recall results into a bullet list for context injection. */ export declare function formatMemories(results: RecallResultLike[]): string; /** Format current UTC time for the recall preamble. */ export declare function formatCurrentTime(now?: Date): string; /** * Slice messages to the last N turns, where a turn boundary is a user message. * Returns the trailing tail starting at the (N-th from the end) user message. */ export declare function sliceLastTurnsByUserBoundary(messages: HindsightMessage[], turns: number): HindsightMessage[]; /** * Compose a recall query from the latest user prompt plus optional prior context. * * When `recallContextTurns <= 1` the query is just the trimmed latest prompt. * Otherwise we prepend a `Prior context:` block built from the trailing * `recallContextTurns` user-bounded turns (memory tags stripped, latest prompt * suppressed to avoid duplicating it inside the context block). */ export declare function composeRecallQuery(latestQuery: string, messages: HindsightMessage[], recallContextTurns: number): string; /** * Truncate a composed recall query to `maxChars`. * * Always preserves the latest user message. Drops oldest context lines first * and degrades gracefully when even the latest message exceeds the budget. */ export declare function truncateRecallQuery(query: string, latestQuery: string, maxChars: number): string; export interface RetentionTranscript { transcript: string | null; messageCount: number; } /** * Format messages into a retention transcript using `[role: ...]` markers. * * - When `retainFullWindow` is true, all messages are included (used when the * caller pre-sliced the window itself). * - Otherwise, only the last user turn (last user message → end) is retained. * * Messages are tag-stripped before framing to break the recall→retain loop. * Returns `{ transcript: null }` when nothing meaningful survives. */ export declare function prepareRetentionTranscript(messages: HindsightMessage[], retainFullWindow?: boolean): RetentionTranscript;