/** * Transcript Selection — choosing WHICH messages a regen distiller reads. * * Deliberately dependency-free and side-effect-free: no CMS, no artifact * store, no clock, no randomness. It takes an array of messages and returns * a selection. That makes it testable in isolation (fixtures + an LLM-judge * suite) without standing up a session, and keeps it safe to call from a * durable activity, where a retry must reproduce the identical result. * * The default strategy is EXCHANGE-CLUSTERED salience: * * A long agent transcript is mostly assistant self-talk — status pings, * cron re-arms, "no new signal" cycle reports. The parts that carry intent * are the exchanges: a user says something and the agent responds, possibly * over several turns. Those clusters are what a resumed session needs; the * unattached machinery between them is what it can afford to lose. * * So salience is defined structurally rather than lexically: distance to * the nearest user message. No keyword lists to tune, no model call, and it * degrades sensibly on transcripts with few user messages (it simply keeps * more of the surrounding context per exchange). */ /** A transcript message as the selector sees it. */ export interface SelectableMessage { /** Monotonic order key (CMS seq). Ties break on array position. */ seq: number; /** Only "user" and "assistant" participate; "system" is dropped up front. */ role: "user" | "assistant" | "system"; /** Message text; used for size accounting only. */ text: string; } export interface SelectionOptions { /** Total messages to keep. Default 1000. */ budget?: number; /** * Split of the budget between the head and tail halves of the * transcript. Default 0.5 — first 500 / last 500 at a 1000 budget. */ headFraction?: number; /** * How many messages after a user message still count as part of that * exchange (the agent's reply may span several turns). Default 6. */ exchangeWindow?: number; } export interface SelectionElision { /** Selected message this gap follows (null = gap precedes everything kept). */ afterSeq: number | null; /** How many messages were dropped. */ count: number; /** Inclusive seq range of the dropped run. */ span: [number, number]; } export interface SelectionResult { /** Chosen messages, chronological. */ selected: SelectableMessage[]; /** Gaps between kept messages, so the distiller never infers continuity. */ elisions: SelectionElision[]; strategy: string; stats: { inputTotal: number; systemDropped: number; eligible: number; selectedCount: number; headSelected: number; tailSelected: number; userKept: number; droppedCount: number; }; } export interface TranscriptSelectionStrategy { readonly name: string; describe(): string; select(messages: SelectableMessage[], options?: SelectionOptions): SelectionResult; } /** * Salience = proximity to a user message, scored on the eligible (non-system) * sequence. A user message scores highest; an assistant message scores by how * close it sits to the user message it answers. * * Messages AFTER a user message score higher than messages before it at the * same distance: the reply to a question is the substance, whereas the turns * preceding a question are usually the routine the user interrupted. */ export declare function scoreByExchangeProximity(messages: SelectableMessage[], exchangeWindow?: number): number[]; /** * Exchange-clustered selection: drop system messages, split the remainder in * half, and fill each half with its most salient messages — first N from the * head, last N from the tail. */ export declare const exchangeClusteredStrategy: TranscriptSelectionStrategy; export declare function registerSelectionStrategy(strategy: TranscriptSelectionStrategy): void; export declare function resolveSelectionStrategy(name?: string): TranscriptSelectionStrategy; export declare function listSelectionStrategies(): TranscriptSelectionStrategy[]; /** Convenience wrapper: resolve by name and run. */ export declare function selectTranscript(messages: SelectableMessage[], options?: SelectionOptions & { strategy?: string; }): SelectionResult; //# sourceMappingURL=transcript-selection.d.ts.map