MCPcopy Index your code
hub / github.com/TanStack/ai / buildChatCompletionsUsage

Function buildChatCompletionsUsage

packages/openai-base/src/usage.ts:15–75  ·  view source on GitHub ↗
(
  usage: OpenAI.Chat.Completions.ChatCompletion['usage'] | undefined | null,
)

Source from the content-addressed store, hash-verified

13 * usage object, so callers omit the field rather than fabricating zeroed totals.
14 */
15export function buildChatCompletionsUsage(
16 usage: OpenAI.Chat.Completions.ChatCompletion['usage'] | undefined | null,
17): TokenUsage | undefined {
18 if (!usage) return undefined
19
20 const result = buildBaseUsage({
21 promptTokens: usage.prompt_tokens || 0,
22 completionTokens: usage.completion_tokens || 0,
23 totalTokens: usage.total_tokens || 0,
24 })
25
26 const completionDetails = usage.completion_tokens_details
27 const completionTokensDetails = {
28 ...(completionDetails?.reasoning_tokens
29 ? { reasoningTokens: completionDetails.reasoning_tokens }
30 : {}),
31 ...(completionDetails?.audio_tokens
32 ? { audioTokens: completionDetails.audio_tokens }
33 : {}),
34 }
35
36 const promptDetails = usage.prompt_tokens_details
37 const promptTokensDetails = {
38 ...(promptDetails?.cached_tokens
39 ? { cachedTokens: promptDetails.cached_tokens }
40 : {}),
41 ...(promptDetails?.audio_tokens
42 ? { audioTokens: promptDetails.audio_tokens }
43 : {}),
44 }
45
46 if (Object.keys(completionTokensDetails).length > 0) {
47 result.completionTokensDetails = completionTokensDetails
48 }
49 if (Object.keys(promptTokensDetails).length > 0) {
50 result.promptTokensDetails = promptTokensDetails
51 }
52
53 // Predicted Outputs accepted/rejected counts have no canonical TokenUsage
54 // slot but are still billed (rejected tokens included), so surface them under
55 // providerUsageDetails — matching how the OpenRouter adapter exposes them.
56 const providerUsageDetails = {
57 ...(completionDetails?.accepted_prediction_tokens
58 ? {
59 acceptedPredictionTokens:
60 completionDetails.accepted_prediction_tokens,
61 }
62 : {}),
63 ...(completionDetails?.rejected_prediction_tokens
64 ? {
65 rejectedPredictionTokens:
66 completionDetails.rejected_prediction_tokens,
67 }
68 : {}),
69 }
70 if (Object.keys(providerUsageDetails).length > 0) {
71 result.providerUsageDetails = providerUsageDetails
72 }

Callers 2

structuredOutputStreamFunction · 0.90
processStreamChunksFunction · 0.90

Calls 1

buildBaseUsageFunction · 0.90

Tested by

no test coverage detected