claude-monitor
Version:
Real-time terminal monitoring tool for Claude AI token usage
88 lines • 3.65 kB
JavaScript
import { getSessionDurationMinutes } from '../types/index.js';
import { getBillableTokens } from '../types/session-tokens.js';
export function calculateBurnRate(session) {
const durationMinutes = getSessionDurationMinutes(session);
if (durationMinutes <= 0 || session.entries.length === 0) {
return null;
}
const billableTokens = getBillableTokens(session.tokenCounts);
const tokensPerMinute = billableTokens / durationMinutes;
const costPerHour = (session.costUsd / durationMinutes) * 60;
return {
tokensPerMinute: Math.round(tokensPerMinute),
costPerHour: Math.round(costPerHour * 100) / 100,
};
}
export function calculateProjection(session, tokenLimit) {
if (!session.isActive || !session.burnRate) {
return null;
}
const currentTokens = getBillableTokens(session.tokenCounts);
const remainingTokens = tokenLimit - currentTokens;
if (remainingTokens <= 0) {
return {
projectedTotalTokens: currentTokens,
projectedTotalCost: session.costUsd,
remainingMinutes: 0,
};
}
const remainingMinutes = remainingTokens / session.burnRate.tokensPerMinute;
const sessionEndTime = new Date(session.endTime);
const currentTime = new Date();
const sessionTimeRemaining = (sessionEndTime.getTime() - currentTime.getTime()) / (1000 * 60);
const effectiveRemainingMinutes = Math.min(remainingMinutes, sessionTimeRemaining);
const projectedAdditionalTokens = session.burnRate.tokensPerMinute * effectiveRemainingMinutes;
const projectedAdditionalCost = (session.burnRate.costPerHour / 60) * effectiveRemainingMinutes;
return {
projectedTotalTokens: Math.round(currentTokens + projectedAdditionalTokens),
projectedTotalCost: Math.round((session.costUsd + projectedAdditionalCost) * 100) / 100,
remainingMinutes: Math.round(effectiveRemainingMinutes),
};
}
export function calculateLimitPercentage(used, limit) {
if (limit <= 0)
return 0;
return Math.min(100, Math.round((used / limit) * 100));
}
export function calculateAverageTokensPerMessage(session) {
if (session.sentMessagesCount === 0)
return 0;
const billableTokens = getBillableTokens(session.tokenCounts);
return Math.round(billableTokens / session.sentMessagesCount);
}
export function formatLargeNumber(num) {
if (num >= 1_000_000) {
return `${(num / 1_000_000).toFixed(1)}M`;
}
if (num >= 1_000) {
return `${(num / 1_000).toFixed(1)}K`;
}
return num.toString();
}
export function calculateSessionStatistics(session) {
const totalTokens = getBillableTokens(session.tokenCounts);
const averageTokensPerMessage = calculateAverageTokensPerMessage(session);
const burnRate = calculateBurnRate(session);
const durationMinutes = getSessionDurationMinutes(session);
const modelBreakdown = {};
for (const [model, stats] of Object.entries(session.perModelStats)) {
const modelStats = stats;
const modelBillableTokens = modelStats.inputTokens + modelStats.outputTokens;
const percentage = totalTokens > 0 ? (modelBillableTokens / totalTokens) * 100 : 0;
modelBreakdown[model] = {
tokens: modelBillableTokens,
cost: modelStats.cost,
percentage: Math.round(percentage),
};
}
return {
totalTokens,
totalCost: session.costUsd,
messageCount: session.sentMessagesCount,
averageTokensPerMessage,
burnRate,
durationMinutes,
modelBreakdown,
};
}
//# sourceMappingURL=calculations.js.map