From fb057b3b05f4a7c4178d545bacd8be425ec242e4 Mon Sep 17 00:00:00 2001 From: Klaus Agnoletti Date: Wed, 17 Jun 2026 14:20:57 +0200 Subject: [PATCH] fix(statusline): correct context percentage when switching models mid-session MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a Claude Code session starts with Opus (1M context window) and the user switches to Sonnet/Haiku (200K window) — or vice versa — the statusline may display an incorrect context percentage. Claude Code's context_window_size JSON field can reflect the session's starting model rather than the currently active model. Root cause: used_percentage is calculated by Claude Code against context_window_size from session start. After a model switch, the denominator is wrong. Fix: derive the expected context window from model_name (which IS current), then recalculate context_pct using total_input_tokens (absolute, model-independent) against the correct window. Falls back to proportional rescaling if total_input is unavailable. No-op when context_max already matches the model's expected size. Model→window mapping: Opus 4.x → 1,048,576 tokens Sonnet 4.x → 200,000 tokens Haiku 4.x → 200,000 tokens Fable → 200,000 tokens Unknown → no correction (display as-is) --- Releases/v4.0.3/.claude/statusline-command.sh | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Releases/v4.0.3/.claude/statusline-command.sh b/Releases/v4.0.3/.claude/statusline-command.sh index eba866cafe..5782835f01 100755 --- a/Releases/v4.0.3/.claude/statusline-command.sh +++ b/Releases/v4.0.3/.claude/statusline-command.sh @@ -100,6 +100,27 @@ context_remaining=${context_remaining:-100} total_input=${total_input:-0} total_output=${total_output:-0} +# Model-aware context window correction. When switching between Opus (1M) and +# Sonnet/Haiku (200K) mid-session, Claude Code may report context_window_size +# from the session's starting model, not the current model. Use model_name to +# derive the expected window and recalculate context_pct against the right value. +_model_lower="${model_name,,}" +if [[ "$_model_lower" == *"opus"* ]]; then + _expected_ctx=1048576 +elif [[ "$_model_lower" == *"sonnet"* ]] || [[ "$_model_lower" == *"haiku"* ]] || [[ "$_model_lower" == *"fable"* ]]; then + _expected_ctx=200000 +else + _expected_ctx="" +fi +if [ -n "$_expected_ctx" ] && [ "$context_max" != "$_expected_ctx" ] && [ "$_expected_ctx" -gt 0 ]; then + if [ "$total_input" -gt 0 ]; then + context_pct=$(( total_input * 100 / _expected_ctx )) + elif [ "$context_max" -gt 0 ] && [ "$context_pct" -gt 0 ]; then + context_pct=$(( context_pct * context_max / _expected_ctx )) + fi + context_max="$_expected_ctx" +fi + # NOTE: Removed fallback that calculated context_pct from total_input + total_output # when used_percentage was 0. total_input/output_tokens are CUMULATIVE session totals # (like an odometer) — they can far exceed context_window_size. After /clear,