fix(tui): move tolerance to module-level const, add total helpers

Promote COST_EQ_TOLERANCE from a function-local const to a module-level
constant in sidebar.rs.

Add SessionCostSnapshot::total_usd() and total_cny() helpers that
encapsulate session+subagent cost summation, used during session restore.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
lbcheng
2026-05-08 20:24:11 +08:00
parent d29fbcb24b
commit d1187e2b8f
3 changed files with 19 additions and 5 deletions
+12
View File
@@ -125,6 +125,18 @@ pub struct SessionCostSnapshot {
pub displayed_cost_high_water_cny: f64,
}
impl SessionCostSnapshot {
/// Session + subagent cost in USD.
pub fn total_usd(&self) -> f64 {
self.session_cost_usd + self.subagent_cost_usd
}
/// Session + subagent cost in CNY.
pub fn total_cny(&self) -> f64 {
self.session_cost_cny + self.subagent_cost_cny
}
}
impl SessionMetadata {
/// Copy cost fields from another metadata (used when forking a session).
pub fn copy_cost_from(&mut self, other: &SessionMetadata) {
+5 -3
View File
@@ -26,6 +26,11 @@ use super::history::{HistoryCell, ToolCell, ToolStatus};
use super::subagent_routing::active_fanout_counts;
use super::ui::truncate_line_to_width;
/// Tolerance for floating-point cost comparison in the sidebar breakdown.
/// Must be large enough that accumulated f64 error across hundreds of turns
/// does not prematurely hide the session+agents breakdown.
const COST_EQ_TOLERANCE: f64 = 1e-6;
pub fn render_sidebar(f: &mut Frame, area: Rect, app: &App) {
if area.width < 24 || area.height < 8 {
// Paint a styled block over the area so stale cells from a previous
@@ -678,9 +683,6 @@ fn render_context_panel(f: &mut Frame, area: Rect, app: &App) {
// Only show the additive breakdown when it matches the displayed
// total; when the high-water mark is in effect (post-reconciliation),
// the breakdown would not sum to the displayed value (#244).
// Tolerance must be large enough that floating-point accumulation
// across many turns doesn't prematurely hide the breakdown.
const COST_EQ_TOLERANCE: f64 = 1e-6;
let cost_line = if (displayed_total - real_total).abs() < COST_EQ_TOLERANCE {
format!(
"cost: {} (session {} + agents {})",
+2 -2
View File
@@ -6073,8 +6073,8 @@ fn apply_loaded_session(app: &mut App, session: &SavedSession) -> bool {
// Take the max with the current totals — old sessions without
// persisted high-water fields deserialise to 0.0 and fall back to
// the restored total with no regression.
let total_restored_usd = app.session.session_cost + app.session.subagent_cost;
let total_restored_cny = app.session.session_cost_cny + app.session.subagent_cost_cny;
let total_restored_usd = session.metadata.cost.total_usd();
let total_restored_cny = session.metadata.cost.total_cny();
app.session.displayed_cost_high_water =
session.metadata.cost.displayed_cost_high_water_usd.max(total_restored_usd);
app.session.displayed_cost_high_water_cny =