Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions codex-rs/tui/src/bottom_pane/chat_composer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1120,6 +1120,16 @@ impl ChatComposer {
.collect()
}

#[cfg(test)]
pub(crate) fn status_line_text(&self) -> Option<String> {
self.status_line_value.as_ref().map(|line| {
line.spans
.iter()
.map(|span| span.content.as_ref())
.collect::<String>()
})
}

pub(crate) fn local_images(&self) -> Vec<LocalImageAttachment> {
self.attached_images
.iter()
Expand Down
5 changes: 5 additions & 0 deletions codex-rs/tui/src/bottom_pane/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -690,6 +690,11 @@ impl BottomPane {
self.status.is_some()
}

#[cfg(test)]
pub(crate) fn status_line_text(&self) -> Option<String> {
self.composer.status_line_text()
}

pub(crate) fn show_esc_backtrack_hint(&mut self) {
self.esc_backtrack_hint = true;
self.composer.set_esc_backtrack_hint(true);
Expand Down
4 changes: 4 additions & 0 deletions codex-rs/tui/src/bottom_pane/status_line_setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ pub(crate) enum StatusLineItem {

/// Full session UUID.
SessionId,

/// Whether Fast mode is currently active.
FastMode,
}

impl StatusLineItem {
Expand Down Expand Up @@ -125,6 +128,7 @@ impl StatusLineItem {
StatusLineItem::SessionId => {
"Current session identifier (omitted until session starts)"
}
StatusLineItem::FastMode => "Whether Fast mode is currently active",
}
}
}
Expand Down
7 changes: 7 additions & 0 deletions codex-rs/tui/src/chatwidget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5348,6 +5348,13 @@ impl ChatWidget {
format_tokens_compact(self.status_line_total_usage().output_tokens)
)),
StatusLineItem::SessionId => self.thread_id.map(|id| id.to_string()),
StatusLineItem::FastMode => Some(
if matches!(self.config.service_tier, Some(ServiceTier::Fast)) {
"Fast on".to_string()
} else {
"Fast off".to_string()
},
),
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
source: tui/src/chatwidget/tests.rs
expression: terminal.backend()
---
" "
" "
"› Ask Codex to do anything "
" "
" Fast on "
37 changes: 37 additions & 0 deletions codex-rs/tui/src/chatwidget/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1951,6 +1951,10 @@ fn lines_to_single_string(lines: &[ratatui::text::Line<'static>]) -> String {
s
}

fn status_line_text(chat: &ChatWidget) -> Option<String> {
chat.bottom_pane.status_line_text()
}

fn make_token_info(total_tokens: i64, context_window: i64) -> TokenUsageInfo {
fn usage(total_tokens: i64) -> TokenUsage {
TokenUsage {
Expand Down Expand Up @@ -9282,6 +9286,39 @@ async fn status_line_branch_refreshes_after_interrupt() {
assert!(chat.status_line_branch_pending);
}

#[tokio::test]
async fn status_line_fast_mode_renders_on_and_off() {
let (mut chat, _rx, _op_rx) = make_chatwidget_manual(None).await;
chat.config.tui_status_line = Some(vec!["fast-mode".to_string()]);

chat.refresh_status_line();
assert_eq!(status_line_text(&chat), Some("Fast off".to_string()));

chat.set_service_tier(Some(ServiceTier::Fast));
chat.refresh_status_line();
assert_eq!(status_line_text(&chat), Some("Fast on".to_string()));
}

#[tokio::test]
async fn status_line_fast_mode_footer_snapshot() {
use ratatui::Terminal;
use ratatui::backend::TestBackend;

let (mut chat, _rx, _op_rx) = make_chatwidget_manual(None).await;
chat.show_welcome_banner = false;
chat.config.tui_status_line = Some(vec!["fast-mode".to_string()]);
chat.set_service_tier(Some(ServiceTier::Fast));
chat.refresh_status_line();

let width = 80;
let height = chat.desired_height(width);
let mut terminal = Terminal::new(TestBackend::new(width, height)).expect("create terminal");
terminal
.draw(|f| chat.render(f.area(), f.buffer_mut()))
.expect("draw fast-mode footer");
assert_snapshot!("status_line_fast_mode_footer", terminal.backend());
}

#[tokio::test]
async fn stream_recovery_restores_previous_status_header() {
let (mut chat, mut rx, _op_rx) = make_chatwidget_manual(None).await;
Expand Down
Loading