export interface CompressibleMessage {
    role: string;
    content?: string | unknown;
    tool_call_id?: string;
    tool_calls?: unknown;
    name?: string;
}
export interface CompressionResult {
    messages: CompressibleMessage[];
    droppedCount: number;
    strategy: string;
    /** Phase 4: optional metrics from the compression pass */
    metrics?: CompressionMetrics;
}
export interface CompressionMetrics {
    tokensBefore: number;
    tokensAfter: number;
    compressionRatio: number;
    /** ms elapsed for this strategy pass */
    latencyMs: number;
    /** Whether an LLM call was made during this pass */
    usedLlm: boolean;
    /** Whether prompt cache was invalidated by compression */
    cacheInvalidated?: boolean;
}
export interface CompressionStrategy {
    compress(messages: CompressibleMessage[], budget: number): CompressionResult;
}
/**
 * Async compression strategy — required for LLM-based summarization.
 * Falls back to sync `compress` when the caller doesn't support async.
 */
export interface AsyncCompressionStrategy extends CompressionStrategy {
    compressAsync(messages: CompressibleMessage[], budget: number): Promise<CompressionResult>;
}
export declare function isAsyncCompressionStrategy(s: CompressionStrategy): s is AsyncCompressionStrategy;
/** Caller-provided LLM summarization function (wired by Hub). */
export type SummarizeFn = (messages: CompressibleMessage[], instruction: string) => Promise<string>;
export declare class SlidingWindowStrategy implements CompressionStrategy {
    private estimateTokens;
    constructor(estimateTokens: (msg: CompressibleMessage) => number);
    compress(messages: CompressibleMessage[], budget: number): CompressionResult;
}
export declare class SummarizeOldStrategy implements CompressionStrategy {
    private recentCount;
    private summarize;
    constructor(recentCount: number, summarize: (messages: CompressibleMessage[]) => string);
    compress(messages: CompressibleMessage[], _budget: number): CompressionResult;
}
export declare class ToolResultTrimStrategy implements CompressionStrategy {
    private maxToolResultChars;
    constructor(maxToolResultChars?: number);
    compress(messages: CompressibleMessage[], _budget: number): CompressionResult;
}
export declare function composeStrategies(...strategies: CompressionStrategy[]): CompressionStrategy;
/**
 * Compose strategies with async support — if any strategy is async,
 * the pipeline becomes async.
 */
export declare function composeAsyncStrategies(...strategies: CompressionStrategy[]): AsyncCompressionStrategy;
/**
 * Build the structured 9-section summary instruction for the LLM.
 * Based on Claude Code's Full Compact mode, adapted for Hub.
 */
export declare function buildStructuredSummaryPrompt(messagesToSummarize: CompressibleMessage[], opts?: {
    taskContext?: string;
}): string;
export interface HeadTailProtectionConfig {
    /** Number of initial user-assistant exchanges to protect (default: 1) */
    protectedHeadExchanges: number;
    /** Number of recent messages to always keep (default: 8 = ~4 exchanges) */
    protectedTailMessages: number;
    /** The summarization callback */
    summarize: SummarizeFn;
    /** Optional token estimator */
    estimateTokens?: (msg: CompressibleMessage) => number;
    /** Optional extra context for the summary prompt */
    taskContext?: string;
}
/**
 * Phase 2.2: Head/Tail protected summarization.
 *
 * Protects: system messages + first exchange + last N messages.
 * Compresses: middle section via LLM summarization.
 */
export declare class HeadTailProtectedStrategy implements AsyncCompressionStrategy {
    private config;
    constructor(config: HeadTailProtectionConfig);
    compress(messages: CompressibleMessage[], _budget: number): CompressionResult;
    compressAsync(messages: CompressibleMessage[], budget: number): Promise<CompressionResult>;
}
export interface IncrementalCompactConfig {
    /** Messages newer than this count are never summarized (default: 12) */
    preserveRecentCount: number;
    /** Summarization callback */
    summarize: SummarizeFn;
    /** Token estimator */
    estimateTokens?: (msg: CompressibleMessage) => number;
}
/**
 * Phase 2.3: Incremental (partial) compaction.
 *
 * Only summarizes the oldest messages beyond the preserve window.
 * Avoids repeatedly re-summarizing already-compressed content.
 * If a previous summary marker exists, only new old messages are compressed.
 */
