import type { ChatMessage, CompletionRequest, ProviderId, SuccessfulRequestSnapshot } from "../types.js"; import type { OperationLedger } from "../llm/operation-ledger.js"; import { type RequestAccounting } from "./request-accounting.js"; /** The assembled snapshot-replay request cannot fit the effective safe limit. */ export declare class CompactionOverLimitError extends Error { readonly requestTokens: number; readonly effectiveSafeTokens: number | undefined; constructor(message: string, requestTokens: number, effectiveSafeTokens: number | undefined); } export declare function isCompactionOverLimitError(error: unknown): error is CompactionOverLimitError; export interface CompactionSummaryExecution { readonly provider: ProviderId | undefined; readonly model: string | undefined; readonly systemContent: string; readonly prompt: string; readonly maxTokens: number; readonly signal?: AbortSignal | undefined; readonly sourceMessages?: readonly ChatMessage[] | undefined; readonly baseRequest?: SuccessfulRequestSnapshot | undefined; readonly history?: readonly ChatMessage[] | undefined; readonly contextLimitTokens?: number | undefined; readonly tools?: CompletionRequest["tools"] | undefined; readonly allowModelFallback?: boolean | undefined; readonly stream: boolean; readonly retryOnServerError?: boolean | undefined; /** Backoff before the error retry; defaults to COMPACTION_ERROR_RETRY_DELAY_MS. */ readonly retryDelayMs?: number | undefined; readonly qualityRetry?: boolean | undefined; readonly operation?: OperationLedger | undefined; readonly onToken?: ((text: string, replace?: boolean) => void) | undefined; } /** * The cache-preserving compaction request: the exact messages of the last * successful turn request, any history messages appended since, then the * compaction instruction as the final user turn. The previous prompt is a * strict prefix of this request, so APC providers serve it entirely from * cache and only the tail + instruction bill as fresh input. */ export declare function buildCompactionReplayMessages(baseRequest: SuccessfulRequestSnapshot, history: readonly ChatMessage[], userPrompt: string): ChatMessage[]; export interface CompactionReplayPlan { readonly messages: ChatMessage[]; readonly accounting: RequestAccounting; readonly continuationAccounting: RequestAccounting; } /** * Pre-flight the snapshot-replay request without dispatching it. Returns * undefined when the snapshot is not a usable prefix base for the live * history; otherwise the replay messages and their serialized-request * accounting, so the caller can pick the cache-preserving strategy only when * the request actually fits (`!plan.accounting.overLimit`). The accounting * reserves the summary completion budget and adds planner slack for the * durable-state detail the final instruction prompt gains later. * * Replay compatibility: identical heads are the common case (the snapshot was * captured from this session's live message array). History restored from * disk drops the composed system head, so a headless history is accepted when * its messages still match into the snapshot's body. Anything else means the * snapshot belongs to a different lineage (provider/model switch, rewound or * replaced history) and replaying it would resurrect dropped messages. */ export declare function planCompactionReplay(input: { readonly baseRequest: SuccessfulRequestSnapshot; readonly history: readonly ChatMessage[]; readonly prompt: string; readonly maxTokens: number; readonly contextLimitTokens?: number | undefined; readonly stream?: boolean | undefined; }): CompactionReplayPlan | undefined; export declare function executeCompactionSummary(execution: CompactionSummaryExecution): Promise;