cost-claude
Version:
Claude Code cost monitoring, analytics, and optimization toolkit
113 lines • 4.31 kB
JavaScript
import { Config } from '../config/index.js';
import { PricingService } from '../services/pricing-service.js';
export class CostCalculator {
rates;
pricingService;
model;
constructor(customRates, model) {
const config = Config.getInstance();
this.model = model || 'claude-opus-4-20250514';
this.pricingService = PricingService.getInstance(this.model);
this.rates = customRates ? { ...config.getRates(), ...customRates } : config.getRates();
this.initializeRates();
}
async initializeRates() {
try {
const pricingConfig = await this.pricingService.getRateConfig(this.model);
if (pricingConfig) {
this.rates = pricingConfig;
}
}
catch (error) {
console.warn('Failed to load pricing from service, using defaults:', error);
}
}
calculate(usage) {
const cost = (usage.input_tokens || 0) * this.getRate('input') +
(usage.output_tokens || 0) * this.getRate('output') +
(usage.cache_creation_input_tokens || 0) * this.getRate('cacheCreation') +
(usage.cache_read_input_tokens || 0) * this.getRate('cacheRead');
return cost;
}
calculateBreakdown(usage) {
const inputTokensCost = (usage.input_tokens || 0) * this.getRate('input');
const outputTokensCost = (usage.output_tokens || 0) * this.getRate('output');
const cacheCreationCost = (usage.cache_creation_input_tokens || 0) * this.getRate('cacheCreation');
const cacheReadCost = (usage.cache_read_input_tokens || 0) * this.getRate('cacheRead');
return {
inputTokensCost,
outputTokensCost,
cacheCreationCost,
cacheReadCost,
totalCost: inputTokensCost + outputTokensCost + cacheCreationCost + cacheReadCost,
};
}
calculateCacheEfficiency(usage) {
const cacheableTokens = (usage.cache_creation_input_tokens || 0) +
(usage.cache_read_input_tokens || 0);
if (cacheableTokens === 0)
return 0;
const cacheHits = usage.cache_read_input_tokens || 0;
return (cacheHits / cacheableTokens) * 100;
}
calculateCacheSavings(usage) {
const cacheReadTokens = usage.cache_read_input_tokens || 0;
const cacheCreationTokens = usage.cache_creation_input_tokens || 0;
const normalReadCost = cacheReadTokens * this.getRate('input');
const cacheReadCost = cacheReadTokens * this.getRate('cacheRead');
const readSavings = normalReadCost - cacheReadCost;
const normalCreationCost = cacheCreationTokens * this.getRate('input');
const cacheCreationCost = cacheCreationTokens * this.getRate('cacheCreation');
const creationOverhead = cacheCreationCost - normalCreationCost;
return readSavings - creationOverhead;
}
formatCost(cost) {
return `$${cost.toFixed(4)}`;
}
formatCostAdaptive(cost) {
if (cost >= 10) {
return `$${cost.toFixed(2)}`;
}
else if (cost >= 1) {
return `$${cost.toFixed(3)}`;
}
else {
return `$${cost.toFixed(4)}`;
}
}
getRate(type) {
return this.rates[type] / this.rates.perTokens;
}
updateRates(newRates) {
this.rates = { ...this.rates, ...newRates };
}
getRates() {
return { ...this.rates };
}
estimateCostFromText(inputText, outputText) {
const inputTokens = Math.ceil(inputText.length / 4);
const outputTokens = Math.ceil(outputText.length / 4);
return this.calculate({
input_tokens: inputTokens,
output_tokens: outputTokens,
cache_creation_input_tokens: 0,
cache_read_input_tokens: 0,
});
}
async ensureRatesLoaded() {
await this.initializeRates();
}
async switchModel(modelId) {
this.model = modelId;
this.pricingService.setModel(modelId);
await this.initializeRates();
}
getModel() {
return this.model;
}
async refreshPricing() {
await this.pricingService.refreshPricing();
await this.initializeRates();
}
}
//# sourceMappingURL=cost-calculator.js.map