UNPKG

perf-lens

Version:

AI-powered frontend performance optimizer

63 lines (62 loc) 2.19 kB
// USD per million tokens. Cache read = 0.1x input, cache write (5m TTL) = 1.25x input. const PRICING = { 'claude-opus-4-8': { input: 5, output: 25 }, 'claude-sonnet-5': { input: 3, output: 15 }, 'claude-haiku-4-5': { input: 1, output: 5 }, }; // ponytail: module-level accumulator; fine for a single-run CLI process const totals = { inputTokens: 0, outputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0, costUsd: 0, costKnown: true, calls: 0, }; /** * Records token usage from an API response and accumulates estimated cost. */ export function recordUsage(model, usage) { const input = usage.input_tokens ?? 0; const output = usage.output_tokens ?? 0; const cacheRead = usage.cache_read_input_tokens ?? 0; const cacheWrite = usage.cache_creation_input_tokens ?? 0; totals.inputTokens += input; totals.outputTokens += output; totals.cacheReadTokens += cacheRead; totals.cacheWriteTokens += cacheWrite; totals.calls += 1; const pricing = PRICING[Object.keys(PRICING).find(id => model.startsWith(id)) ?? '']; if (!pricing) { totals.costKnown = false; return; } totals.costUsd += (input * pricing.input + output * pricing.output + cacheRead * pricing.input * 0.1 + cacheWrite * pricing.input * 1.25) / 1000000; } /** * One-line usage summary printed at the end of a scan. */ export function getCostSummary() { if (totals.calls === 0) return ''; const tokens = `${totals.inputTokens.toLocaleString()} in / ${totals.outputTokens.toLocaleString()} out`; const cache = totals.cacheReadTokens > 0 ? `, ${totals.cacheReadTokens.toLocaleString()} cached` : ''; const cost = totals.costKnown ? `$${totals.costUsd.toFixed(4)}` : 'unknown (unrecognized model)'; return `AI usage: ${totals.calls} calls, ${tokens}${cache} tokens — estimated cost ${cost}`; } /** Test hook. */ export function resetUsage() { totals.inputTokens = 0; totals.outputTokens = 0; totals.cacheReadTokens = 0; totals.cacheWriteTokens = 0; totals.costUsd = 0; totals.costKnown = true; totals.calls = 0; }