import type { Api, Model } from "./types.js"; /** Cumulative model-cache write counters for this process. */ export interface ModelCacheWriteStats { /** Payload rows (re)written because their stored content changed. */ payloadWrites: number; /** Serialized model bytes written by `payloadWrites`. */ payloadBytes: number; /** Unchanged payloads whose freshness/authority advanced via the side table. */ refreshWrites: number; /** Writes that matched the stored row exactly and touched nothing. */ skippedWrites: number; /** Provider ids of the most recent payload writes (bounded). */ recentPayloadProviders: readonly string[]; } /** Snapshot of this process's model-cache write counters. */ export declare function getModelCacheWriteStats(): ModelCacheWriteStats; /** Materialized provider snapshot with freshness and header-restoration provenance. */ export interface CacheEntry { /** Trusted, fully materialized rows; request headers remain omitted. */ models: Model[]; fresh: boolean; authoritative: boolean; /** * `authoritative` of the payload row itself, ignoring the * `model_cache_refresh` side row. A failed refresh flips only the side row * (freshness plus retry backoff), so this keeps answering "were `models` * written by an authoritative discovery result?" after such a write. */ payloadAuthoritative: boolean; updatedAt: number; /** Model ids whose live headers were intentionally omitted from disk. */ headerOmittedModelIds: readonly string[]; /** Header-bearing model ids that cannot be rebuilt from the static source. */ unrestorableHeaderModelIds: readonly string[]; /** Whether unrestorable markers predate request-model header matching. */ legacyHeaderRestoreMarkers: boolean; /** * Hash of the static catalog slice that was merged into `models` when this * row was written. `resolveProviderModels` compares against the current * static fingerprint and bypasses the static+cache re-merge when they * match — the cache already incorporates the same static state. */ staticFingerprint: string; } /** * Closes the shared handle to the default `/models.db`; the next * default-path access reopens it. Call before deleting an agent directory the * cache was opened under — Windows cannot remove a database that is still open. */ export declare function closeModelCache(): void; /** * Keeps one connection to a non-default cache path open until the returned * handle is disposed. The default `models.db` already shares a long-lived * connection; other paths otherwise open, initialize and close the database on * every read and write, which a refresh pass repeats once per provider. * Retains nest: the connection closes when the last one is disposed. */ export declare function retainModelCacheConnection(dbPath: string | undefined): Disposable; export declare function readModelCache(providerId: string, ttlMs: number, now: () => number, dbPath?: string): CacheEntry | null; /** * Persist a provider snapshot. * * When the stored payload (models, header provenance, fingerprint, schema and * materialization policy) is byte-identical, the multi-MB row is left alone and * only `model_cache_refresh` records the new freshness and authority; a write * that changes nothing at all is skipped. Every model persisted here is * validated with the reader's own predicate, so a row this writes is never * rejected (and deleted) by `readModelCache`. */ export declare function writeModelCache(providerId: string, updatedAt: number, models: Model[], authoritative: boolean, staticFingerprint: string, dbPath?: string, staticHeaderSources?: readonly Model[], restorableHeaderFallback?: Record): void;