diff --git a/codex-rs/tui/src/chatwidget.rs b/codex-rs/tui/src/chatwidget.rs index bd0ba788b2b..d9b0152af58 100644 --- a/codex-rs/tui/src/chatwidget.rs +++ b/codex-rs/tui/src/chatwidget.rs @@ -365,6 +365,9 @@ pub(crate) struct ChatWidget { pre_review_token_info: Option>, // Whether to add a final message separator after the last message needs_final_message_separator: bool, + // Whether actual work (exec commands, MCP tool calls, patches) was done in the current turn. + // Used to determine if "Worked for" separator should be shown. + had_work_activity: bool, last_rendered_width: std::cell::Cell>, // Feedback sink for /feedback @@ -1158,13 +1161,17 @@ impl ChatWidget { self.flush_active_cell(); if self.stream_controller.is_none() { - if self.needs_final_message_separator { + if self.needs_final_message_separator && self.had_work_activity { let elapsed_seconds = self .bottom_pane .status_widget() .map(super::status_indicator_widget::StatusIndicatorWidget::elapsed_seconds); self.add_to_history(history_cell::FinalMessageSeparator::new(elapsed_seconds)); self.needs_final_message_separator = false; + self.had_work_activity = false; + } else if self.needs_final_message_separator { + // Reset the flag even if we don't show separator (no work was done) + self.needs_final_message_separator = false; } self.stream_controller = Some(StreamController::new( self.last_rendered_width.get().map(|w| w.saturating_sub(2)), @@ -1230,6 +1237,8 @@ impl ChatWidget { self.flush_active_cell(); } } + // Mark that actual work was done (command executed) + self.had_work_activity = true; } pub(crate) fn handle_patch_apply_end_now( @@ -1241,6 +1250,8 @@ impl ChatWidget { if !event.success { self.add_to_history(history_cell::new_patch_apply_failure(event.stderr)); } + // Mark that actual work was done (patch applied) + self.had_work_activity = true; } pub(crate) fn handle_exec_approval_now(&mut self, id: String, ev: ExecApprovalRequestEvent) { @@ -1403,6 +1414,8 @@ impl ChatWidget { if let Some(extra) = extra_cell { self.add_boxed_history(extra); } + // Mark that actual work was done (MCP tool call) + self.had_work_activity = true; } pub(crate) fn new(common: ChatWidgetInit, thread_manager: Arc) -> Self { @@ -1475,6 +1488,7 @@ impl ChatWidget { is_review_mode: false, pre_review_token_info: None, needs_final_message_separator: false, + had_work_activity: false, last_rendered_width: std::cell::Cell::new(None), feedback, current_rollout_path: None, @@ -1561,6 +1575,7 @@ impl ChatWidget { is_review_mode: false, pre_review_token_info: None, needs_final_message_separator: false, + had_work_activity: false, last_rendered_width: std::cell::Cell::new(None), feedback, current_rollout_path: None, diff --git a/codex-rs/tui/src/chatwidget/tests.rs b/codex-rs/tui/src/chatwidget/tests.rs index 1b9723ec54e..7209543cab3 100644 --- a/codex-rs/tui/src/chatwidget/tests.rs +++ b/codex-rs/tui/src/chatwidget/tests.rs @@ -422,6 +422,7 @@ async fn make_chatwidget_manual( is_review_mode: false, pre_review_token_info: None, needs_final_message_separator: false, + had_work_activity: false, last_rendered_width: std::cell::Cell::new(None), feedback: codex_feedback::CodexFeedback::new(), current_rollout_path: None,