151 lines · 4.5 KB · TypeScript
RawDownload
/** * LLM token usage by phase (extracted from logger for structure). */import chalk from 'chalk'; export interface TokenUsage {  phase: string;  inputTokens: number;  outputTokens: number;  calls: number;} const sessionTokenUsage: TokenUsage[] = [];let overallTokenUsage: TokenUsage[] = [];let currentPhase = 'unknown'; export function setTokenPhase(phase: string): void {  currentPhase = phase;} export function trackTokens(inputTokens: number, outputTokens: number): void {  const existingSession = sessionTokenUsage.find(t => t.phase === currentPhase);  if (existingSession) {    existingSession.inputTokens += inputTokens;    existingSession.outputTokens += outputTokens;    existingSession.calls += 1;  } else {    sessionTokenUsage.push({      phase: currentPhase,      inputTokens,      outputTokens,      calls: 1,    });  }   const existingOverall = overallTokenUsage.find(t => t.phase === currentPhase);  if (existingOverall) {    existingOverall.inputTokens += inputTokens;    existingOverall.outputTokens += outputTokens;    existingOverall.calls += 1;  } else {    overallTokenUsage.push({      phase: currentPhase,      inputTokens,      outputTokens,      calls: 1,    });  }} export function getTokenUsage(): TokenUsage[] {  return [...sessionTokenUsage];} export function loadOverallTokenUsage(usage: TokenUsage[]): void {  overallTokenUsage = usage.map(u => ({ ...u }));} export function getOverallTokenUsage(): TokenUsage[] {  return overallTokenUsage.map(u => ({ ...u }));} function formatTokenCount(tokens: number): string {  if (tokens < 1000) {    return `${tokens}`;  } else if (tokens < 1000000) {    return `${(tokens / 1000).toFixed(1)}k`;  } else {    return `${(tokens / 1000000).toFixed(2)}M`;  }} function printTokenSection(label: string, usage: TokenUsage[], isSession: boolean): { totalInput: number; totalOutput: number; totalCalls: number } {  let totalInput = 0;  let totalOutput = 0;  let totalCalls = 0;   console.log(chalk.gray(`   ${label}:`));   for (const { phase, inputTokens, outputTokens, calls } of usage) {    totalInput += inputTokens;    totalOutput += outputTokens;    totalCalls += calls;    console.log(chalk.gray(      `     ${phase.padEnd(23)} ${formatTokenCount(inputTokens).padStart(8)} in / ${formatTokenCount(outputTokens).padStart(8)} out  (${calls} call${calls > 1 ? 's' : ''})`    ));  }   const lineChar = isSession ? '─' : '─';  const color = isSession ? chalk.gray : chalk.cyan;  console.log(color(`     ${lineChar.repeat(58)}`));  console.log(color(    `     ${'Subtotal'.padEnd(23)} ${formatTokenCount(totalInput).padStart(8)} in / ${formatTokenCount(totalOutput).padStart(8)} out  (${totalCalls} calls)`  ));   return { totalInput, totalOutput, totalCalls };} export function printTokenSummary(): void {  const hasSession = sessionTokenUsage.length > 0;  const hasOverall = overallTokenUsage.length > 0;   if (!hasSession && !hasOverall) return;   console.log(chalk.cyan('\n🔤 Token Usage:'));   let sessionTotals = { totalInput: 0, totalOutput: 0, totalCalls: 0 };   if (hasSession) {    sessionTotals = printTokenSection('This session', sessionTokenUsage, true);  }   if (hasOverall) {    const overallTotals = { totalInput: 0, totalOutput: 0, totalCalls: 0 };    for (const { inputTokens, outputTokens, calls } of overallTokenUsage) {      overallTotals.totalInput += inputTokens;      overallTotals.totalOutput += outputTokens;      overallTotals.totalCalls += calls;    }     if (overallTotals.totalCalls > sessionTotals.totalCalls) {      console.log('');      printTokenSection('Overall (all sessions)', overallTokenUsage, false);       const inputCost = (overallTotals.totalInput / 1000000) * 3;      const outputCost = (overallTotals.totalOutput / 1000000) * 15;      const totalCost = inputCost + outputCost;      if (totalCost > 0.001) {        console.log(chalk.gray(`     Estimated total cost: ~$${totalCost.toFixed(3)}`));      }    } else {      const inputCost = (sessionTotals.totalInput / 1000000) * 3;      const outputCost = (sessionTotals.totalOutput / 1000000) * 15;      const totalCost = inputCost + outputCost;      if (totalCost > 0.001) {        console.log(chalk.gray(`     Estimated cost: ~$${totalCost.toFixed(3)}`));      }    }  }} export function resetTokenUsage(): void {  sessionTokenUsage.length = 0;  currentPhase = 'unknown';} export function resetAllTokenUsage(): void {  sessionTokenUsage.length = 0;  overallTokenUsage = [];  currentPhase = 'unknown';}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t