|
9 | 9 | import type { CmuxMessage } from "@/types/message"; |
10 | 10 | import type { ChatStats, TokenConsumer } from "@/types/chatStats"; |
11 | 11 | import type { LanguageModelV2Usage } from "@ai-sdk/provider"; |
12 | | -import { getModelStats } from "./modelStats"; |
13 | 12 | import type { ChatUsageDisplay } from "./usageAggregator"; |
14 | 13 |
|
15 | 14 | // Simple approximation tokenizer to avoid loading 8MB ai-tokenizer package |
@@ -61,23 +60,13 @@ export function createDisplayUsage( |
61 | 60 | (usage.outputTokens ?? 0) - (usage.reasoningTokens ?? 0) |
62 | 61 | ); |
63 | 62 |
|
64 | | - // Get model stats for cost calculation |
65 | | - const modelStats = getModelStats(model); |
66 | | - |
67 | | - // Calculate costs based on model stats (undefined if model unknown) |
68 | | - let inputCost: number | undefined; |
69 | | - let cachedCost: number | undefined; |
70 | | - let cacheCreateCost: number | undefined; |
71 | | - let outputCost: number | undefined; |
72 | | - let reasoningCost: number | undefined; |
73 | | - |
74 | | - if (modelStats) { |
75 | | - inputCost = inputTokens * modelStats.input_cost_per_token; |
76 | | - cachedCost = cachedTokens * (modelStats.cache_read_input_token_cost ?? 0); |
77 | | - cacheCreateCost = cacheCreateTokens * (modelStats.cache_creation_input_token_cost ?? 0); |
78 | | - outputCost = outputWithoutReasoning * modelStats.output_cost_per_token; |
79 | | - reasoningCost = (usage.reasoningTokens ?? 0) * modelStats.output_cost_per_token; |
80 | | - } |
| 63 | + // In approximation mode, we don't calculate costs to avoid loading 701KB models.json |
| 64 | + // Costs are calculated accurately in the main process and stored in message metadata |
| 65 | + const inputCost: number | undefined = undefined; |
| 66 | + const cachedCost: number | undefined = undefined; |
| 67 | + const cacheCreateCost: number | undefined = undefined; |
| 68 | + const outputCost: number | undefined = undefined; |
| 69 | + const reasoningCost: number | undefined = undefined; |
81 | 70 |
|
82 | 71 | return { |
83 | 72 | input: { |
@@ -190,7 +179,7 @@ export function calculateTokenStatsApproximate(messages: CmuxMessage[], model: s |
190 | 179 | for (const part of message.parts) { |
191 | 180 | if (part.type === "dynamic-tool") { |
192 | 181 | // Count tool arguments |
193 | | - const argsTokens = approximateCountTokensForData(part.input, tokenizer); |
| 182 | + const argsTokens = approximateCountTokensForData(part.input); |
194 | 183 |
|
195 | 184 | // Count tool results if available |
196 | 185 | // Tool results have nested structure: { type: "json", value: {...} } |
@@ -235,11 +224,11 @@ export function calculateTokenStatsApproximate(messages: CmuxMessage[], model: s |
235 | 224 | resultTokens = Math.ceil(encryptedChars * 0.75); |
236 | 225 | } else { |
237 | 226 | // Normal web search results without encryption |
238 | | - resultTokens = approximateCountTokensForData(outputData, tokenizer); |
| 227 | + resultTokens = approximateCountTokensForData(outputData); |
239 | 228 | } |
240 | 229 | } else { |
241 | 230 | // Normal tool results |
242 | | - resultTokens = approximateCountTokensForData(outputData, tokenizer); |
| 231 | + resultTokens = approximateCountTokensForData(outputData); |
243 | 232 | } |
244 | 233 | } |
245 | 234 |
|
|
0 commit comments