import { type Api, type CacheWarmingAction, type CacheWarmingDecision, type Context, type Model, type ModelsSimpleStreamOptions } from "@earendil-works/pi-ai";
import type { ModelRuntime } from "./model-runtime.ts";
import type { SessionManager, UsageEntry } from "./session-manager.ts";
import type { CacheWarmingMode } from "./settings-manager.ts";
export type { CacheWarmingAction, CacheWarmingDecision };
/**
 * Fired before each refresh with pi's decision filled in. Everything else an
 * extension might want (model, idle state, context size) is on the context.
 */
export interface CacheWarmingDecisionEvent extends Pick<CacheWarmingDecision, "warmCost" | "missCost" | "continuationProbability" | "action"> {
    type: "cache_warming_decision";
}
export interface CacheWarmingDecisionEventResult {
    /** Override whether this refresh is sent. "stop" ends warming until the next real request. */
    action?: CacheWarmingAction;
}
export interface CacheWarmingStatus {
    /** "scheduled": a refresh timer is armed; "refreshing": a warm request is in flight. */
    state: "inactive" | "scheduled" | "refreshing";
    /** Why nothing is scheduled. */
    reason?: string;
    nextWarmAt?: number;
    /** The pending decision, or the decision that stopped warming. */
    decision?: CacheWarmingDecision;
    /** True when an extension changed `decision.action`. */
    extensionOverride?: boolean;
}
/** The request whose prompt cache entry should be kept warm, exactly as it was sent. */
export interface CacheWarmRequest {
    model: Model<Api>;
    context: Context;
    options: ModelsSimpleStreamOptions;
}
/**
 * Keeps one prompt cache entry alive by re-sending its request with a
 * one-token output cap before the entry expires. `start` replaces any
 * previous run; warm requests never extend the fixed safety windows.
 */
export declare class CacheWarmer {
    private run?;
    private inactive;
    private readonly models;
    private readonly sessionManager;
    private readonly getMode;
    /** Lets extensions override `event.action`; failures fall back to pi's decision. */
    private readonly decide;
    /** Called with the persisted usage entry after each successful refresh. */
    onWarmed?: (entry: UsageEntry) => void;
    constructor(models: Pick<ModelRuntime, "streamSimple">, sessionManager: Pick<SessionManager, "appendUsage" | "getBranch">, getMode: () => CacheWarmingMode, decide?: (event: CacheWarmingDecisionEvent) => Promise<CacheWarmingAction>);
    get status(): CacheWarmingStatus;
    /** Keep the prompt cache entry written by `request` warm while `isCurrent` holds. */
    start(request: CacheWarmRequest, isCurrent: () => boolean): void;
    onAgentSettled(): void;
    /** Reconcile an active run after the persisted warming mode changes. */
    onModeChanged(): void;
    cancel(): void;
    private clearRun;
    private stop;
    private schedule;
    private refresh;
    private refreshDeadlineMissed;
    private validateRun;
    private getModeStopReason;
    private evaluate;
}
/** One-line status for `/session`. */
export declare function formatCacheWarmingStatus(status: CacheWarmingStatus, now?: number): string;
/** One-line transcript text for the total cost of one or more consecutive cache warms. */
export declare function formatCacheWarmingUsage(totalCost: number, note?: string): string;
//# sourceMappingURL=cache-warmer.d.ts.map