Show model and reasoning effort near the top of task details (#50727)

## What changed

- Display reasoning effort alongside the model in the agents overview, using `Unknown` when unavailable.
- Place model, reasoning, project, and usage information before attention details, activity, and the last message.
- Truncate long model and reasoning values with an ellipsis to keep each on one line.

## Testing

Update overview snapshots for the new layout and extend fixtures to cover a known model and long model and custom reasoning values.

GitOrigin-RevId: 1f36e5e1e0ccf09a851f8982bbbe4fbc7d9c7461
This commit is contained in:
Eric Traut
2026-10-03 22:13:55 +00:00
committed by copyberry
parent 447eac3b81
commit 3e238776e8
15 changed files with 104 additions and 75 deletions
@@ -796,6 +796,10 @@ async fn agents_overview_details_show_available_attention_without_expanding_rows
threads[0].name = None;
threads[2].name = None;
threads[2].preview = "Investigate parser\nInclude edge cases\n".repeat(8);
threads[2].model = Some("provider/".repeat(12));
threads[2].reasoning_effort = Some(codex_protocol::openai_models::ReasoningEffort::Custom(
"deliberate".repeat(12),
));
app.agents_overview.threads = threads
.iter()
.cloned()
@@ -1297,6 +1301,12 @@ async fn shared_overview_shows_only_root_sessions() {
);
side.ephemeral = true;
threads.push(side);
let default_model = app
.model_catalog
.models
.first()
.expect("test model catalog");
threads[0].model = Some(default_model.model.clone());
let view = app.agents_overview_view(threads, /*selected_thread_id*/ None);
let (event_tx, mut event_rx) = tokio::sync::mpsc::unbounded_channel();
+24 -5
View File
@@ -38,6 +38,7 @@ use codex_app_server_protocol::Thread;
use codex_app_server_protocol::ThreadActiveFlag;
use codex_app_server_protocol::ThreadStatus;
use codex_protocol::ThreadId;
use codex_protocol::openai_models::ReasoningEffort;
use crossterm::event::KeyCode;
use crossterm::event::KeyEvent;
use crossterm::event::KeyModifiers;
@@ -432,6 +433,25 @@ impl AgentsOverviewView {
};
let (status, dot) = Self::status(row);
let width = usize::from(area.width);
let model = crate::line_truncation::truncate_line_with_ellipsis_if_overflow(
Line::from(vec![
"Model: ".dim(),
model_name(&row.thread).to_string().into(),
]),
width,
);
let reasoning = crate::line_truncation::truncate_line_with_ellipsis_if_overflow(
Line::from(vec![
"Reasoning: ".dim(),
row.thread
.reasoning_effort
.as_ref()
.map_or("Unknown", ReasoningEffort::as_str)
.to_string()
.into(),
]),
width,
);
let mut lines = vec![
Line::from("Task details".bold()),
Line::default(),
@@ -444,12 +464,11 @@ impl AgentsOverviewView {
),
Line::from(vec![dot, " ".into(), status.into()]),
Line::default(),
model,
reasoning,
Line::default(),
Line::from("Project".dim()),
Line::from(row.thread.cwd.display().to_string()),
Line::from(vec![
"Model: ".dim(),
model_name(&row.thread).to_string().into(),
]),
];
lines.extend(row.details.usage_lines.clone());
if let Some(branch) = row
@@ -488,7 +507,7 @@ impl AgentsOverviewView {
prompt.truncate(2);
prompt[1] = HyperlinkLine::new("…".dim().into());
}
let details_start = crate::wrapping::word_wrap_lines(lines[..4].to_vec(), width).len();
let details_start = prompt_start;
let mut lines = wrap(plain_hyperlink_lines(lines));
lines.extend(prompt);
if self.state().connection_notice.is_none() {
@@ -10,6 +10,12 @@ expression: normalize_agent_center_snapshot(&cached)
" › ○ Review parser │ Review parser "
" │ ○ Ready "
" │ "
" │ Model: Unknown "
" │ Reasoning: Unknown "
" │ "
" │ Project "
" │ /tmp/project "
" │ "
" │ Last message "
" │ ## Findings "
" │ "
@@ -20,10 +26,6 @@ expression: normalize_agent_center_snapshot(&cached)
" │ "
" │ let token = 1; "
" │ "
" │ Project "
" │ /tmp/project "
" │ Model: Unknown "
" │ "
" │ Prompt "
" │ Review parser and token handling. "
" │ "
@@ -39,6 +41,4 @@ expression: normalize_agent_center_snapshot(&cached)
" │ "
" │ "
" │ "
" │ "
" │ "
" ? help esc back ↑/↓ move enter open n new "
@@ -10,19 +10,19 @@ expression: "normalize_agent_center_snapshot(render_bottom_popup(&app.chat_widge
› ○ Review parser │ Review parser
│ ○ Ready
│
│ Model: Unknown
│ Reasoning: Unknown
│
│ Project
│ /tmp/project
│
│ Last message
│ let explanation = "A long code line
│ should wrap inside the task details
│ panel.";
│
│ Project
│ /tmp/project
│ Model: Unknown
│
│ Prompt
│ long prompt long prompt long prompt
│ …
│
│
│
? help esc back ↑/↓ move enter open n new
@@ -10,19 +10,19 @@ expression: "normalize_agent_center_snapshot(render_bottom_popup(&app.chat_widge
› ○ Review parser │ Review parser
│ ○ Ready
│
│ Model: Unknown
│ Reasoning: Unknown
│
│ Project
│ /tmp/project
│
│ Last message
│ Check Result
│ ━━━━━━━━ ━━━━━━━━
│ Parser Fixed
│
│ Project
│ /tmp/project
│ Model: Unknown
│
│ Prompt
│ long prompt long prompt long prompt
│ …
│
│
│
? help esc back ↑/↓ move enter open n new
@@ -10,11 +10,13 @@ expression: "render_bottom_popup(&app.chat_widget,\n100).replace(&test_path_disp
› ○ Legacy task │ Legacy task
│ ○ Ready
model-a 2 │
○ Recent task │ Project
○ Older task │ /tmp/project
│ Model: Unknown
model-b 1 │
○ Other model │ Prompt
○ Recent task │ Model: Unknown
○ Older task │ Reasoning: Unknown
│
model-b 1 │ Project
○ Other model │ /tmp/project
│
│ Prompt
│ Legacy task
│
│
@@ -23,6 +25,4 @@ expression: "render_bottom_popup(&app.chat_widget,\n100).replace(&test_path_disp
│
│
│
│
│
? help esc back ↑/↓ move enter open n new
@@ -10,9 +10,11 @@ expression: "screen(&view, 160, 22)"
› ○ Current task Ready now │ Current task
○ A longer task title that uses the available column voice Ready 5m ago │ ○ Ready
! Failed task Error 1h ago │
● Needs an answer Needs input 2h ago │ Project
● Working task Working 1d ago │ /tmp/project
○ Unloaded task Inactive 2d ago │ Model: Unknown
● Needs an answer Needs input 2h ago │ Model: Unknown
● Working task Working 1d ago │ Reasoning: Unknown
○ Unloaded task Inactive 2d ago │
│ Project
│ /tmp/project
│
│ Prompt
│ Current task
@@ -21,6 +23,4 @@ expression: "screen(&view, 160, 22)"
│
│
│
│
│
? help esc back ↑/↓ move enter open n new
@@ -9,20 +9,20 @@ expression: "render_bottom_popup(&app.chat_widget,\n96).replace(&format!(\"{proj
/tmp/project 2 │
› ● Review parser │ Review parser
○ Other task │ ● Needs input
│
│ Model: Unknown
│ Reasoning: Unknown
│
│ Project
│ /tmp/project
│ Tokens: 13K in · 4K out
│ Est. usage: 5 credits · ~$0.20
│
│ Needs attention
│ Which dependency version should I use?
│ Open task to review.
│
│ Project
│ /tmp/project
│ Model: Unknown
│ Tokens: 13K in · 4K out
│ Est. usage: 5 credits · ~$0.20
│
│ Prompt
│ Review parser
│
│
│
? help esc back ↑/↓ move enter open n new
@@ -10,9 +10,11 @@ expression: "render_bottom_popup(&app.chat_widget, 100)"
/tmp/project 2 │ Selected task
› ● Selected task │ ● Working
○ Vanished task │
│ Model: Unknown
│ Reasoning: Unknown
│
│ Project
│ /tmp/project
│ Model: Unknown
│
│ Prompt
│ Selected task
@@ -23,6 +25,4 @@ expression: "render_bottom_popup(&app.chat_widget, 100)"
│
│
│
│
│
Reconnect failed — agent list is stale; relaunch to retry
@@ -10,9 +10,11 @@ expression: "render_bottom_popup(&app.chat_widget, 100)"
/tmp/project 2 │ Selected task
› ● Selected task │ ● Working
○ Vanished task │
│ Model: Unknown
│ Reasoning: Unknown
│
│ Project
│ /tmp/project
│ Model: Unknown
│
│ Prompt
│ Selected task
@@ -23,6 +25,4 @@ expression: "render_bottom_popup(&app.chat_widget, 100)"
│
│
│
│
│
Reconnecting — agent list is stale
@@ -9,10 +9,12 @@ expression: "render_bottom_popup(&app.chat_widget, 100)"
/tmp/project 2 │
● New task │ Selected task
› ○ Selected task │ ○ Ready
│
│ Model: Unknown
│ Reasoning: Unknown
│
│ Project
│ /tmp/project
│ Model: Unknown
│
│ Prompt
│ Selected task
@@ -23,6 +25,4 @@ expression: "render_bottom_popup(&app.chat_widget, 100)"
│
│
│
│
│
Service v2.0.0 ≠ Codex CLI v0.0.0 · /daemon
@@ -10,19 +10,19 @@ expression: "render_bottom_popup(&app.chat_widget,\n96).replace(&format!(\"{proj
› ● Build the dashboard │ Build the dashboard
● Repair authentication │ ● Needs input
○ Review yesterday's changes │
│ Agent: Inspect keyboard shortcuts
│ Open task to review.
│ Waiting for approval.
│ Model: gpt-6.1-sol
│ Reasoning: Unknown
│
│ Project
│ /tmp/project
│ Model: Unknown
│
│ Agent: Inspect keyboard shortcuts
│ Open task to review.
│ Waiting for approval.
│
│ Prompt
│ Build the dashboard
│
│
│
│
│
? help esc back ↑/↓ move enter open n new
@@ -9,6 +9,12 @@ expression: "render_bottom_popup(&app.chat_widget,\n96).replace(&format!(\"{proj
/tmp/project 2 │
› ● Repair authentication │ Repair authentication
○ Investigate parser │ ● Needs input
│
│ Model: Unknown
│ Reasoning: Unknown
│
│ Project
│ /tmp/project
│
│ Agent: Check dependencies
│ Which dependency version should I use?
@@ -16,13 +22,7 @@ expression: "render_bottom_popup(&app.chat_widget,\n96).replace(&format!(\"{proj
│ Waiting for approval.
│ Waiting for your response.
│
│ Project
│ /tmp/project
│ Model: Unknown
│
│ Prompt
│ Repair authentication
│
│
│
? help esc back ↑/↓ move enter open n new
@@ -9,19 +9,19 @@ expression: "render_bottom_popup(&app.chat_widget,\n96).replace(&format!(\"{proj
/tmp/project 2 │
● Repair authentication │ Investigate parser
› ○ Investigate parser │ ○ Inactive
│
│ Model: provider/provider/provider/pro…
│ Reasoning: deliberatedeliberatedelibe…
│
│ Project
│ /tmp/project
│
│ Last message
│ Found the regression in the parser.
│ Found the regression in the parser.
│ Found the regression in the parser.
│ Found the regression in the parser.
│ Found the regression in the parser.
│ …
│
│ Project
│ /tmp/project
│ Model: Unknown
│
│ Prompt
│ Investigate parser
│ …
@@ -10,12 +10,14 @@ expression: "render_bottom_popup(&app.chat_widget,\n96).replace(&format!(\"{proj
› ● Check startup performance │ Check startup performance
│ ● Working
│
│ Latest activity
│ Checking cold-start regressions
│ Model: Unknown
│ Reasoning: Unknown
│
│ Project
│ /tmp/project
│ Model: Unknown
│
│ Latest activity
│ Checking cold-start regressions
│
│ Prompt
│ No prompt available.
@@ -23,6 +25,4 @@ expression: "render_bottom_popup(&app.chat_widget,\n96).replace(&format!(\"{proj
│
│
│
│
│
? help esc back ↑/↓ move enter open n new