/** * Proactive per-turn token cost guard (Hermes-parity superiority item #34). * * Hermes (and pi today) only react to context growth by compressing AFTER it's expensive. This estimates * the dollar cost of the NEXT LLM call BEFORE it is submitted, so the agent can warn the user or * automatically reduce reasoning effort before a runaway billing spike — a proactive ceiling, not a * reactive cleanup. Pure functions: no I/O, fully testable. */ /** Per-million-token USD prices, as carried on `Model.cost`. */ export interface ModelTokenCost { input: number; output: number; cacheRead?: number; cacheWrite?: number; } /** * Estimate the USD cost of one turn: the whole current context is billed as input, plus up to * `maxOutputTokens` of output. `cachedInputTokens` (prefix-cache hits) are billed at the cheaper * cache-read rate. Fresh input is billed once at the higher of the uncached-input and cache-write * rates because a provider may select that prefix for a new cache write. This is an UPPER bound on * the turn (it also assumes the model emits its full output budget), which is what a spending ceiling * should bound against. */ export declare function estimateTurnCostUsd(args: { inputTokens: number; maxOutputTokens: number; cost: ModelTokenCost; cachedInputTokens?: number; longContextPricing?: { thresholdTokens: number; inputMultiplier: number; outputMultiplier: number; }; }): number; /** What to do when a turn's projected cost exceeds the threshold. */ export type CostGuardAction = "warn" | "downgrade"; export interface CostGuardSettings { /** Explicit opt-in. A stored threshold without this flag is dormant legacy configuration. */ enabled: boolean; /** Per-turn projected USD threshold. Must also be explicitly enabled to activate the guard. */ maxTurnUsd: number; /** Over the ceiling: `warn` (surface a notice) or `downgrade` (also reduce reasoning effort). */ action: CostGuardAction; } export declare const DEFAULT_COST_GUARD_SETTINGS: CostGuardSettings; /** Threshold offered when the user enables an unconfigured guard from `/settings`. */ export declare const DEFAULT_ENABLED_COST_GUARD_MAX_TURN_USD = 0.5; export interface CostGuardDecision { /** True only after explicit opt-in and when projected TOTAL (estUsd + backgroundUsd) exceeds the ceiling. */ over: boolean; /** Projected USD cost of the next foreground call alone (unchanged meaning — what the footer's "/turn" label shows). */ estUsd: number; /** Background/spawned-lane USD spend (research/worker/reflection/fitness) folded into this decision — the caller decides the window (e.g. since the current turn began). */ backgroundUsd: number; /** `estUsd + backgroundUsd` — the value actually compared against `thresholdUsd`. */ totalUsd: number; thresholdUsd: number; action: CostGuardAction; } /** * Decide whether the projected turn cost trips the guard. `enabled: true` is mandatory; a positive * legacy threshold by itself stays dormant. * * `cumulativeBackgroundUsd` (default 0) is spawned/background-lane spend (research, worker delegation, * reflection, model-fitness probes — see {@link SpawnedUsageTotals}) folded into the same ceiling as the * next foreground call. This function is window-agnostic — it just sums whatever the caller passes — but * the intended caller convention (agent-session.ts) is spend attributed to the CURRENT turn only (a * baseline snapshotted at the top of the turn, subtracted from the live cumulative total), not the * session's entire lifetime, so a turn that is cheap in the foreground but has quietly spent a lot in * background lanes THIS turn still trips the guard, without a prior turn's spend keeping it stuck over * forever (still warn-only by default). `cost-guard-controller.ts` owns that bracketing convention. */ export declare function evaluateCostGuard(estUsd: number, settings: CostGuardSettings, cumulativeBackgroundUsd?: number): CostGuardDecision; /** Reasoning levels in descending cost order, used to pick the next-cheaper level on a downgrade. */ declare const REASONING_LADDER: readonly ["ultra", "max", "xhigh", "high", "medium", "low", "minimal", "off"]; export type ReasoningLevel = (typeof REASONING_LADDER)[number]; export type ReasoningEffortMap = Readonly>>; /** * One supported step down the reasoning ladder (cost reduction) from `current`. When * `supportedLevels` is provided, unsupported intermediate levels are skipped instead of relying on a * provider clamp that may move back upward. Returns `current` unchanged when already at the model's * floor or unrecognized — the guard never raises effort, only lowers it. */ export declare function downgradeReasoning(current: string, supportedLevels?: readonly ReasoningLevel[], effortMap?: ReasoningEffortMap): ReasoningLevel | string; export {}; //# sourceMappingURL=cost-guard.d.ts.map