feat: Add live context window tracking with visual progress bar

- Extract token usage from message_delta events in backend
- Calculate context usage percentage (input + cache tokens / 200k)
- Add context_update, compacting_started/finished, compact_boundary events
- Display progress bar that fills up as context is consumed
- Color-coded warnings (green→yellow→red) based on usage
- Show compacting status indicator when auto-compact runs
- Display system messages for compact start/finish with usage stats

🤖 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 21:58:34 +01:00
parent 86a1d84ea1
commit 905e295f5d
4 changed files with 195 additions and 14 deletions

View File

@@ -590,6 +590,61 @@ export function SessionProvider({ children }) {
}
break;
case 'context_update':
// Live context window metrics from message_delta events
updateSession(sessionId, (session) => ({
stats: {
...(session.stats || {}),
tokensUsed: data.tokensUsed,
contextWindow: data.contextWindow,
contextLeftPercent: data.percentRemaining,
},
}));
break;
case 'compacting_started':
console.log(`[${sessionId}] Compacting started`);
updateSession(sessionId, (session) => ({
stats: {
...(session.stats || {}),
isCompacting: true,
},
}));
addMessage(sessionId, {
type: 'system',
content: '⏳ Context compacting in progress...',
});
break;
case 'compacting_finished':
console.log(`[${sessionId}] Compacting finished`);
updateSession(sessionId, (session) => ({
stats: {
...(session.stats || {}),
isCompacting: false,
},
}));
break;
case 'compact_boundary':
console.log(`[${sessionId}] Compact boundary:`, data);
// Context was compacted - reset the metrics
updateSession(sessionId, (session) => ({
stats: {
...(session.stats || {}),
isCompacting: false,
tokensUsed: 0,
contextLeftPercent: 100,
lastCompactTrigger: data.trigger,
lastCompactPreTokens: data.preTokens,
},
}));
addMessage(sessionId, {
type: 'system',
content: `✅ Context compacted (${data.trigger}). Was at ${data.percentUsedBeforeCompact}% usage.`,
});
break;
default:
console.log(`[${sessionId}] Unhandled message type:`, type, data);
}