fix(tui_gateway): don't show cumulative session total as context_used (#50421) - #56146
Merged
kshitijk4poor merged 3 commits intoJul 1, 2026
Conversation
…total_tokens _get_usage substituted the cumulative lifetime session_total_tokens into the current-window context_used when an external context engine did not report last_prompt_tokens, producing impossible status-bar readings (e.g. 1.9m/120k clamped to 100%). Populate context_used/percent only from a real current occupancy; leave the gauge unset otherwise. The built-in compressor always reports last_prompt_tokens, so it's unaffected. Fixes NousResearch#50421.
The salvaged fix guards with `if ctx_max and last_prompt`, but last_prompt comes from `last_prompt_tokens or 0` — the post-compression -1 sentinel (conversation_compression) is truthy, so it leaked context_used=-1 on the transitional turn. Clamp <0 to 0 so it reads as unknown (no gauge), matching the CLI status-bar path (cli.py _get_status_bar_snapshot). Follow-up on the salvaged NousResearch#50518 (r266-tech).
kshitijk4poor
enabled auto-merge (rebase)
July 1, 2026 07:51
Collaborator
Fix PR for #50421 — related. Overlapping/competing open cluster removing the same |
Whole-bug-class follow-up to the tui_gateway fix: the same -1 last_prompt_tokens sentinel (parked by conversation_compression after a compression) leaked into other status readers, producing a raw -1 or a NEGATIVE usage_percent on the transitional turn: - agent/context_engine.py get_status() (the ABC default every external context engine inherits) — highest blast radius - gateway/slash_commands.py /usage context line - cli.py session usage printout All clamped to >=0, mirroring cli.py _get_status_bar_snapshot and the tui_gateway fix. Adds an ABC get_status sentinel-clamp regression test.
kshitijk4poor
force-pushed
the
salvage/50421-context-used-cumulative
branch
from
July 1, 2026 08:01
990391b to
f772141
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The TUI/dashboard status bar no longer shows impossible context-usage readings like
4m/1m(100% red) when the real context is well within the window.tui_gateway/server.py::_get_usage()computedcontext_used = last_prompt_tokens or usage["total"]— falling back to cumulative lifetimesession_total_tokenswheneverlast_prompt_tokenswas falsy. In a long session (this report: 348 tool-turns → ~4M cumulative tokens) the bar rendered4m/1mpegged at 100% red even though each API call only sent ~189k/1M.context_usedis a current-window signal; cumulative lifetime usage is not interchangeable with it.Changes
tui_gateway/server.py: drop theor usage["total"]cumulative fallback — populatecontext_used/context_percentonly from a real current-occupancy value; emit no gauge when it's unknown (prefer absent over wrong). Clamp the-1post-compression sentinel to 0.-1sentinel (parked byconversation_compression.pyafter every compression) leaked into other status readers, producing a raw-1or a negativeusage_percenton the transitional turn. Clamped at every sibling site:agent/context_engine.py::get_status()— the ABC default every external context engine inherits (highest blast radius)gateway/slash_commands.py/usagecontext linecli.pysession-usage printouttests/: salvaged tests (no cumulative substitution; real occupancy reported) + regression tests for the-1sentinel in both_get_usageand the ABCget_status.Root cause
context_used = getattr(comp, "last_prompt_tokens", 0) or usage["total"] or 0whereusage["total"]is cumulativesession_total_tokens. Whenlast_prompt_tokensis falsy (0, or the-1sentinel), theorchain substitutes lifetime totals as the live context fill. The built-in compressor reports a reallast_prompt_tokensonce a turn runs, so steady-state is unaffected — the bad value surfaces on transitional/edge turns and for external context engines that don't track per-window occupancy (context.engine: lcm).The
-1sentinel is truthy, solast_prompt_tokens or 0does NOT neutralize it — the fix clamps<0 → 0at every status reader, mirroring the CLI status-bar path (cli.py::_get_status_bar_snapshot, which already clamped). Onlytui_gateway/server.pyhad the cumulative-total fallback; the sibling sites had the softer negative-percent variant of the same sentinel class.Validation
4m/1m@ 100% (red)189k/1M= 18%-1post-compression sentinel-1/ negative % leakedtests/test_tui_gateway_server.py+tests/agent/test_context_engine.py(1 pre-existing unrelated browser-test failure onorigin/maindeselected). ruff clean.context_used/context_percent/context_maxkeys verified missing-key-safe across Python, Ink TUI (ui-tui/), and Electron desktop (apps/desktop/).Salvaged from #50518 by @r266-tech (cherry-picked to preserve authorship), with follow-up commits fixing the
-1sentinel edge case and widening the fix to sibling status paths. Duplicate of the same core line fixed independently in #55940 (@HenkDz) — both credited on close.Closes #50421