/** * Token and cost tracking for API usage */ export interface TokenUsage { promptTokens: number; completionTokens: number; totalTokens: number; /** Anthropic prompt caching: tokens written to the cache on this call * (billed at ~1.25× input rate). Undefined for providers that don't * support caching or for calls below the cache size threshold. */ cacheCreationTokens?: number; /** Anthropic prompt caching: tokens read from cache on this call * (billed at ~0.1× input rate — the big savings live here). */ cacheReadTokens?: number; } export interface SessionTokenStats { totalPromptTokens: number; totalCompletionTokens: number; totalTokens: number; requestCount: number; estimatedCost: number; /** `estimatedCost` minus every flat-fee entry — the only figure we may show * as a dollar total, since flat-fee tokens carry no per-token charge. */ billableCost: number; /** True when at least one entry came from a flat-fee provider, so callers can * say "included in plan" instead of silently dropping that usage. */ hasFlatFeeUsage: boolean; /** Anthropic prompt caching: total tokens written to cache this session. */ totalCacheCreationTokens: number; /** Anthropic prompt caching: total tokens read from cache this session. */ totalCacheReadTokens: number; } interface TokenRecord { timestamp: number; promptTokens: number; completionTokens: number; totalTokens: number; /** Anthropic prompt caching breakdown — see TokenUsage. */ cacheCreationTokens?: number; cacheReadTokens?: number; model: string; provider: string; /** Authoritative per-call USD from the provider (OpenRouter), if available. */ actualCostUsd?: number; } /** * Get context window size for a model (falls back to 128k if unknown) */ export declare function getModelContextWindow(model: string): number; export declare function getPricingTable(): { model: string; inputPer1M: number; outputPer1M: number; }[]; /** An isolated token-record buffer for one scope (e.g. one ACP session). */ export type TokenScope = TokenRecord[]; /** Create a fresh, empty scope buffer (one per ACP session). */ export declare function createTokenScope(): TokenScope; /** * Run `fn` with `scope` as the active token-record buffer. Every * recordTokenUsage() call made within `fn`'s async flow (including across * awaits) accumulates into `scope`, and reads (getCostBreakdown/…) made in the * same flow see only `scope`. Used by the ACP server to isolate per-session * usage without threading a session id through the deep API layer. */ export declare function runWithTokenScope(scope: TokenScope, fn: () => T): T; /** * Record token usage from an API response. The optional `actualCostUsd` * argument lets aggregator providers (OpenRouter) pass through the * authoritative per-call cost they returned in `usage.cost`, instead of * forcing us to look it up in `MODEL_PRICING` (which we don't maintain * for every OpenRouter-listed model — there are 100+). */ export declare function recordTokenUsage(usage: TokenUsage, model: string, provider: string, actualCostUsd?: number): void; /** * Extract token usage from OpenAI-format API response */ export declare function extractOpenAIUsage(data: any): TokenUsage | null; /** * Extract token usage from Anthropic-format API response */ export declare function extractAnthropicUsage(data: any): TokenUsage | null; export interface ProviderCostBreakdown { provider: string; model: string; promptTokens: number; completionTokens: number; /** Anthropic prompt caching: tokens written to cache (billed ~1.25× input). * 0 for providers that don't report caching. */ cacheCreationTokens: number; /** Anthropic prompt caching: tokens read from cache (billed ~0.1× input). * 0 for providers that don't report caching. */ cacheReadTokens: number; estimatedCost: number; } /** * What a cached prompt token costs, as a fraction of the model's input rate. * Model first (a property of the model), then provider, then the default. * * One lookup for everything that needs it. Cost used this chain while savings * hardcoded 0.1, so every provider priced differently from Anthropic had a * cost and a "saved" figure that disagreed with each other. */ export declare function cacheReadRateFor(model: string, provider: string | undefined): number; /** * The rate note for a report. One rate reads as "0.02×"; a session mixing * providers reads as a range, because any single number there would be wrong * for part of it. */ export declare function formatCacheReadRates(rates: readonly number[]): string; /** * Get cost breakdown grouped by provider/model. * * `startIndex` lets callers price only the records appended since a marker (see * getRecordCount) — used to report a single run/prompt's delta to cloud * telemetry WITHOUT wiping the session-cumulative store the status bar and * `/cost` read. Defaults to 0 (the whole current scope). */ export declare function getCostBreakdown(startIndex?: number): ProviderCostBreakdown[]; /** * Aggregate Anthropic prompt-caching stats for the current session. * Returns the breakdown plus an estimate of what the input billing would * have been *without* caching, so we can surface "you saved $X" to the * user. */ export interface CacheStats { cacheCreationTokens: number; cacheReadTokens: number; /** Sum of estimatedSavings across pay-per-use records only. */ estimatedSavingsUsd: number; /** True when some cached tokens came from a flat-fee plan, whose "savings" * are not a dollar amount at all. Lets the report say so instead of quoting * a figure that silently covers only part of the session. */ hasFlatFeeCacheUsage: boolean; /** True when EVERY cached token came from a flat-fee plan — there is no * metered spend to have saved against. */ isEntirelyFlatFeeCache: boolean; /** The read rate of each metered record that read from cache, so a report * can state the rate that actually applied instead of assuming 0.1×. */ cacheReadRates: number[]; } export declare function getCacheStats(): CacheStats; /** * Get session stats */ export declare function getSessionStats(): SessionTokenStats; /** * Get last request usage */ export declare function getLastUsage(): TokenRecord | null; /** * Format token count for display (e.g., 1234 -> "1.2K") */ export declare function formatTokenCount(tokens: number): string; /** * Number of records in the current scope. Capture before a run/prompt and pass * it to getCostBreakdown(startIndex) to price just that run's delta (for cloud * telemetry) without wiping the cumulative store the status bar and `/cost` * read. */ export declare function getRecordCount(): number; /** * Reset the current scope's tracking. Production run/prompt paths no longer * call this (they use getRecordCount + getCostBreakdown(startIndex) so the * session-cumulative totals survive); retained for the test suite, which uses * it to isolate the process-wide default buffer between cases. */ export declare function resetTokenTracking(): void; /** * Format a session cost report as a Markdown block. Used by `/cost` in both * the TUI and ACP command handlers. Returns a "no usage yet" message if the * session hasn't made any API calls. */ export declare function formatCostReport(): string; export {};