Merge pull request #2914 from pocharlies/fix/context-usage-server-total

fix(ui): stop the context meter from counting every internal round-trip
This commit is contained in:
Serhii Dziupin
2026-08-18 11:07:04 +03:00
committed by GitHub
11 changed files with 156 additions and 25 deletions
@@ -92,6 +92,7 @@ const extractTokenBreakdown = (message: SessionMessage): TokenBreakdown => {
}
const breakdown = source as {
total?: unknown;
input?: unknown;
output?: unknown;
reasoning?: unknown;
@@ -103,6 +104,10 @@ const extractTokenBreakdown = (message: SessionMessage): TokenBreakdown => {
const reasoning = toNonNegativeNumber(breakdown.reasoning);
const cacheRead = toNonNegativeNumber(breakdown.cache?.read);
const cacheWrite = toNonNegativeNumber(breakdown.cache?.write);
// Multi-step turns accumulate the fields across API round-trips (every tool
// call re-reads the whole cached prompt), so summing them overstates the
// window. The server-reported total is the final round-trip's window.
const reportedTotal = toNonNegativeNumber(breakdown.total);
return {
input,
@@ -110,7 +115,7 @@ const extractTokenBreakdown = (message: SessionMessage): TokenBreakdown => {
reasoning,
cacheRead,
cacheWrite,
total: input + output + reasoning + cacheRead + cacheWrite,
total: reportedTotal > 0 ? reportedTotal : input + output + reasoning + cacheRead + cacheWrite,
};
};
@@ -8,6 +8,7 @@ import { useViewportStore } from '@/sync/viewport-store';
import { useSessions, useDirectorySync, useSessionMessages, useSessionMessagesResolved } from '@/sync/sync-context';
import { useConfigStore } from '@/stores/useConfigStore';
import { resolveGlobalSessionDirectory, useGlobalSessionsStore } from '@/stores/useGlobalSessionsStore';
import { contextTokensFromBreakdown } from '@/stores/utils/tokenUtils';
import { ContextUsageDisplay } from '@/components/ui/ContextUsageDisplay';
import { McpDropdown } from '@/components/mcp/McpDropdown';
import { ArchiveAllDropdown } from '@/components/session/ArchiveAllDropdown';
@@ -702,7 +703,7 @@ const VSCodeHeader: React.FC<VSCodeHeaderProps> = ({ title, showBack, onBack, on
}
if (!lastTokens && message.tokens) {
const total = message.tokens.input + message.tokens.output + message.tokens.reasoning + (message.tokens.cache?.read ?? 0) + (message.tokens.cache?.write ?? 0);
const total = contextTokensFromBreakdown(message.tokens);
if (total > 0) {
lastTokens = message.tokens;
lastMessageId = (currentSessionMessages[i] as { id?: string }).id;
@@ -730,7 +731,7 @@ const VSCodeHeader: React.FC<VSCodeHeaderProps> = ({ title, showBack, onBack, on
}
const lastTokens = headerMessageSummary.lastTokens;
const totalTokens = lastTokens.input + lastTokens.output + lastTokens.reasoning + (lastTokens.cache?.read ?? 0) + (lastTokens.cache?.write ?? 0);
const totalTokens = contextTokensFromBreakdown(lastTokens);
const thresholdLimit = contextLimit > 0 ? contextLimit : 200000;
const percentage = contextLimit > 0 ? Math.round((totalTokens / contextLimit) * 100) : 0;
const normalizedOutput = outputLimit > 0 ? Math.round((lastTokens.output / outputLimit) * 100) : undefined;