fix: tighten up some logic around session timestamps and ids (#922)

* update `SessionConfigured` event to include the UUID for the session
* show the UUID in the Rust TUI
* use local timestamps in log files instead of UTC
* include timestamps in log file names for easier discovery
This commit is contained in:
Michael Bolin
2025-05-13 19:22:16 -07:00
committed by GitHub
parent 3c03c25e56
commit e6c206d19d
9 changed files with 101 additions and 77 deletions

View File

@@ -102,8 +102,6 @@ impl ChatWidget<'_> {
config,
};
let _ = chat_widget.submit_welcome_message();
if initial_prompt.is_some() || !initial_images.is_empty() {
let text = initial_prompt.unwrap_or_default();
let _ = chat_widget.submit_user_message_with_images(text, initial_images);
@@ -161,12 +159,6 @@ impl ChatWidget<'_> {
}
}
fn submit_welcome_message(&mut self) -> std::result::Result<(), SendError<AppEvent>> {
self.conversation_history.add_welcome_message(&self.config);
self.request_redraw()?;
Ok(())
}
fn submit_user_message(
&mut self,
text: String,
@@ -215,10 +207,10 @@ impl ChatWidget<'_> {
) -> std::result::Result<(), SendError<AppEvent>> {
let Event { id, msg } = event;
match msg {
EventMsg::SessionConfigured { model } => {
EventMsg::SessionConfigured(event) => {
// Record session information at the top of the conversation.
self.conversation_history
.add_session_info(&self.config, model);
.add_session_info(&self.config, event);
self.request_redraw()?;
}
EventMsg::AgentMessage { message } => {

View File

@@ -3,6 +3,7 @@ use crate::history_cell::HistoryCell;
use crate::history_cell::PatchEventType;
use codex_core::config::Config;
use codex_core::protocol::FileChange;
use codex_core::protocol::SessionConfiguredEvent;
use crossterm::event::KeyCode;
use crossterm::event::KeyEvent;
use ratatui::prelude::*;
@@ -162,8 +163,11 @@ impl ConversationHistoryWidget {
self.scroll_position = usize::MAX;
}
pub fn add_welcome_message(&mut self, config: &Config) {
self.add_to_history(HistoryCell::new_welcome_message(config));
/// Note `model` could differ from `config.model` if the agent decided to
/// use a different model than the one requested by the user.
pub fn add_session_info(&mut self, config: &Config, event: SessionConfiguredEvent) {
let is_first_event = self.history.is_empty();
self.add_to_history(HistoryCell::new_session_info(config, event, is_first_event));
}
pub fn add_user_message(&mut self, message: String) {
@@ -195,12 +199,6 @@ impl ConversationHistoryWidget {
self.add_to_history(HistoryCell::new_patch_event(event_type, changes));
}
/// Note `model` could differ from `config.model` if the agent decided to
/// use a different model than the one requested by the user.
pub fn add_session_info(&mut self, config: &Config, model: String) {
self.add_to_history(HistoryCell::new_session_info(config, model));
}
pub fn add_active_exec_command(&mut self, call_id: String, command: Vec<String>) {
self.add_to_history(HistoryCell::new_active_exec_command(call_id, command));
}

View File

@@ -2,6 +2,7 @@ use codex_ansi_escape::ansi_escape_line;
use codex_common::elapsed::format_duration;
use codex_core::config::Config;
use codex_core::protocol::FileChange;
use codex_core::protocol::SessionConfiguredEvent;
use ratatui::prelude::*;
use ratatui::style::Color;
use ratatui::style::Modifier;
@@ -94,29 +95,50 @@ pub(crate) enum HistoryCell {
const TOOL_CALL_MAX_LINES: usize = 5;
impl HistoryCell {
pub(crate) fn new_welcome_message(config: &Config) -> Self {
let mut lines: Vec<Line<'static>> = vec![
Line::from(vec![
"OpenAI ".into(),
"Codex".bold(),
" (research preview)".dim(),
]),
Line::from(""),
Line::from("codex session:".magenta().bold()),
];
pub(crate) fn new_session_info(
config: &Config,
event: SessionConfiguredEvent,
is_first_event: bool,
) -> Self {
let SessionConfiguredEvent { model, session_id } = event;
if is_first_event {
let mut lines: Vec<Line<'static>> = vec![
Line::from(vec![
"OpenAI ".into(),
"Codex".bold(),
" (research preview)".dim(),
]),
Line::from(""),
Line::from(vec![
"codex session".magenta().bold(),
" ".into(),
session_id.to_string().dim(),
]),
];
let entries = vec![
("workdir", config.cwd.display().to_string()),
("model", config.model.clone()),
("provider", config.model_provider_id.clone()),
("approval", format!("{:?}", config.approval_policy)),
("sandbox", format!("{:?}", config.sandbox_policy)),
];
for (key, value) in entries {
lines.push(Line::from(vec![format!("{key}: ").bold(), value.into()]));
let entries = vec![
("workdir", config.cwd.display().to_string()),
("model", config.model.clone()),
("provider", config.model_provider_id.clone()),
("approval", format!("{:?}", config.approval_policy)),
("sandbox", format!("{:?}", config.sandbox_policy)),
];
for (key, value) in entries {
lines.push(Line::from(vec![format!("{key}: ").bold(), value.into()]));
}
lines.push(Line::from(""));
HistoryCell::WelcomeMessage { lines }
} else if config.model == model {
HistoryCell::SessionInfo { lines: vec![] }
} else {
let lines = vec![
Line::from("model changed:".magenta().bold()),
Line::from(format!("requested: {}", config.model)),
Line::from(format!("used: {}", model)),
Line::from(""),
];
HistoryCell::SessionInfo { lines }
}
lines.push(Line::from(""));
HistoryCell::WelcomeMessage { lines }
}
pub(crate) fn new_user_prompt(message: String) -> Self {
@@ -296,20 +318,6 @@ impl HistoryCell {
HistoryCell::ErrorEvent { lines }
}
pub(crate) fn new_session_info(config: &Config, model: String) -> Self {
if config.model == model {
HistoryCell::SessionInfo { lines: vec![] }
} else {
let lines = vec![
Line::from("model changed:".magenta().bold()),
Line::from(format!("requested: {}", config.model)),
Line::from(format!("used: {}", model)),
Line::from(""),
];
HistoryCell::SessionInfo { lines }
}
}
/// Create a new `PendingPatch` cell that lists the filelevel summary of
/// a proposed patch. The summary lines should already be formatted (e.g.
/// "A path/to/file.rs").