From 85d16ebe97ca07de35154612daab14501fabc369 Mon Sep 17 00:00:00 2001 From: asepharyana Date: Thu, 16 Jul 2026 05:16:49 +0700 Subject: [PATCH] refactor(status): pakai context::tokens dan context::window MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Status bar sekarang memakai penghitungan token yang sama persis dengan compaction (bukan heuristik /4 terpisah), dan selalu menampilkan angka context window nyata alih-alih '?' saat model role tidak override context_window secara eksplisit — konsisten dengan fallback yang sudah dipakai compaction sendiri. --- src/view/status.rs | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/src/view/status.rs b/src/view/status.rs index 022344b..c35f17f 100644 --- a/src/view/status.rs +++ b/src/view/status.rs @@ -56,33 +56,25 @@ pub fn draw_status_bar(frame: &mut Frame, area: Rect, state: &crate::app::state: ]; // ── Right segment: metadata ─────────────────────────────────────────── - let right_str = if let Some(ref rt) = state.session_runtime { - let max_tokens = state.app_config.model_roles.values() - .find(|role| role.provider == state.settings.provider && role.model == state.settings.model) - .and_then(|role| role.context_window); + let max_tokens = crate::app::runtime::context::window::resolve(&state.app_config, &state.settings); - let total_chars: usize = rt.messages.iter() + let right_str = if let Some(ref rt) = state.session_runtime { + let current_tokens: usize = rt.messages.iter() .filter_map(|m| m.content.as_deref()) - .map(str::len) + .map(crate::app::runtime::context::tokens::count_tokens) .sum(); - let current_tokens = total_chars / 4; let mut parts = Vec::new(); if rt.usage.last_tokens_in > 0 || rt.usage.last_tokens_out > 0 { parts.push(format!("↑{} ↓{}", rt.usage.last_tokens_in, rt.usage.last_tokens_out)); } - let max_str = max_tokens.map_or_else(|| "?".to_string(), |v| v.to_string()); - parts.push(format!("{current_tokens}/{max_str}")); + parts.push(format!("{current_tokens}/{max_tokens}")); parts.push(state.settings.provider.clone()); parts.push(state.settings.model.clone()); format!(" {} ", parts.join(" · ")) } else { - let max_tokens = state.app_config.model_roles.values() - .find(|role| role.provider == state.settings.provider && role.model == state.settings.model) - .and_then(|role| role.context_window); - let max_str = max_tokens.map_or_else(|| "?".to_string(), |v| v.to_string()); - format!(" 0/{} · {} · {} ", max_str, state.settings.provider, state.settings.model) + format!(" 0/{} · {} · {} ", max_tokens, state.settings.provider, state.settings.model) }; // ── Combine everything ────────────────────────────────────────────────