diff --git a/src/openai.ts b/src/openai.ts index 94e6689..39a5ec2 100644 --- a/src/openai.ts +++ b/src/openai.ts @@ -75,10 +75,17 @@ export function mapUsageToOpenAI(usage: CommandCodeUsage | undefined): OpenAIUsa const promptTokens = usage?.inputTokens ?? 0; const completionTokens = usage?.outputTokens ?? 0; const totalTokens = usage?.totalTokens ?? promptTokens + completionTokens; + const cacheReadTokens = usage?.cachedInputTokens ?? usage?.inputTokenDetails?.["cacheReadTokens"]; return { prompt_tokens: promptTokens, completion_tokens: completionTokens, total_tokens: totalTokens, + prompt_tokens_details: { + cached_tokens: + typeof cacheReadTokens === "number" && Number.isFinite(cacheReadTokens) + ? cacheReadTokens + : 0, + }, }; } diff --git a/src/types.ts b/src/types.ts index b3edc44..fd3b312 100644 --- a/src/types.ts +++ b/src/types.ts @@ -232,6 +232,9 @@ export interface OpenAIUsage { prompt_tokens: number; completion_tokens: number; total_tokens: number; + prompt_tokens_details: { + cached_tokens: number; + }; } export interface OpenAIChatCompletion { diff --git a/tests/openai.test.ts b/tests/openai.test.ts index acfdf18..30f83c7 100644 --- a/tests/openai.test.ts +++ b/tests/openai.test.ts @@ -78,10 +78,18 @@ function parseSsePayloads(chunks: string[]): unknown[] { describe("CommandCode to OpenAI conversion", () => { it("maps usage fields", () => { - expect(mapUsageToOpenAI({ inputTokens: 3, outputTokens: 2, totalTokens: 5 })).toEqual({ + expect( + mapUsageToOpenAI({ + inputTokens: 3, + outputTokens: 2, + totalTokens: 5, + inputTokenDetails: { cacheReadTokens: 1 }, + }), + ).toEqual({ prompt_tokens: 3, completion_tokens: 2, total_tokens: 5, + prompt_tokens_details: { cached_tokens: 1 }, }); });