Add session header to chat widget (#3592)

<img width="570" height="332" alt="image"
src="https://github.com/user-attachments/assets/ca6dfcb0-f3a1-4b3e-978d-4f844ba77527"
/>
This commit is contained in:
Ahmed Ibrahim
2025-09-14 20:53:50 -04:00
committed by GitHub
parent c47febf221
commit ce984b2c71
8 changed files with 227 additions and 63 deletions

View File

@@ -0,0 +1,16 @@
pub(crate) struct SessionHeader {
model: String,
}
impl SessionHeader {
pub(crate) fn new(model: String) -> Self {
Self { model }
}
/// Updates the header's model text.
pub(crate) fn set_model(&mut self, model: &str) {
if self.model != model {
self.model = model.to_string();
}
}
}

View File

@@ -1,6 +1,5 @@
---
source: tui/src/chatwidget/tests.rs
assertion_line: 728
expression: terminal.backend()
---
" "

View File

@@ -1,6 +1,5 @@
---
source: tui/src/chatwidget/tests.rs
assertion_line: 794
expression: terminal.backend()
---
" "

View File

@@ -1,6 +1,5 @@
---
source: tui/src/chatwidget/tests.rs
assertion_line: 921
expression: terminal.backend()
---
" "

View File

@@ -79,7 +79,9 @@ fn final_answer_without_newline_is_flushed_immediately() {
// Set up a VT100 test terminal to capture ANSI visual output
let width: u16 = 80;
let height: u16 = 2000;
// Increased height to keep the initial banner/help lines in view even if
// the session renders an extra header line or minor layout changes occur.
let height: u16 = 2500;
let viewport = Rect::new(0, height - 1, width, 1);
let backend = ratatui::backend::TestBackend::new(width, height);
let mut terminal = crate::custom_terminal::Terminal::with_options(backend)
@@ -230,6 +232,7 @@ fn make_chatwidget_manual() -> (
bottom_pane: bottom,
active_exec_cell: None,
config: cfg.clone(),
session_header: SessionHeader::new(cfg.model.clone()),
initial_user_message: None,
token_info: None,
stream: StreamController::new(cfg),
@@ -773,10 +776,11 @@ async fn binary_size_transcript_snapshot() {
// Consider content only after the last session banner marker. Skip the transient
// 'thinking' header if present, and start from the first non-empty content line
// that follows. This keeps the snapshot stable across sessions.
const MARKER_PREFIX: &str = ">_ You are using OpenAI Codex in ";
const MARKER_PREFIX: &str =
"Describe a task to get started or try one of the following commands:";
let last_marker_line_idx = lines
.iter()
.rposition(|l| l.starts_with(MARKER_PREFIX))
.rposition(|l| l.trim_start().starts_with(MARKER_PREFIX))
.expect("marker not found in visible output");
// Prefer the first assistant content line (blockquote '>' prefix) after the marker;
// fallback to the first non-empty, non-'thinking' line.