diff --git a/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__standalone_image_generation_status.snap b/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__standalone_image_generation_status.snap new file mode 100644 index 0000000000..7762b9d047 --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__standalone_image_generation_status.snap @@ -0,0 +1,12 @@ +--- +source: tui/src/chatwidget/tests/exec_flow.rs +assertion_line: 917 +expression: normalized_backend_snapshot(terminal.backend()) +--- +" " +"• Generating image (0s • esc to interrupt) " +" " +" " +"› Ask Codex to do anything " +" " +" gpt-5.5 default · /tmp/project " diff --git a/codex-rs/tui/src/chatwidget/tests/exec_flow.rs b/codex-rs/tui/src/chatwidget/tests/exec_flow.rs index ca1c9bc681..eab6349d8b 100644 --- a/codex-rs/tui/src/chatwidget/tests/exec_flow.rs +++ b/codex-rs/tui/src/chatwidget/tests/exec_flow.rs @@ -894,6 +894,32 @@ async fn image_generation_call_adds_history_cell() { ); } +#[tokio::test] +async fn standalone_image_generation_started_updates_status() { + let (mut chat, _rx, _op_rx) = make_chatwidget_manual(/*model_override*/ None).await; + handle_turn_started(&mut chat, "turn-1"); + + handle_image_generation_started(&mut chat, "call-image-generation"); + assert_eq!(chat.status_state.current_status.header, "Generating image"); + let status = chat + .bottom_pane + .status_widget() + .expect("status indicator should be visible"); + assert_eq!(status.header(), "Generating image"); + assert!(chat.transcript.active_cell.is_none()); + + let height = chat.desired_height(/*width*/ 80); + let mut terminal = ratatui::Terminal::new(ratatui::backend::TestBackend::new(80, height)) + .expect("create terminal"); + terminal + .draw(|f| chat.render(f.area(), f.buffer_mut())) + .expect("draw image generation status"); + assert_chatwidget_snapshot!( + "standalone_image_generation_status", + normalized_backend_snapshot(terminal.backend()) + ); +} + #[tokio::test] async fn exec_history_extends_previous_when_consecutive() { let (mut chat, _rx, _op_rx) = make_chatwidget_manual(/*model_override*/ None).await; diff --git a/codex-rs/tui/src/chatwidget/tests/helpers.rs b/codex-rs/tui/src/chatwidget/tests/helpers.rs index d155376478..6920626f88 100644 --- a/codex-rs/tui/src/chatwidget/tests/helpers.rs +++ b/codex-rs/tui/src/chatwidget/tests/helpers.rs @@ -715,6 +715,24 @@ pub(super) fn handle_image_generation_end( ); } +pub(super) fn handle_image_generation_started(chat: &mut ChatWidget, call_id: impl Into) { + chat.handle_server_notification( + ServerNotification::ItemStarted(ItemStartedNotification { + thread_id: thread_id(chat), + turn_id: "turn-1".to_string(), + started_at_ms: 0, + item: AppServerThreadItem::ImageGeneration { + id: call_id.into(), + status: "in_progress".to_string(), + revised_prompt: None, + result: String::new(), + saved_path: None, + }, + }), + /*replay_kind*/ None, + ); +} + pub(super) fn replay_user_message_inputs( chat: &mut ChatWidget, item_id: &str, diff --git a/codex-rs/tui/src/chatwidget/tool_lifecycle.rs b/codex-rs/tui/src/chatwidget/tool_lifecycle.rs index e37c44a4fa..f080d33613 100644 --- a/codex-rs/tui/src/chatwidget/tool_lifecycle.rs +++ b/codex-rs/tui/src/chatwidget/tool_lifecycle.rs @@ -24,6 +24,9 @@ impl ChatWidget { pub(super) fn on_image_generation_begin(&mut self) { self.record_visible_turn_activity(); self.flush_answer_stream_with_separator(); + self.status_state.terminal_title_status_kind = TerminalTitleStatusKind::Working; + self.set_status_header(String::from("Generating image")); + self.request_redraw(); } pub(super) fn on_image_generation_end( @@ -40,6 +43,7 @@ impl ChatWidget { revised_prompt, saved_path, )); + self.restore_reasoning_status_header(); self.request_redraw(); }