Skip to content

Commit 4af0b09

Browse files
committed
feat(data-loader): add loader forr fetching model
1 parent 599b522 commit 4af0b09

File tree

1 file changed

+46
-11
lines changed

1 file changed

+46
-11
lines changed

data-loader.ts

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ import path from "node:path";
44
import { sort } from "fast-sort";
55
import { glob } from "tinyglobby";
66
import * as v from "valibot";
7+
import {
8+
type ModelPricing,
9+
calculateCostFromTokens,
10+
fetchModelPricing,
11+
getModelPricing,
12+
} from "./pricing-fetcher.ts";
713

814
export const getDefaultClaudePath = () => path.join(homedir(), ".claude");
915

@@ -16,8 +22,9 @@ export const UsageDataSchema = v.object({
1622
cache_creation_input_tokens: v.optional(v.number()),
1723
cache_read_input_tokens: v.optional(v.number()),
1824
}),
25+
model: v.optional(v.string()), // Model is inside message object
1926
}),
20-
costUSD: v.number(),
27+
costUSD: v.optional(v.number()), // Made optional for new schema
2128
});
2229

2330
export type UsageData = v.InferOutput<typeof UsageDataSchema>;
@@ -77,6 +84,9 @@ export async function loadUsageData(
7784
return [];
7885
}
7986

87+
// Fetch pricing data for cost calculation
88+
const modelPricing = await fetchModelPricing();
89+
8090
const dailyMap = new Map<string, DailyUsage>();
8191

8292
for (const file of files) {
@@ -105,13 +115,24 @@ export async function loadUsageData(
105115
totalCost: 0,
106116
};
107117

108-
existing.inputTokens += data.message.usage.input_tokens || 0;
109-
existing.outputTokens += data.message.usage.output_tokens || 0;
118+
existing.inputTokens += data.message.usage.input_tokens ?? 0;
119+
existing.outputTokens += data.message.usage.output_tokens ?? 0;
110120
existing.cacheCreationTokens +=
111-
data.message.usage.cache_creation_input_tokens || 0;
121+
data.message.usage.cache_creation_input_tokens ?? 0;
112122
existing.cacheReadTokens +=
113-
data.message.usage.cache_read_input_tokens || 0;
114-
existing.totalCost += data.costUSD || 0;
123+
data.message.usage.cache_read_input_tokens ?? 0;
124+
125+
// Calculate cost: use costUSD if available, otherwise calculate from tokens
126+
let cost = 0;
127+
if (data.costUSD !== undefined) {
128+
cost = data.costUSD;
129+
} else if (data.message.model) {
130+
const pricing = getModelPricing(data.message.model, modelPricing);
131+
if (pricing) {
132+
cost = calculateCostFromTokens(data.message.usage, pricing);
133+
}
134+
}
135+
existing.totalCost += cost;
115136

116137
dailyMap.set(date, existing);
117138
} catch (e) {
@@ -150,6 +171,9 @@ export async function loadSessionData(
150171
return [];
151172
}
152173

174+
// Fetch pricing data for cost calculation
175+
const modelPricing = await fetchModelPricing();
176+
153177
const sessionMap = new Map<string, SessionUsage>();
154178

155179
for (const file of files) {
@@ -190,13 +214,24 @@ export async function loadSessionData(
190214
lastActivity: "",
191215
};
192216

193-
existing.inputTokens += data.message.usage.input_tokens || 0;
194-
existing.outputTokens += data.message.usage.output_tokens || 0;
217+
existing.inputTokens += data.message.usage.input_tokens ?? 0;
218+
existing.outputTokens += data.message.usage.output_tokens ?? 0;
195219
existing.cacheCreationTokens +=
196-
data.message.usage.cache_creation_input_tokens || 0;
220+
data.message.usage.cache_creation_input_tokens ?? 0;
197221
existing.cacheReadTokens +=
198-
data.message.usage.cache_read_input_tokens || 0;
199-
existing.totalCost += data.costUSD || 0;
222+
data.message.usage.cache_read_input_tokens ?? 0;
223+
224+
// Calculate cost: use costUSD if available, otherwise calculate from tokens
225+
let cost = 0;
226+
if (data.costUSD !== undefined) {
227+
cost = data.costUSD;
228+
} else if (data.message.model) {
229+
const pricing = getModelPricing(data.message.model, modelPricing);
230+
if (pricing) {
231+
cost = calculateCostFromTokens(data.message.usage, pricing);
232+
}
233+
}
234+
existing.totalCost += cost;
200235

201236
// Keep track of the latest timestamp
202237
if (data.timestamp > lastTimestamp) {

0 commit comments

Comments
 (0)