import { ZERO_COST } from '../constants/limits.js'; import type { CostInfo, TokenUsage } from '../types/common/index.js'; /** * What a driver's cache tokens cost, and what they mean. * * `promptIncludesCacheReads` is a property of the DRIVER, not of the model, and * it is why this is a nested object rather than two more rate fields. The * drivers in this repository disagree about it: two report `promptTokens` * excluding cache reads and charge them on top, one reports `promptTokens` * already containing them. Applying a read rate without knowing which one you * have is wrong by the entire cache volume, in a direction that changes with * whoever served the turn — so the fact travels with the rates and is never * inferred. */ export interface CacheRates { /** * `true`: `usage.cachedTokens` is a SUBSET of `usage.promptTokens`, so the * billable input is the difference. * `false`: they are additional to it. */ readonly promptIncludesCacheReads: boolean; readonly readCostPer1M: number; /** * Absent when the driver never reports a cache write. Tokens that arrive * anyway are counted as unpriced rather than charged at some neighbouring * rate, so a driver that starts reporting them surfaces as a gap instead of * a quietly wrong total. */ readonly writeCostPer1M?: number; } export interface ModelPricing { inputCostPer1M: number; outputCostPer1M: number; /** * Absent means the caller declared a two-rate card and gets a two-rate * answer: prompt and completion tokens are priced, and cache tokens are * left inside whichever of those the driver already counted them in. That * is the host-supplied case and it is a declaration, not a guess on our * part. The catalogue always supplies this. */ cache?: CacheRates; } export { ZERO_COST }; export declare function calculateCost(usage: TokenUsage, pricing: ModelPricing): CostInfo; export declare function accumulateCost(current: CostInfo, additionalUsage: TokenUsage, pricing: ModelPricing): CostInfo; /** * Record tokens that were consumed at a rate nobody has. * * The alternative was to add nothing and leave the total alone, which is how * every turn came to report `$0.00` for work that cost real money. Counting the * tokens instead makes the gap a fact the caller can read and the budget guard * can refuse on, rather than an absence that looks like an answer. * * The rate fields go, if they were there: a total that omits part of a turn is * not described by any single card. */ export declare function accumulateUnpricedCost(current: CostInfo, additionalUsage: TokenUsage): CostInfo; export declare function formatCost(usd: number): string; /** * How a total should be shown, given what is and is not known about it. * * Exists so that no surface has to re-derive the free/unknown distinction from * two fields and get it subtly wrong. `@namzu/cli` printed * `'$0.0000 (this provider reported no price)'` for every turn, because every * run was unpriced; now the two cases really are different and the string has * to follow. */ export declare function describeCost(cost: CostInfo): string; //# sourceMappingURL=cost.d.ts.map