diff --git a/src/core/task/Task.ts b/src/core/task/Task.ts index 08880d0ee0..bb0f549c5a 100644 --- a/src/core/task/Task.ts +++ b/src/core/task/Task.ts @@ -1920,9 +1920,13 @@ export class Task extends EventEmitter implements TaskLike { cacheReadTokens, ) + // For tokensIn, store the base input tokens (not including cache tokens) + // This ensures context length calculation works correctly in getApiMetrics + // where it adds tokensIn + tokensOut. The cache tokens are stored separately + // in cacheWrites and cacheReads for display purposes. this.clineMessages[lastApiReqIndex].text = JSON.stringify({ ...existingData, - tokensIn: costResult.totalInputTokens, + tokensIn: inputTokens, tokensOut: costResult.totalOutputTokens, cacheWrites: cacheWriteTokens, cacheReads: cacheReadTokens, diff --git a/src/shared/getApiMetrics.ts b/src/shared/getApiMetrics.ts index 2ae4756764..4f13fefc65 100644 --- a/src/shared/getApiMetrics.ts +++ b/src/shared/getApiMetrics.ts @@ -82,9 +82,10 @@ export function getApiMetrics(messages: ClineMessage[]) { const parsedText: ParsedApiReqStartedTextType = JSON.parse(message.text) const { tokensIn, tokensOut } = parsedText - // Since tokensIn now stores TOTAL input tokens (including cache tokens), - // we no longer need to add cacheWrites and cacheReads separately. - // This applies to both Anthropic and OpenAI protocols. + // tokensIn contains base input tokens (without cache tokens). + // This works correctly for both Anthropic and OpenAI protocols because: + // - Cache tokens are stored separately in cacheWrites/cacheReads + // - Context length = base input + output tokens result.contextTokens = (tokensIn || 0) + (tokensOut || 0) } catch (error) { console.error("Error parsing JSON:", error)