(openaiUsage: {
prompt_tokens: number;
completion_tokens: number;
total_tokens: number;
prompt_tokens_details?: {
cached_tokens?: number | null;
audio_tokens?: number | null;
image_tokens?: number | null;
} | null;
cached_input_tokens?: number | null;
cache_read_input_tokens?: number | null;
cache_creation_input_tokens?: number | null;
reasoning_tokens?: number | null;
completion_tokens_details?: {
reasoning_tokens?: number | null;
audio_tokens?: number | null;
accepted_prediction_tokens?: number | null;
rejected_prediction_tokens?: number | null;
} | null;
})
| 74 | * visible-text count. |
| 75 | */ |
| 76 | export function openaiUsageToUsage(openaiUsage: { |
| 77 | prompt_tokens: number; |
| 78 | completion_tokens: number; |
| 79 | total_tokens: number; |
| 80 | prompt_tokens_details?: { |
| 81 | cached_tokens?: number | null; |
| 82 | audio_tokens?: number | null; |
| 83 | image_tokens?: number | null; |
| 84 | } | null; |
| 85 | cached_input_tokens?: number | null; |
| 86 | cache_read_input_tokens?: number | null; |
| 87 | cache_creation_input_tokens?: number | null; |
| 88 | reasoning_tokens?: number | null; |
| 89 | completion_tokens_details?: { |
| 90 | reasoning_tokens?: number | null; |
| 91 | audio_tokens?: number | null; |
| 92 | accepted_prediction_tokens?: number | null; |
| 93 | rejected_prediction_tokens?: number | null; |
| 94 | } | null; |
| 95 | }): Usage { |
| 96 | const promptCachedTokens = |
| 97 | openaiUsage.prompt_tokens_details?.cached_tokens || |
| 98 | openaiUsage.cached_input_tokens || |
| 99 | openaiUsage.cache_read_input_tokens || |
| 100 | 0; |
| 101 | const promptCacheWriteTokens = openaiUsage.cache_creation_input_tokens ?? 0; |
| 102 | const promptDetails = [ |
| 103 | promptCachedTokens, |
| 104 | promptCacheWriteTokens, |
| 105 | openaiUsage.prompt_tokens_details?.audio_tokens || 0, |
| 106 | openaiUsage.prompt_tokens_details?.image_tokens || 0, |
| 107 | ]; |
| 108 | |
| 109 | const rawCompletionReasoningTokens = |
| 110 | openaiUsage.completion_tokens_details?.reasoning_tokens || |
| 111 | openaiUsage.reasoning_tokens || |
| 112 | 0; |
| 113 | const completionDetails = [ |
| 114 | openaiUsage.completion_tokens_details?.accepted_prediction_tokens || 0, |
| 115 | openaiUsage.completion_tokens_details?.rejected_prediction_tokens || 0, |
| 116 | openaiUsage.completion_tokens_details?.audio_tokens || 0, |
| 117 | rawCompletionReasoningTokens, |
| 118 | ]; |
| 119 | |
| 120 | const promptDetailTokens = sumTokens(promptDetails); |
| 121 | const completionDetailTokens = sumTokens(completionDetails); |
| 122 | const { promptDetailsAreAdditive, completionDetailsAreAdditive } = |
| 123 | detectUsageConvention( |
| 124 | openaiUsage, |
| 125 | promptDetailTokens, |
| 126 | completionDetailTokens, |
| 127 | rawCompletionReasoningTokens, |
| 128 | ); |
| 129 | |
| 130 | const cappedPromptDetails = promptDetailsAreAdditive |
| 131 | ? promptDetails |
| 132 | : capDetailsToTotal(openaiUsage.prompt_tokens, promptDetails); |
| 133 | const cappedCompletionDetails = completionDetailsAreAdditive |
no test coverage detected