From bd7c08ce3e5df9b914c1656e2824f7f20d4e3e02 Mon Sep 17 00:00:00 2001 From: lbcheng Date: Fri, 8 May 2026 18:35:09 +0800 Subject: [PATCH] fix(tui): persist session cost across save/restore cycles Session cost (USD/CNY) was reset to zero on every session restore because only total_tokens was persisted. Carry session/subagent cost through SessionMetadata so resumed sessions show the correct billing. Also extract repeated cost-sync lines into App::sync_cost_to_metadata. Co-Authored-By: Claude Opus 4.7 --- crates/tui/src/commands/rename.rs | 5 +---- crates/tui/src/commands/session.rs | 5 +---- crates/tui/src/tui/app.rs | 9 +++++++++ crates/tui/src/tui/ui.rs | 12 +++--------- 4 files changed, 14 insertions(+), 17 deletions(-) diff --git a/crates/tui/src/commands/rename.rs b/crates/tui/src/commands/rename.rs index d539a40e..e551cf61 100644 --- a/crates/tui/src/commands/rename.rs +++ b/crates/tui/src/commands/rename.rs @@ -58,10 +58,7 @@ fn rename_with_manager( u64::from(app.session.total_tokens), app.system_prompt.as_ref(), ); - session.metadata.session_cost_usd = app.session.session_cost; - session.metadata.session_cost_cny = app.session.session_cost_cny; - session.metadata.subagent_cost_usd = app.session.subagent_cost; - session.metadata.subagent_cost_cny = app.session.subagent_cost_cny; + app.sync_cost_to_metadata(&mut session.metadata); session.metadata.title = new_title.to_string(); match manager.save_session(&session) { diff --git a/crates/tui/src/commands/session.rs b/crates/tui/src/commands/session.rs index 692503e9..67acdbbf 100644 --- a/crates/tui/src/commands/session.rs +++ b/crates/tui/src/commands/session.rs @@ -28,10 +28,7 @@ pub fn save(app: &mut App, path: Option<&str>) -> CommandResult { app.system_prompt.as_ref(), Some(app.mode.label()), ); - session.metadata.session_cost_usd = app.session.session_cost; - session.metadata.session_cost_cny = app.session.session_cost_cny; - session.metadata.subagent_cost_usd = app.session.subagent_cost; - session.metadata.subagent_cost_cny = app.session.subagent_cost_cny; + app.sync_cost_to_metadata(&mut session.metadata); let sessions_dir = save_path .parent() diff --git a/crates/tui/src/tui/app.rs b/crates/tui/src/tui/app.rs index 5332623b..362925f9 100644 --- a/crates/tui/src/tui/app.rs +++ b/crates/tui/src/tui/app.rs @@ -1648,6 +1648,15 @@ impl App { self.refresh_displayed_cost_high_water(); } + /// Copy current session/subagent cost accumulators into session metadata + /// for persistence. + pub fn sync_cost_to_metadata(&self, metadata: &mut crate::session_manager::SessionMetadata) { + metadata.session_cost_usd = self.session.session_cost; + metadata.session_cost_cny = self.session.session_cost_cny; + metadata.subagent_cost_usd = self.session.subagent_cost; + metadata.subagent_cost_cny = self.session.subagent_cost_cny; + } + /// Recompute the displayed cost high-water mark. Called any time a cost /// counter is mutated; never decreases. pub fn refresh_displayed_cost_high_water(&mut self) { diff --git a/crates/tui/src/tui/ui.rs b/crates/tui/src/tui/ui.rs index e7748847..e2503be7 100644 --- a/crates/tui/src/tui/ui.rs +++ b/crates/tui/src/tui/ui.rs @@ -3001,10 +3001,7 @@ fn build_session_snapshot(app: &App, manager: &SessionManager) -> SavedSession { app.system_prompt.as_ref(), ); updated.metadata.mode = Some(app.mode.as_setting().to_string()); - updated.metadata.session_cost_usd = app.session.session_cost; - updated.metadata.session_cost_cny = app.session.session_cost_cny; - updated.metadata.subagent_cost_usd = app.session.subagent_cost; - updated.metadata.subagent_cost_cny = app.session.subagent_cost_cny; + app.sync_cost_to_metadata(&mut updated.metadata); updated.context_references = app.session_context_references.clone(); updated } else { @@ -3016,10 +3013,7 @@ fn build_session_snapshot(app: &App, manager: &SessionManager) -> SavedSession { app.system_prompt.as_ref(), Some(app.mode.as_setting()), ); - session.metadata.session_cost_usd = app.session.session_cost; - session.metadata.session_cost_cny = app.session.session_cost_cny; - session.metadata.subagent_cost_usd = app.session.subagent_cost; - session.metadata.subagent_cost_cny = app.session.subagent_cost_cny; + app.sync_cost_to_metadata(&mut session.metadata); session.context_references = app.session_context_references.clone(); session } @@ -5373,7 +5367,7 @@ fn render(f: &mut Frame, app: &mut App) { .with_usage( app.session.total_conversation_tokens, sanitized_context_window, - app.displayed_session_cost_for_currency(app.cost_currency), + app.session.session_cost, sanitized_prompt_tokens, ) .with_reasoning_effort(Some(&effort_label))