fix: improve telemetry accuracy with modelUsage data

- Extract token counts from modelUsage (per-model stats) instead of
  basic usage object for accurate values
- Add contextWindow from modelUsage to calculate proper context %
- Show "X% used" when > 70% free, "X% left" when running low
- Color coding: green (ok), yellow (<30% left), red (<15%), pulsing (<5%)
- Fix totalTokens undefined error (renamed to contextUsed)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-18 07:29:29 +01:00
parent ea7ea9c5f8
commit a91ba61dd8
2 changed files with 39 additions and 17 deletions

View File

@@ -22,6 +22,7 @@ export function StatusBar({ sessionStats, isProcessing, connected, permissionMod
cacheReadTokens = 0,
cacheCreationTokens = 0,
numTurns = 0,
contextWindow = 200000,
isCompacting = false,
} = sessionStats || {};
@@ -29,10 +30,12 @@ export function StatusBar({ sessionStats, isProcessing, connected, permissionMod
const currentMode = PERMISSION_MODES.find(m => m.value === permissionMode) || PERMISSION_MODES[0];
const ModeIcon = currentMode.icon;
// Calculate total tokens and estimate context usage
const totalTokens = inputTokens + outputTokens;
// Claude has ~200k context, but we show relative usage
const contextPercent = Math.min(100, (inputTokens / 200000) * 100);
// Calculate context usage
// inputTokens from modelUsage represents tokens in current context (including cache reads)
// contextWindow is the model's max context size (e.g., 200000 for opus)
const contextUsed = inputTokens + outputTokens;
const contextPercent = contextWindow > 0 ? Math.min(100, (contextUsed / contextWindow) * 100) : 0;
const contextRemaining = Math.max(0, 100 - contextPercent);
// Format cost
const formatCost = (cost) => {
@@ -137,7 +140,7 @@ export function StatusBar({ sessionStats, isProcessing, connected, permissionMod
{/* Right side: Token usage */}
<div className="flex items-center gap-4">
{/* Token counts */}
{totalTokens > 0 && (
{contextUsed > 0 && (
<div className="flex items-center gap-3 text-dark-400">
<span className="flex items-center gap-1">
<span className="text-dark-500">In:</span>
@@ -156,15 +159,18 @@ export function StatusBar({ sessionStats, isProcessing, connected, permissionMod
</div>
)}
{/* Context status - simple text based on remaining context */}
{/* Context status - shows remaining context percentage */}
<div className="flex items-center gap-2">
<span className="text-dark-500">Context:</span>
{inputTokens > 0 ? (
{contextUsed > 0 ? (
<span className={`${
contextPercent >= 95 ? 'text-red-400 font-medium' :
contextPercent >= 85 ? 'text-yellow-400' : 'text-green-400'
contextRemaining <= 5 ? 'text-red-400 font-medium animate-pulse' :
contextRemaining <= 15 ? 'text-red-400' :
contextRemaining <= 30 ? 'text-yellow-400' : 'text-green-400'
}`}>
{contextPercent >= 85 ? `${(100 - contextPercent).toFixed(0)}% left` : 'ok'}
{contextRemaining <= 30
? `${contextRemaining.toFixed(0)}% left`
: `${contextPercent.toFixed(0)}% used`}
</span>
) : (
<span className="text-green-400">ok</span>