From d72d669ca727a26765315ffe03db3dd2594d9b91 Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Thu, 9 Jul 2026 10:03:22 -0700 Subject: [PATCH] tui: update safety buffering copy (#31813) ## Summary The safety-buffering message currently leads with additional safety checks, which can make the delay feel accusatory. Update it to describe the system taking more time before responding, matching the revised user-facing language. - Replace the safety-buffering copy in both retry and non-retry flows. - Keep the faster-model escape hatch while aligning its wording with the updated message. - Update the TUI snapshots for both states. --- .../tui/src/chatwidget/safety_buffering.rs | 28 +++++++++++-------- ..._tests__safety_buffering_retry_prompt.snap | 3 +- ...safety_buffering_status_without_retry.snap | 3 +- .../tui/src/chatwidget/tests/app_server.rs | 25 +++++++++++------ 4 files changed, 36 insertions(+), 23 deletions(-) diff --git a/codex-rs/tui/src/chatwidget/safety_buffering.rs b/codex-rs/tui/src/chatwidget/safety_buffering.rs index 649432f21c..50d0ad75e8 100644 --- a/codex-rs/tui/src/chatwidget/safety_buffering.rs +++ b/codex-rs/tui/src/chatwidget/safety_buffering.rs @@ -6,9 +6,9 @@ use codex_app_server_protocol::ModelSafetyBufferingUpdatedNotification; const SAFETY_BUFFERING_PROMPT_VIEW_ID: &str = "safety-buffering-prompt"; const SAFETY_BUFFERING_LEARN_MORE_URL: &str = "https://help.openai.com/en/articles/20001326"; -const SAFETY_BUFFERING_MESSAGE_WITH_RETRY: &str = "This request requires additional safety checks, which can take extra time. Hang tight or retry with a faster model for a quicker response, though it may be less capable of handling complex requests."; -const SAFETY_BUFFERING_MESSAGE_WITHOUT_RETRY: &str = - "This request requires additional safety checks, which can take extra time."; +const SAFETY_BUFFERING_HEADER: &str = + "Our systems are thinking a bit more about this request before responding."; +const SAFETY_BUFFERING_MESSAGE_WITH_RETRY: &str = "Hang tight or retry with a faster model for a quicker response, though it may be less capable of handling complex requests."; #[derive(Debug)] struct ActiveSafetyBuffering { @@ -135,15 +135,15 @@ impl ChatWidget { agent_message_started, }); - let message = if can_offer_retry { - SAFETY_BUFFERING_MESSAGE_WITH_RETRY + let status_details = if can_offer_retry { + format!("{SAFETY_BUFFERING_HEADER} {SAFETY_BUFFERING_MESSAGE_WITH_RETRY}") } else { - SAFETY_BUFFERING_MESSAGE_WITHOUT_RETRY + SAFETY_BUFFERING_HEADER.to_string() }; self.bottom_pane.ensure_status_indicator(); self.set_status( "Working".to_string(), - Some(message.to_string()), + Some(status_details), StatusDetailsCapitalization::Preserve, /*details_max_lines*/ 6, ); @@ -154,10 +154,16 @@ impl ChatWidget { self.bottom_pane .dismiss_view_by_id(SAFETY_BUFFERING_PROMPT_VIEW_ID); - let header = ColumnRenderable::with(vec![ - Box::new(Line::from("Additional safety checks").bold()) as Box, - Box::new(Paragraph::new(Line::from(message).dim()).wrap(Wrap { trim: false })), - ]); + let mut header = vec![Box::new( + Paragraph::new(Line::from(SAFETY_BUFFERING_HEADER).bold()).wrap(Wrap { trim: false }), + ) as Box]; + if can_offer_retry { + header.push(Box::new( + Paragraph::new(Line::from(SAFETY_BUFFERING_MESSAGE_WITH_RETRY).dim()) + .wrap(Wrap { trim: false }), + )); + } + let header = ColumnRenderable::with(header); let mut items = Vec::new(); if let (Some(faster_model), Some(turn), Some(thread_id)) = (faster_model, retry_turn, thread_id) diff --git a/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__safety_buffering_retry_prompt.snap b/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__safety_buffering_retry_prompt.snap index 6517d73336..0a038ca70c 100644 --- a/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__safety_buffering_retry_prompt.snap +++ b/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__safety_buffering_retry_prompt.snap @@ -2,8 +2,7 @@ source: tui/src/chatwidget/tests/app_server.rs expression: popup --- - Additional safety checks - This request requires additional safety checks, which can take extra time. + Our systems are thinking a bit more about this request before responding. Hang tight or retry with a faster model for a quicker response, though it may be less capable of handling complex requests. diff --git a/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__safety_buffering_status_without_retry.snap b/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__safety_buffering_status_without_retry.snap index f3645db4fc..85570b3ebc 100644 --- a/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__safety_buffering_status_without_retry.snap +++ b/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__safety_buffering_status_without_retry.snap @@ -2,8 +2,7 @@ source: tui/src/chatwidget/tests/app_server.rs expression: popup --- - Additional safety checks - This request requires additional safety checks, which can take extra time. + Our systems are thinking a bit more about this request before responding. › 1. Keep waiting 2. Learn more diff --git a/codex-rs/tui/src/chatwidget/tests/app_server.rs b/codex-rs/tui/src/chatwidget/tests/app_server.rs index f8d6f463e5..eeaedab618 100644 --- a/codex-rs/tui/src/chatwidget/tests/app_server.rs +++ b/codex-rs/tui/src/chatwidget/tests/app_server.rs @@ -1,6 +1,9 @@ use super::*; use pretty_assertions::assert_eq; +const SAFETY_BUFFERING_HEADER_TEXT: &str = + "Our systems are thinking a bit more about this request before responding."; + fn thread_settings_for_test( model: &str, thread_id: ThreadId, @@ -136,7 +139,7 @@ async fn safety_buffering_offers_one_retry_with_app_wording() { } }; assert_eq!(opened_url, "https://help.openai.com/en/articles/20001326"); - assert!(render_bottom_popup(&chat, /*width*/ 80).contains("Additional safety checks")); + assert!(render_bottom_popup(&chat, /*width*/ 80).contains(SAFETY_BUFFERING_HEADER_TEXT)); chat.handle_key_event(KeyEvent::new(KeyCode::Up, KeyModifiers::NONE)); chat.handle_key_event(KeyEvent::new(KeyCode::Up, KeyModifiers::NONE)); @@ -157,7 +160,10 @@ async fn safety_buffering_offers_one_retry_with_app_wording() { assert_eq!(event_turn_id, turn_id); assert_eq!(model, "faster-model"); assert_matches!(turn, Op::UserTurn { .. }); - assert!(!render_bottom_popup(&chat, /*width*/ 80).contains("Additional safety checks")); + assert!( + !render_bottom_popup(&chat, /*width*/ 80) + .contains("Press enter to confirm or esc to go back") + ); } #[tokio::test] @@ -177,11 +183,11 @@ async fn safety_buffering_remains_visible_until_turn_completes() { chat.on_agent_message_delta("Visible response".to_string()); assert!(!chat.can_retry_safety_buffered_turn(turn_id)); - assert!(render_bottom_popup(&chat, /*width*/ 80).contains("Additional safety checks")); + assert!(render_bottom_popup(&chat, /*width*/ 80).contains(SAFETY_BUFFERING_HEADER_TEXT)); handle_turn_completed(&mut chat, turn_id, /*duration_ms*/ None); - assert!(!render_bottom_popup(&chat, /*width*/ 80).contains("Additional safety checks")); + assert!(!render_bottom_popup(&chat, /*width*/ 80).contains(SAFETY_BUFFERING_HEADER_TEXT)); } #[tokio::test] @@ -218,7 +224,10 @@ async fn safety_buffering_without_retry_shows_short_app_message() { assert_eq!(render_popup(&chat), popup); chat.handle_key_event(KeyEvent::new(KeyCode::Enter, KeyModifiers::NONE)); - assert!(!render_bottom_popup(&chat, /*width*/ 80).contains("Additional safety checks")); + assert!( + !render_bottom_popup(&chat, /*width*/ 80) + .contains("Press enter to confirm or esc to go back") + ); } #[tokio::test] @@ -248,14 +257,14 @@ async fn safety_buffering_ignores_hidden_stale_and_historical_updates() { )), Some(ReplayKind::ResumeInitialMessages), ); - assert!(!render_bottom_popup(&chat, /*width*/ 80).contains("Additional safety checks")); + assert!(!render_bottom_popup(&chat, /*width*/ 80).contains(SAFETY_BUFFERING_HEADER_TEXT)); let mut hidden = safety_buffering_notification(thread_id, turn_id, Some("faster-model")); chat.handle_server_notification( ServerNotification::ModelSafetyBufferingUpdated(hidden.clone()), /*replay_kind*/ None, ); - assert!(render_bottom_popup(&chat, /*width*/ 80).contains("Additional safety checks")); + assert!(render_bottom_popup(&chat, /*width*/ 80).contains(SAFETY_BUFFERING_HEADER_TEXT)); hidden.show_buffering_ui = false; chat.handle_server_notification( ServerNotification::ModelSafetyBufferingUpdated(hidden), @@ -269,7 +278,7 @@ async fn safety_buffering_ignores_hidden_stale_and_historical_updates() { .details(), None ); - assert!(!render_bottom_popup(&chat, /*width*/ 80).contains("Additional safety checks")); + assert!(!render_bottom_popup(&chat, /*width*/ 80).contains(SAFETY_BUFFERING_HEADER_TEXT)); } #[tokio::test]