import { type CostAccumulator, type CostSnapshot, type LLMProvider, type ResponseCache } from '../llm/index'; /** A logger sink for budget/cache notes. Defaults to a no-op. */ export type BudgetLogger = (line: string) => void; /** * Thrown when a hard budget ceiling is reached BETWEEN calls. Carries the * cost snapshot at the moment of the abort so the caller can report it. */ export declare class BudgetExceededError extends Error { /** The cost snapshot at the moment the ceiling was crossed. */ readonly snapshot: CostSnapshot; /** Which ceiling tripped: the dollar cap or the call cap. */ readonly reason: 'maxCostUsd' | 'maxLlmCallsPerRun'; constructor(reason: 'maxCostUsd' | 'maxLlmCallsPerRun', snapshot: CostSnapshot); } /** Construction options for {@link createBudgetedProvider}. */ export interface BudgetedProviderOptions { /** The content-addressed cache consulted before every call. */ cache: ResponseCache; /** The shared per-run cost accumulator (the ceiling is read from its snapshot). */ cost: CostAccumulator; /** Hard dollar ceiling, consulted BETWEEN calls. */ maxCostUsd: number; /** Hard call-count ceiling, consulted BETWEEN calls. */ maxLlmCallsPerRun: number; /** Default model used to compute a cache key when a request omits `cacheKey`. */ defaultModel: string; /** Optional note logger (cache hits, aborts). */ log?: BudgetLogger; /** * FROZEN-SET / CI-gating mode. When `true`, a cache MISS does NOT call the * inner provider or write the cache — it records a zero-cost call and returns * an empty-candidates result, so the run re-scores ONLY already-cached * proposals (deterministic + free). Default `false` (the live network path). */ cacheOnly?: boolean; } /** * Wrap `inner` in a budget-enforcing, cache-backed {@link LLMProvider}. The * wrapper: * 1. computes the cache key (request-supplied or content-addressed); * 2. on a cache HIT → returns a zero-cost cached result (records the call); * 3. on a MISS → checks the dollar + call ceilings against the live snapshot * and THROWS {@link BudgetExceededError} if already crossed, else delegates, * records the real cost, and stores the entry. * * @param inner The real (or mock) provider to wrap. * @param options Cache, cost accumulator, ceilings, default model, logger. * @returns A budget-enforcing provider with the same {@link LLMProvider} surface. */ export declare function createBudgetedProvider(inner: LLMProvider, options: BudgetedProviderOptions): LLMProvider;