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.
This commit is contained in:
Eric Traut
2026-07-09 10:03:22 -07:00
committed by GitHub
parent 0e19d5e908
commit d72d669ca7
4 changed files with 36 additions and 23 deletions
+17 -11
View File
@@ -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<dyn Renderable>,
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<dyn Renderable>];
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)
@@ -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.
@@ -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
@@ -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]