diff --git a/src/CodexCommands.ts b/src/CodexCommands.ts index 9ec78bb6..cf88ed51 100644 --- a/src/CodexCommands.ts +++ b/src/CodexCommands.ts @@ -245,8 +245,9 @@ export class CodexCommands { } const total = this.formatTokenCount(usage.totalTokens); const input = this.formatTokenCount(usage.inputTokens); + const cachedInput = this.formatTokenCount(usage.cachedInputTokens); const output = this.formatTokenCount(usage.outputTokens); - return `${total} total (${input} input + ${output} output)`; + return `${total} total (${input} input + ${cachedInput} cached input, ${output} output)`; } private formatContextWindow(usage: TokenCount | null, contextWindow: number | null): string { diff --git a/src/TokenCount.ts b/src/TokenCount.ts index 8332d675..38415aae 100644 --- a/src/TokenCount.ts +++ b/src/TokenCount.ts @@ -3,6 +3,12 @@ import type {TokenUsageBreakdown} from "./app-server/v2"; /** * Token usage information for a turn. * This interface decouples our API from Codex's internal types. + * + * [totalTokens]: total number of tokens used (the sum of all other fields) + * [inputTokens]: number of non-cached input tokens + * [cachedInputTokens]: number of cached input tokens + * [outputTokens]: number of output tokens (including reasoning output tokens) + * [reasoningOutputTokens]: number of reasoning output tokens */ export interface TokenCount { totalTokens: number; @@ -15,11 +21,13 @@ export interface TokenCount { /** * Maps Codex's TokenUsageBreakdown to our TokenCount interface. * This explicit mapping ensures compile-time errors if Codex changes their types. + * Note: Codex includes cached input tokens in the input token count, so they are subtracted here. */ export function toTokenCount(usage: TokenUsageBreakdown): TokenCount { + return { totalTokens: usage.totalTokens, - inputTokens: usage.inputTokens, + inputTokens: usage.inputTokens - usage.cachedInputTokens, cachedInputTokens: usage.cachedInputTokens, outputTokens: usage.outputTokens, reasoningOutputTokens: usage.reasoningOutputTokens, diff --git a/src/__tests__/CodexACPAgent/data/token-usage-end-turn.json b/src/__tests__/CodexACPAgent/data/token-usage-end-turn.json index 7ce20fa8..765672df 100644 --- a/src/__tests__/CodexACPAgent/data/token-usage-end-turn.json +++ b/src/__tests__/CodexACPAgent/data/token-usage-end-turn.json @@ -4,7 +4,7 @@ "quota": { "token_count": { "totalTokens": 2500, - "inputTokens": 2000, + "inputTokens": 1500, "cachedInputTokens": 500, "outputTokens": 450, "reasoningOutputTokens": 50 @@ -14,7 +14,7 @@ "model": "model-id", "token_count": { "totalTokens": 2500, - "inputTokens": 2000, + "inputTokens": 1500, "cachedInputTokens": 500, "outputTokens": 450, "reasoningOutputTokens": 50 diff --git a/src/__tests__/CodexACPAgent/data/token-usage-multiple-updates.json b/src/__tests__/CodexACPAgent/data/token-usage-multiple-updates.json index 369368b4..90ae01fa 100644 --- a/src/__tests__/CodexACPAgent/data/token-usage-multiple-updates.json +++ b/src/__tests__/CodexACPAgent/data/token-usage-multiple-updates.json @@ -4,7 +4,7 @@ "quota": { "token_count": { "totalTokens": 1500, - "inputTokens": 1200, + "inputTokens": 700, "cachedInputTokens": 500, "outputTokens": 200, "reasoningOutputTokens": 100 @@ -14,7 +14,7 @@ "model": "model-id", "token_count": { "totalTokens": 1500, - "inputTokens": 1200, + "inputTokens": 700, "cachedInputTokens": 500, "outputTokens": 200, "reasoningOutputTokens": 100