Skip to content

fix(agent): clamp context_percent to 100 when the window is a guess#214

Open
AmirF194 wants to merge 1 commit into
EverMind-AI:mainfrom
AmirF194:fix/124-context-percent-over-100
Open

fix(agent): clamp context_percent to 100 when the window is a guess#214
AmirF194 wants to merge 1 commit into
EverMind-AI:mainfrom
AmirF194:fix/124-context-percent-over-100

Conversation

@AmirF194

Copy link
Copy Markdown

Root cause: resolve_context_window() returns None whenever a model isn't in litellm's static map or OpenRouter's live /models table, and the per-turn usage handler in raven/agent/loop/main.py falls back to self.context_window_tokens (65536 by default) as the denominator for context_percent. That fallback is a guess, not the model's real window. Real usage can legitimately pass 65536 tokens while staying well under a model's true window (128k/200k/1M), so the computed percent renders past 100% even though the request keeps succeeding.

Fix: clamp context_percent to 100. context_max and context_used are unchanged (still the real numbers behind the used/max label); only the derived percent is bounded, so the gauge never implies an over-budget state that isn't real.

raven/tui_rpc/methods/session.py's _baseline_usage uses the same fallback-window pattern but always pairs it with context_used=0 (the docstring: "Usage starts at zero for a fresh session by design... counters refresh on the next turn"), so it can't itself produce a percent over 100 and needed no change.

Verified in a clean python:3.12-slim container (uv-managed venv, uv sync --frozen --extra dev --dev):

  • Added test_usage_sink_context_percent_clamps_when_window_is_a_guess, which drives the real _process_message usage-sink path with a stub model (never resolves via resolve_context_window) and a configured window smaller than actual usage.
  • Confirmed it fails on unpatched main (800 == 100, i.e. the raw unclamped ratio) and passes with the fix.
  • uv run --extra dev pytest tests/test_agent_loop_usage_sink.py tests/test_tui_rpc_session_init_bundle.py -q -> 17 passed.
  • ruff check / ruff format --check on both changed files, and pre-commit run --files raven/agent/loop/main.py tests/test_agent_loop_usage_sink.py (ruff, trailing-whitespace, end-of-file-fixer, large-files, merge-conflict, private-key) all pass.

Not changed: the reporter's other suggestion (mark the window as estimated/unknown to the UI instead of clamping) would need a new wire field in raven/tui_rpc/models.py plus TUI/bridge changes to consume it, which is a separate, larger concern; happy to follow up if that's wanted.

Fixes #124

Co-authored-by: Claude (claude-sonnet-5) noreply@anthropic.com

resolve_context_window() returns None when a model is not in litellm's or
OpenRouter's context-window table, and the caller falls back to
context_window_tokens (65536 by default). context_percent was then computed
against that guessed denominator even when real usage legitimately exceeded
it while staying well under the model's true, larger window, so the TUI
context gauge could read past 100% while requests kept succeeding.

Clamp the percent to 100 so an unresolved window never renders as over
budget. context_max itself is unchanged (still surfaced as-is for the
used/max label); only the derived percent is bounded.

Adds a regression test that drives the real per-turn usage path with a
guessed window smaller than actual usage and asserts context_percent stays
at 100 instead of the raw (unclamped) ratio.

Fixes EverMind-AI#124

Co-authored-by: Claude (claude-sonnet-5) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TUI context usage can exceed 100% (percent falls back to a hardcoded 64k window when the model window can't be resolved)

1 participant