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 <noreply@anthropic.com>
This commit is contained in:
lbcheng
2026-05-08 18:35:09 +08:00
parent a1eeacdfae
commit bd7c08ce3e
4 changed files with 14 additions and 17 deletions
+1 -4
View File
@@ -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) {
+1 -4
View File
@@ -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()
+9
View File
@@ -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) {
+3 -9
View File
@@ -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))