export declare class IncrementalCompactStrategy implements AsyncCompressionStrategy {
    private config;
    constructor(config: IncrementalCompactConfig);
    compress(messages: CompressibleMessage[], _budget: number): CompressionResult;
    compressAsync(messages: CompressibleMessage[], budget: number): Promise<CompressionResult>;
}
export interface CacheAwareCompressionConfig {
    /** The inner strategy to delegate to */
    inner: CompressionStrategy;
    /** Token estimator */
    estimateTokens?: (msg: CompressibleMessage) => number;
    /**
     * Callback: notify when prompt cache was invalidated by compression.
     * Hub uses this to set pendingPostCompaction and track cache miss rate.
     */
    onCacheInvalidated?: (info: {
        droppedCount: number;
        strategy: string;
    }) => void;
}
/**
 * Phase 3: Cache-aware wrapper.
 *
 * Wraps any strategy and tracks whether compression invalidated the
 * provider prompt cache. System prompt prefix stability is preserved
 * by never modifying system[0] (the original system prompt).
 */
export declare class CacheAwareCompressionStrategy implements AsyncCompressionStrategy {
    private config;
    constructor(config: CacheAwareCompressionConfig);
    compress(messages: CompressibleMessage[], budget: number): CompressionResult;
    compressAsync(messages: CompressibleMessage[], budget: number): Promise<CompressionResult>;
}
export interface AdaptiveBudgetConfig {
    /** Model context window size in tokens */
    modelContextWindow: number;
    /** Target usage ratio (0.0–1.0, default 0.75) — trigger compaction at this fraction */
    targetUsageRatio: number;
    /** Minimum guaranteed budget in tokens */
    minBudget: number;
    /** Maximum budget (usually = modelContextWindow) */
    maxBudget: number;
}
export declare const DEFAULT_ADAPTIVE_BUDGET_CONFIG: AdaptiveBudgetConfig;
/**
 * Compute the adaptive token budget for a given model + message history.
 *
 * Adjusts based on model context window, and uses the target ratio
 * so compression triggers before hitting the hard limit.
 */
export declare function computeAdaptiveBudget(config?: Partial<AdaptiveBudgetConfig>): number;
/**
 * Decide which compression tier to use based on current token count vs budget.
 */
export type CompressionTier = "none" | "trim-only" | "sliding-window" | "llm-summarize";
export declare function selectCompressionTier(currentTokens: number, budget: number): CompressionTier;
export interface CompressionEvent {
    timestamp: number;
    strategy: string;
    tokensBefore: number;
    tokensAfter: number;
    droppedCount: number;
    latencyMs: number;
    usedLlm: boolean;
    cacheInvalidated: boolean;
    tier: CompressionTier;
}
export interface CompressionMetricsSnapshot {
    totalCompressions: number;
    totalLlmCalls: number;
    totalCacheInvalidations: number;
    averageCompressionRatio: number;
    averageLatencyMs: number;
    totalTokensSaved: number;
    recentEvents: CompressionEvent[];
}
export declare class CompressionMetricsCollector {
    private events;
    private maxEvents;
    constructor(maxEvents?: number);
    record(event: CompressionEvent): void;
    snapshot(): CompressionMetricsSnapshot;
    reset(): void;
}
/**
 * A pluggable context engine. Only one can be active at a time.
 * The default engine uses the 4-layer compression funnel.
 */
