fix: /status shows incorrect context percentage — totalTokens clamped to contextTokens (#15114) (#15133)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: a489669fc7
Co-authored-by: echoVic <16428813+echoVic@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
This commit is contained in:
青雲
2026-02-13 12:52:19 +08:00
committed by GitHub
parent b93ad2cd48
commit fd076eb43a
28 changed files with 361 additions and 53 deletions

View File

@@ -45,20 +45,29 @@ export async function persistSessionUsageUpdate(params: {
const input = params.usage?.input ?? 0;
const output = params.usage?.output ?? 0;
const resolvedContextTokens = params.contextTokensUsed ?? entry.contextTokens;
const hasPromptTokens =
typeof params.promptTokens === "number" &&
Number.isFinite(params.promptTokens) &&
params.promptTokens > 0;
const hasFreshContextSnapshot = Boolean(params.lastCallUsage) || hasPromptTokens;
// Use last-call usage for totalTokens when available. The accumulated
// `usage.input` sums input tokens from every API call in the run
// (tool-use loops, compaction retries), overstating actual context.
// `lastCallUsage` reflects only the final API call — the true context.
const usageForContext = params.lastCallUsage ?? params.usage;
const patch: Partial<SessionEntry> = {
inputTokens: input,
outputTokens: output,
totalTokens:
deriveSessionTotalTokens({
const totalTokens = hasFreshContextSnapshot
? deriveSessionTotalTokens({
usage: usageForContext,
contextTokens: resolvedContextTokens,
promptTokens: params.promptTokens,
}) ?? input,
})
: undefined;
const patch: Partial<SessionEntry> = {
inputTokens: input,
outputTokens: output,
// Missing a last-call snapshot means context utilization is stale/unknown.
totalTokens,
totalTokensFresh: typeof totalTokens === "number",
modelProvider: params.providerUsed ?? entry.modelProvider,
model: params.modelUsed ?? entry.model,
contextTokens: resolvedContextTokens,