( usage: OpenAIUsage, modelShortName: string, )
| 92 | } |
| 93 | |
| 94 | function extractUsageAndCost( |
| 95 | usage: OpenAIUsage, |
| 96 | modelShortName: string, |
| 97 | ): UsageData { |
| 98 | const inputTokenCost = |
| 99 | INPUT_TOKEN_COSTS[modelShortName] ?? DEFAULT_INPUT_COST |
| 100 | const cachedInputTokenCost = |
| 101 | CACHED_INPUT_TOKEN_COSTS[modelShortName] ?? DEFAULT_CACHED_INPUT_COST |
| 102 | const outputTokenCost = |
| 103 | OUTPUT_TOKEN_COSTS[modelShortName] ?? DEFAULT_OUTPUT_COST |
| 104 | |
| 105 | const inTokens = usage.prompt_tokens ?? 0 |
| 106 | const cachedInTokens = usage.prompt_tokens_details?.cached_tokens ?? 0 |
| 107 | const outTokens = usage.completion_tokens ?? 0 |
| 108 | const cost = |
| 109 | (inTokens / 1_000_000) * inputTokenCost + |
| 110 | (cachedInTokens / 1_000_000) * cachedInputTokenCost + |
| 111 | (outTokens / 1_000_000) * outputTokenCost |
| 112 | |
| 113 | return { |
| 114 | inputTokens: inTokens, |
| 115 | outputTokens: outTokens, |
| 116 | cacheReadInputTokens: cachedInTokens, |
| 117 | reasoningTokens: usage.completion_tokens_details?.reasoning_tokens ?? 0, |
| 118 | cost, |
| 119 | } |
| 120 | } |
| 121 | |
| 122 | function extractShortModelName(model: string): string { |
| 123 | return model.startsWith('openai/') ? model.slice('openai/'.length) : model |
no outgoing calls
no test coverage detected