export interface ContextEngine {
    /** Unique engine identifier */
    readonly id: string;
    /** Human-readable label */
    readonly label: string;
    /** Compress messages for a turn */
    compressAsync(messages: CompressibleMessage[], budget: number, context?: {
        model?: string;
        sessionId?: string;
    }): Promise<CompressionResult>;
}
/**
 * Registry for context engines. Enforces single-active constraint.
 */
export declare class ContextEngineRegistry {
    private engines;
    private activeId;
    register(engine: ContextEngine): void;
    activate(id: string): boolean;
    getActive(): ContextEngine | undefined;
    listEngines(): Array<{
        id: string;
        label: string;
        active: boolean;
    }>;
}
/**
 * MicroCompact — selective clearing of old compactable tool results.
 *
 * CC parity: microCompact.ts
 *
 * For tool result messages from COMPACTABLE_TOOLS, if the message is
 * "old enough" (not in the most recent N messages), replace its content
 * with a compact "[result cleared]" marker. This preserves the tool call
 * structure (so the LLM knows what was called) but reclaims token budget.
 *
 * This is a lighter alternative to full summarization — it runs BEFORE
 * LLM summarization as a first-pass reduction.
 */
export declare class MicroCompactStrategy implements CompressionStrategy {
    /** Number of recent messages to preserve (don't clear) */
    private preserveRecentCount;
    /** Token estimator */
    private estimateTokens;
    constructor(
    /** Number of recent messages to preserve (don't clear) */
    preserveRecentCount?: number, 
    /** Token estimator */
    estimateTokens?: (msg: CompressibleMessage) => number);
    compress(messages: CompressibleMessage[], _budget: number): CompressionResult;
}
/**
 * After compaction, the most recently read/edited files may have been
 * dropped from the conversation. CC re-injects up to N file contents
 * to ensure the agent doesn't lose awareness of files it was working with.
 *
 * CC parity: compact.ts postCompactFileStateRecovery
 */
export interface PostCompactRecoveryConfig {
    /** Maximum number of files to re-inject (default 5) */
    maxFiles: number;
    /** Maximum total tokens for re-injected files (default 50000) */
    maxTokenBudget: number;
    /** Function to read a file from disk (injected by caller) */
    readFile: (path: string) => Promise<string | null>;
    /** Token estimator */
    estimateTokens?: (text: string) => number;
}
/**
 * Extract file paths that were recently read/edited from the conversation.
 * Looks at tool calls and results for file path arguments.
 */
export declare function extractRecentFilePaths(messages: CompressibleMessage[]): string[];
/**
 * Re-inject recently-used file contents after compaction.
 *
 * Call this AFTER compression but BEFORE sending to the LLM.
 * Appends file content as system messages at the end of the
 * system message block.
 */
export declare function postCompactFileRecovery(compressedMessages: CompressibleMessage[], originalMessages: CompressibleMessage[], config: PostCompactRecoveryConfig): Promise<CompressibleMessage[]>;
/**
 * Snip Compact — permanently remove specific messages by identifier.
 *
 * CC parity: services/compact/snipCompact.ts
 *
 * Unlike sliding window or summarization, snip removes messages by
 * their unique id (tool_call_id, or index-based). This is used for:
 * - Removing old tool results that are known to be stale
 * - Dropping large image/media messages after they've been processed
 * - Clearing tombstoned messages from the transcript
 *
 * Snip runs BEFORE microcompact and autocompact — both may fire
 * after snip if the result is still over threshold.
 */
export interface SnipResult {
    messages: CompressibleMessage[];
    tokensFreed: number;
    removedCount: number;
    /** Optional boundary message to yield (marks snip point in transcript). */
    boundaryMessage?: CompressibleMessage;
}
/**
 * Remove messages whose tool_call_id or name matches the removedIds set.
 * If no removedIds are pending, this is a no-op.
 */
export declare function snipCompactIfNeeded(messages: CompressibleMessage[], removedIds: Set<string>, estimateTokens?: (msg: CompressibleMessage) => number): SnipResult;
