|
1 | 1 | import { UsageEvent, CostBreakdown } from './types'; |
| 2 | +import { calculateCost } from './pricing'; |
2 | 3 |
|
3 | 4 | export class CostCalculator { |
4 | | - private readonly modelCosts: Record<string, { input: number; output: number; cacheRead?: number; cacheWrite?: number }> = { |
5 | | - 'gpt-4': { input: 0.03, output: 0.06 }, |
6 | | - 'gpt-4-turbo': { input: 0.01, output: 0.03 }, |
7 | | - 'gpt-3.5-turbo': { input: 0.0005, output: 0.0015 }, |
8 | | - 'claude-3-opus': { input: 0.015, output: 0.075 }, |
9 | | - 'claude-3-sonnet': { input: 0.003, output: 0.015 }, |
10 | | - 'claude-3-haiku': { input: 0.00025, output: 0.00125 } |
11 | | - }; |
12 | | - |
13 | 5 | calculateCost(events: UsageEvent[]): CostBreakdown { |
14 | 6 | const now = Date.now(); |
15 | 7 | const startMs = now - (24 * 60 * 60 * 1000); |
16 | 8 | const endMs = now; |
17 | 9 |
|
18 | 10 | const dailyEvents = events.filter(e => e.timestampMs >= startMs && e.timestampMs <= endMs); |
19 | | - |
| 11 | + |
20 | 12 | const totalCents = dailyEvents.reduce((sum, event) => sum + event.cost.totalCents, 0); |
21 | 13 | const modelBreakdown: Record<string, number> = {}; |
22 | 14 | const tokenBreakdown = { |
@@ -50,23 +42,19 @@ export class CostCalculator { |
50 | 42 | }; |
51 | 43 | } |
52 | 44 |
|
| 45 | + /** |
| 46 | + * Fill in missing cost data for a usage event using live pricing. |
| 47 | + * Returns cost in cents. |
| 48 | + */ |
53 | 49 | estimateMissingCost(event: UsageEvent): number { |
54 | 50 | if (event.cost.totalCents > 0) { |
55 | 51 | return event.cost.totalCents; |
56 | 52 | } |
57 | 53 |
|
58 | | - const modelCost = this.modelCosts[event.model.toLowerCase()]; |
59 | | - if (!modelCost) { |
60 | | - return 0; |
61 | | - } |
62 | | - |
63 | | - const inputCost = (event.tokenUsage.inputTokens / 1000) * modelCost.input; |
64 | | - const outputCost = (event.tokenUsage.outputTokens / 1000) * modelCost.output; |
65 | | - const cacheReadCost = event.tokenUsage.cacheReadTokens ? |
66 | | - (event.tokenUsage.cacheReadTokens / 1000) * (modelCost.cacheRead || modelCost.input * 0.1) : 0; |
67 | | - const cacheWriteCost = event.tokenUsage.cacheWriteTokens ? |
68 | | - (event.tokenUsage.cacheWriteTokens / 1000) * (modelCost.cacheWrite || modelCost.input * 0.5) : 0; |
69 | | - |
70 | | - return Math.round((inputCost + outputCost + cacheReadCost + cacheWriteCost) * 100); |
| 54 | + return calculateCost( |
| 55 | + event.tokenUsage.inputTokens, |
| 56 | + event.tokenUsage.outputTokens, |
| 57 | + event.model |
| 58 | + ); |
71 | 59 | } |
72 | 60 | } |
0 commit comments