Skip to content

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

Description

@arelchan

Summary

The TUI context-usage indicator can read over 100% (e.g. ~150%), and messages still send fine after it does. Root cause: the percentage is computed against a denominator that silently falls back to a hardcoded 64k default whenever the model's real context window can't be resolved — so once usage passes 64k but stays under the model's true (larger) window, the bar exceeds 100% while requests keep succeeding.

Where

raven/agent/loop/main.py:1447-1456:

context_max = resolve_context_window(call_model) or self.context_window_tokens
context_used = prompt_tokens + completion_tokens
usage_sink["context_percent"] = round(100 * context_used / context_max) if context_max else 0

Same fallback pattern in raven/tui_rpc/methods/session.py:111-116 (context_max = config...context_window_tokens, replaced by the live window only if resolvable).

self.context_window_tokens defaults to 65_536 (raven/config/schema.py:252). So when resolve_context_window(model) returns None, context_max becomes 64k. If the model's real window is larger (128k / 200k / 1M), a conversation between 64k and the real window renders as >100% yet is still well within the model's limit — hence "150% but still sends".

Why it's intermittent (and how to trigger)

resolve_context_window -> _try_litellm_context_window reads litellm's model map (raven/token_wise/pricing.py:166-201). It returns None when:

  • the model isn't in litellm's cost/window map (version-dependent — e.g. deepseek/deepseek-v4-flash was "isn't mapped yet" in the fix: Model request failed on Windows #119 environment, though it resolves to 1M here), or
  • litellm's remote cost-map fetch fails and the local backup doesn't cover the model (the fix: Model request failed on Windows #119 log shows Failed to fetch remote model cost map ... SSL handshake timed out. Falling back to local backup.).

On this machine resolution currently succeeds (claude-sonnet-4-5 -> 200000), so it does not repro here — but the fallback path makes the percentage meaningless whenever resolution misses.

Note: the per-turn emit uses call_model (the model of that specific call), so a sub-call on a cheaper/unmapped model can momentarily set a wrong context_max.

Expected

A usage percentage should never exceed 100%, and should not be computed against a guessed denominator presented as authoritative.

Suggested fix

  • When resolve_context_window returns None, don't render a percentage against the 64k guess. Instead show used-tokens with the window marked unknown/estimated (or hide the bar), so the number never implies "over budget" when it isn't.
  • Optionally clamp/annotate when context_used > context_max, and allow a per-model context_window_tokens override for models litellm can't map.

Environment

macOS TUI. Reported: bar once showed ~150% while sending continued to work.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions