From a2efaf384c9daf3c8ca44c0b7ea57f2f64eabd02 Mon Sep 17 00:00:00 2001 From: Hernan Javier Ardila Sanchez Date: Thu, 21 May 2026 23:07:29 +0200 Subject: [PATCH] fix(cost): prevent double-billing of cache_creation_input_tokens (#2522) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix(cost): prevent double-billing of cache_creation_input_tokens — integrated into release/v3.8.2 --- src/lib/usage/costCalculator.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/lib/usage/costCalculator.ts b/src/lib/usage/costCalculator.ts index 32ea1460da..15379c6712 100644 --- a/src/lib/usage/costCalculator.ts +++ b/src/lib/usage/costCalculator.ts @@ -94,7 +94,12 @@ export function computeCostFromPricing( const inputTokens = tokens.input ?? tokens.prompt_tokens ?? tokens.input_tokens ?? 0; const cachedTokens = tokens.cacheRead ?? tokens.cached_tokens ?? tokens.cache_read_input_tokens ?? 0; - const nonCachedInput = Math.max(0, inputTokens - cachedTokens); + const cacheCreationTokens = tokens.cacheCreation ?? tokens.cache_creation_input_tokens ?? 0; + + // prompt_tokens from extractors already includes cache_read + cache_creation, + // so we must subtract BOTH cache types to avoid pricing cache at the full + // input rate in addition to their dedicated cache_* rates below. + const nonCachedInput = Math.max(0, inputTokens - cachedTokens - cacheCreationTokens); cost += nonCachedInput * (inputPrice / 1_000_000); if (cachedTokens > 0) cost += cachedTokens * (cachedPrice / 1_000_000); @@ -104,7 +109,6 @@ export function computeCostFromPricing( const reasoningTokens = tokens.reasoning ?? tokens.reasoning_tokens ?? 0; if (reasoningTokens > 0) cost += reasoningTokens * (reasoningPrice / 1_000_000); - const cacheCreationTokens = tokens.cacheCreation ?? tokens.cache_creation_input_tokens ?? 0; if (cacheCreationTokens > 0) cost += cacheCreationTokens * (cacheCreationPrice / 1_000_000); return cost * getCodexFastCostMultiplier(options.provider, options.model, options.serviceTier);