mirror of
https://github.com/openai/codex.git
synced 2026-09-28 16:53:06 +08:00
Stop showing previous-session summaries when switching TUI sessions (#48626)
## What changed Remove the previous session's token usage and resume hint from the history shown when starting a fresh session or resuming another thread. Remove the unused summary helpers and their tests, and rename the fresh-session helper to `start_fresh_session`. GitOrigin-RevId: d808bdf355831d1c7b937b6a101ffbb33a805234
This commit is contained in:
@@ -487,25 +487,6 @@ pub enum ExitReason {
|
||||
Fatal(String),
|
||||
}
|
||||
|
||||
fn session_summary(
|
||||
token_usage: TokenUsage,
|
||||
thread_id: Option<ThreadId>,
|
||||
thread_name: Option<String>,
|
||||
rollout_path: Option<&Path>,
|
||||
) -> Option<SessionSummary> {
|
||||
let usage_line = (!token_usage.is_zero()).then(|| token_usage.to_string());
|
||||
let resume_hint = resume_hint_for_resumable_thread(thread_id, thread_name, rollout_path);
|
||||
|
||||
if usage_line.is_none() && resume_hint.is_none() {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(SessionSummary {
|
||||
usage_line,
|
||||
resume_hint,
|
||||
})
|
||||
}
|
||||
|
||||
fn resumable_thread(
|
||||
thread_id: Option<ThreadId>,
|
||||
thread_name: Option<String>,
|
||||
@@ -519,15 +500,6 @@ fn resumable_thread(
|
||||
})
|
||||
}
|
||||
|
||||
fn resume_hint_for_resumable_thread(
|
||||
thread_id: Option<ThreadId>,
|
||||
thread_name: Option<String>,
|
||||
rollout_path: Option<&Path>,
|
||||
) -> Option<String> {
|
||||
let thread = resumable_thread(thread_id, thread_name, rollout_path)?;
|
||||
codex_utils_cli::resume_hint(thread.thread_name.as_deref(), Some(thread.thread_id))
|
||||
}
|
||||
|
||||
fn rollout_path_is_resumable(rollout_path: &Path) -> bool {
|
||||
std::fs::metadata(rollout_path).is_ok_and(|metadata| metadata.is_file() && metadata.len() > 0)
|
||||
}
|
||||
@@ -541,12 +513,6 @@ fn errors_for_cwd(cwd: &Path, response: &SkillsListResponse) -> Vec<SkillErrorIn
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
struct SessionSummary {
|
||||
usage_line: Option<String>,
|
||||
resume_hint: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
struct InitialHistoryReplayBuffer {
|
||||
retained_lines: VecDeque<crate::terminal_hyperlinks::HyperlinkLine>,
|
||||
|
||||
@@ -131,9 +131,7 @@ async fn non_startup_history_dismisses_logo_until_a_new_thread() -> Result<()> {
|
||||
app.insert_history_cell(
|
||||
&mut tui,
|
||||
Box::new(history_cell::SessionNoticeCell(
|
||||
history_cell::PlainHistoryCell::new(vec![
|
||||
"Previous session usage and resume hint".into(),
|
||||
]),
|
||||
history_cell::PlainHistoryCell::new(vec!["Rate limit reset notice".into()]),
|
||||
)),
|
||||
);
|
||||
draw(&mut app, &mut tui, size)?;
|
||||
|
||||
@@ -149,7 +149,7 @@ impl App {
|
||||
AppEvent::PluginMentionsLoaded { ref cwd, .. }
|
||||
if cwds_differ(cwd, self.config.cwd.as_path()) => {}
|
||||
AppEvent::NewSession { name } => {
|
||||
self.start_fresh_session_with_summary_hint(
|
||||
self.start_fresh_session(
|
||||
tui, app_server, /*session_start_source*/ None,
|
||||
/*initial_user_message*/ None, name,
|
||||
)
|
||||
@@ -389,7 +389,7 @@ impl App {
|
||||
self.clear_terminal_ui(tui, /*redraw_header*/ false)?;
|
||||
self.reset_app_ui_state_after_clear();
|
||||
|
||||
self.start_fresh_session_with_summary_hint(
|
||||
self.start_fresh_session(
|
||||
tui,
|
||||
app_server,
|
||||
Some(ThreadStartSource::Clear),
|
||||
@@ -409,7 +409,7 @@ impl App {
|
||||
self.clear_terminal_ui(tui, /*redraw_header*/ false)?;
|
||||
self.reset_app_ui_state_after_clear();
|
||||
|
||||
self.start_fresh_session_with_summary_hint(
|
||||
self.start_fresh_session(
|
||||
tui,
|
||||
app_server,
|
||||
Some(ThreadStartSource::Clear),
|
||||
|
||||
@@ -929,7 +929,7 @@ impl App {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) async fn start_fresh_session_with_summary_hint(
|
||||
pub(super) async fn start_fresh_session(
|
||||
&mut self,
|
||||
tui: &mut tui::Tui,
|
||||
app_server: &mut AppServerSession,
|
||||
@@ -964,12 +964,6 @@ impl App {
|
||||
&self.cli_kv_overrides,
|
||||
&self.harness_overrides,
|
||||
);
|
||||
let summary = session_summary(
|
||||
self.chat_widget.token_usage(),
|
||||
self.chat_widget.thread_id(),
|
||||
self.chat_widget.thread_name(),
|
||||
self.chat_widget.rollout_path().as_deref(),
|
||||
);
|
||||
match app_server
|
||||
.start_thread_with_session_start_source(
|
||||
&self.local_settings,
|
||||
@@ -1016,25 +1010,8 @@ impl App {
|
||||
self.chat_widget.add_error_message(format!(
|
||||
"Failed to attach to fresh app-server thread: {err}"
|
||||
));
|
||||
} else {
|
||||
if let Some(err) = name_error {
|
||||
self.chat_widget.add_error_message(err);
|
||||
}
|
||||
if let Some(summary) = summary {
|
||||
let mut lines: Vec<Line<'static>> = Vec::new();
|
||||
if let Some(usage_line) = summary.usage_line {
|
||||
lines.push(usage_line.into());
|
||||
}
|
||||
if let Some(command) = summary.resume_hint {
|
||||
let spans =
|
||||
vec!["To continue this session, run ".into(), command.cyan()];
|
||||
lines.push(spans.into());
|
||||
}
|
||||
self.chat_widget
|
||||
.add_to_history(history_cell::SessionNoticeCell(
|
||||
history_cell::PlainHistoryCell::new(lines),
|
||||
));
|
||||
}
|
||||
} else if let Some(err) = name_error {
|
||||
self.chat_widget.add_error_message(err);
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
@@ -1287,12 +1264,6 @@ impl App {
|
||||
let baseline_permissions = RuntimePermissionProfileOverride::from_config(&resume_config);
|
||||
self.apply_runtime_policy_overrides(&mut resume_config, RuntimePolicyOverrideScope::All);
|
||||
|
||||
let summary = session_summary(
|
||||
self.chat_widget.token_usage(),
|
||||
self.chat_widget.thread_id(),
|
||||
self.chat_widget.thread_name(),
|
||||
self.chat_widget.rollout_path().as_deref(),
|
||||
);
|
||||
if let Some(history_mode) = target_session.history_mode {
|
||||
app_server.remember_thread_history_mode(target_session.thread_id, history_mode);
|
||||
}
|
||||
@@ -1387,17 +1358,6 @@ impl App {
|
||||
self.replay_agents_overview_requests(app_server, resumed_thread_id)
|
||||
.await;
|
||||
}
|
||||
if let Some(summary) = summary {
|
||||
let mut lines: Vec<Line<'static>> = Vec::new();
|
||||
if let Some(usage_line) = summary.usage_line {
|
||||
lines.push(usage_line.into());
|
||||
}
|
||||
if let Some(command) = summary.resume_hint {
|
||||
let spans = vec!["To continue this session, run ".into(), command.cyan()];
|
||||
lines.push(spans.into());
|
||||
}
|
||||
self.chat_widget.add_plain_history_lines(lines);
|
||||
}
|
||||
if !read_only {
|
||||
self.maybe_prompt_resume_paused_goal_after_resume(
|
||||
app_server,
|
||||
|
||||
@@ -80,7 +80,6 @@ mod resume_shutdown_tests;
|
||||
mod safety_buffering;
|
||||
#[path = "tests/session_lifecycle_requests.rs"]
|
||||
mod session_lifecycle_requests;
|
||||
mod session_summary;
|
||||
mod startup;
|
||||
#[path = "tests/startup_frame_tests.rs"]
|
||||
mod startup_frame_tests;
|
||||
|
||||
@@ -30,7 +30,7 @@ async fn new_session_preserves_vim_line_yank() -> Result<()> {
|
||||
)
|
||||
.await?;
|
||||
let mut tui = crate::tui::test_support::make_test_tui()?;
|
||||
app.start_fresh_session_with_summary_hint(
|
||||
app.start_fresh_session(
|
||||
&mut tui,
|
||||
&mut server,
|
||||
/*session_start_source*/ None,
|
||||
@@ -148,7 +148,7 @@ async fn replacement_uses_server_defaults_and_preserves_explicit_launch_settings
|
||||
_ => {}
|
||||
}
|
||||
let mut tui = crate::tui::test_support::make_test_tui()?;
|
||||
app.start_fresh_session_with_summary_hint(
|
||||
app.start_fresh_session(
|
||||
&mut tui,
|
||||
&mut server,
|
||||
/*session_start_source*/ None,
|
||||
@@ -215,7 +215,7 @@ async fn replacement_failure_keeps_current_task_and_restores_input() -> Result<(
|
||||
std::fs::write(home.path().join("config.toml"), "invalid = [")?;
|
||||
}
|
||||
let mut tui = crate::tui::test_support::make_test_tui()?;
|
||||
app.start_fresh_session_with_summary_hint(
|
||||
app.start_fresh_session(
|
||||
&mut tui,
|
||||
&mut server,
|
||||
/*session_start_source*/ None,
|
||||
@@ -283,7 +283,7 @@ async fn replacement_preserves_remote_launch_paths_and_older_servers() -> Result
|
||||
.await?;
|
||||
let mut server = server.with_remote_cwd_override(remote_cwd.clone());
|
||||
let mut tui = crate::tui::test_support::make_test_tui()?;
|
||||
app.start_fresh_session_with_summary_hint(
|
||||
app.start_fresh_session(
|
||||
&mut tui,
|
||||
&mut server,
|
||||
/*session_start_source*/ None,
|
||||
|
||||
@@ -3293,7 +3293,7 @@ model_reasoning_effort = "low"
|
||||
)
|
||||
.await?;
|
||||
let mut tui = crate::tui::test_support::make_test_tui()?;
|
||||
app.start_fresh_session_with_summary_hint(
|
||||
app.start_fresh_session(
|
||||
&mut tui,
|
||||
&mut server,
|
||||
/*session_start_source*/ None,
|
||||
@@ -3656,7 +3656,7 @@ terminal_visualization_instructions = true
|
||||
.map(|entry| &entry.owner),
|
||||
Some(&crate::worktree_browser::Owner::Unavailable(missing_owner))
|
||||
);
|
||||
app.start_fresh_session_with_summary_hint(
|
||||
app.start_fresh_session(
|
||||
&mut tui,
|
||||
&mut server,
|
||||
/*session_start_source*/ None,
|
||||
@@ -3819,7 +3819,7 @@ async fn changing_directory_preserves_project_trust_permissions_history_and_hook
|
||||
let (rec, plain, req) = (recorded_params, crate::key_hint::plain, &requests);
|
||||
let mut tui = crate::tui::test_support::make_test_tui()?;
|
||||
let (source, message, name) = (None, None, Some("Previous project".to_string()));
|
||||
app.start_fresh_session_with_summary_hint(&mut tui, &mut server, source, message, name)
|
||||
app.start_fresh_session(&mut tui, &mut server, source, message, name)
|
||||
.await;
|
||||
let original = app.chat_widget.thread_id().expect("original thread");
|
||||
let rollout = app.chat_widget.rollout_path().expect("original rollout");
|
||||
@@ -4115,7 +4115,7 @@ fn fresh_session_applies_requested_name() -> Result<()> {
|
||||
.await?;
|
||||
let mut tui = crate::tui::test_support::make_test_tui()?;
|
||||
|
||||
app.start_fresh_session_with_summary_hint(
|
||||
app.start_fresh_session(
|
||||
&mut tui,
|
||||
&mut app_server,
|
||||
/*session_start_source*/ None,
|
||||
@@ -4293,7 +4293,7 @@ fn session_lifecycle_avoids_redundant_subagent_metadata_reads() -> Result<()> {
|
||||
);
|
||||
assert!(matches!(take_backfill_counts(&requests), (0, 0) | (0, 1)));
|
||||
|
||||
app.start_fresh_session_with_summary_hint(
|
||||
app.start_fresh_session(
|
||||
&mut tui,
|
||||
&mut app_server,
|
||||
/*session_start_source*/ None,
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
use super::*;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
#[tokio::test]
|
||||
async fn session_summary_skips_when_no_usage_or_resume_hint() {
|
||||
assert!(
|
||||
session_summary(
|
||||
TokenUsage::default(),
|
||||
/*thread_id*/ None,
|
||||
/*thread_name*/ None,
|
||||
/*rollout_path*/ None,
|
||||
)
|
||||
.is_none()
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn session_summary_skips_resume_hint_until_rollout_exists() {
|
||||
let usage = TokenUsage::default();
|
||||
let conversation = ThreadId::from_string("123e4567-e89b-12d3-a456-426614174000").unwrap();
|
||||
let temp_dir = tempdir().expect("temp dir");
|
||||
let rollout_path = temp_dir.path().join("rollout.jsonl");
|
||||
|
||||
assert!(
|
||||
session_summary(
|
||||
usage,
|
||||
Some(conversation),
|
||||
/*thread_name*/ None,
|
||||
Some(&rollout_path),
|
||||
)
|
||||
.is_none()
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn session_summary_includes_resume_hint_for_persisted_rollout() {
|
||||
let usage = TokenUsage {
|
||||
input_tokens: 10,
|
||||
output_tokens: 2,
|
||||
total_tokens: 12,
|
||||
..Default::default()
|
||||
};
|
||||
let conversation = ThreadId::from_string("123e4567-e89b-12d3-a456-426614174000").unwrap();
|
||||
let temp_dir = tempdir().expect("temp dir");
|
||||
let rollout_path = temp_dir.path().join("rollout.jsonl");
|
||||
std::fs::write(&rollout_path, "{}\n").expect("write rollout");
|
||||
|
||||
let summary = session_summary(
|
||||
usage,
|
||||
Some(conversation),
|
||||
/*thread_name*/ None,
|
||||
Some(&rollout_path),
|
||||
)
|
||||
.expect("summary");
|
||||
assert_eq!(
|
||||
summary.usage_line,
|
||||
Some("Token usage: total=12 input=10 output=2".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
summary.resume_hint,
|
||||
Some("codex resume 123e4567-e89b-12d3-a456-426614174000".to_string())
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn session_summary_names_picker_item_when_thread_has_name() {
|
||||
let usage = TokenUsage {
|
||||
input_tokens: 10,
|
||||
output_tokens: 2,
|
||||
total_tokens: 12,
|
||||
..Default::default()
|
||||
};
|
||||
let conversation = ThreadId::from_string("123e4567-e89b-12d3-a456-426614174000").unwrap();
|
||||
let temp_dir = tempdir().expect("temp dir");
|
||||
let rollout_path = temp_dir.path().join("rollout.jsonl");
|
||||
std::fs::write(&rollout_path, "{}\n").expect("write rollout");
|
||||
|
||||
let summary = session_summary(
|
||||
usage,
|
||||
Some(conversation),
|
||||
Some("my-session".to_string()),
|
||||
Some(&rollout_path),
|
||||
)
|
||||
.expect("summary");
|
||||
assert_eq!(
|
||||
summary.resume_hint,
|
||||
Some(
|
||||
"codex resume, then select my-session (123e4567-e89b-12d3-a456-426614174000)"
|
||||
.to_string()
|
||||
)
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user