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
11 changes: 0 additions & 11 deletions codex-rs/core/src/codex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ use crate::protocol::ReviewDecision;
use crate::protocol::ReviewOutputEvent;
use crate::protocol::SandboxPolicy;
use crate::protocol::SessionConfiguredEvent;
use crate::protocol::SessionRenamedEvent;
use crate::protocol::StreamErrorEvent;
use crate::protocol::Submission;
use crate::protocol::TokenCountEvent;
Expand Down Expand Up @@ -1508,16 +1507,6 @@ async fn submission_loop(
};
sess.send_event(event).await;
}
Op::SetSessionName { name } => {
// Persist a rename event and notify the client. We rely on the
// recorder's filtering to include this in the rollout.
let sub_id = sub.id.clone();
let event = Event {
id: sub_id,
msg: EventMsg::SessionRenamed(SessionRenamedEvent { name }),
};
sess.send_event(event).await;
}
Op::Review { review_request } => {
spawn_review_thread(
sess.clone(),
Expand Down
64 changes: 18 additions & 46 deletions codex-rs/core/src/rollout/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ use super::SESSIONS_SUBDIR;
use crate::protocol::EventMsg;
use codex_protocol::protocol::RolloutItem;
use codex_protocol::protocol::RolloutLine;
use codex_protocol::protocol::SessionRenamedEvent;
use codex_protocol::protocol::SessionSource;

/// Returned page of conversation summaries.
Expand All @@ -42,8 +41,6 @@ pub struct ConversationItem {
pub head: Vec<serde_json::Value>,
/// Last up to `TAIL_RECORD_LIMIT` JSONL response records parsed as JSON.
pub tail: Vec<serde_json::Value>,
/// Latest human-friendly session name, if any.
pub name: Option<String>,
/// RFC3339 timestamp string for when the session was created, if available.
pub created_at: Option<String>,
/// RFC3339 timestamp string for the most recent response in the tail, if available.
Expand All @@ -59,7 +56,6 @@ struct HeadTailSummary {
source: Option<SessionSource>,
created_at: Option<String>,
updated_at: Option<String>,
name: Option<String>,
}

/// Hard cap to bound worst‑case work per request.
Expand Down Expand Up @@ -226,7 +222,6 @@ async fn traverse_directories_for_paths(
path,
head,
tail,
name: summary.name,
created_at,
updated_at,
});
Expand Down Expand Up @@ -387,69 +382,57 @@ async fn read_head_and_tail(
if matches!(ev, EventMsg::UserMessage(_)) {
summary.saw_user_event = true;
}
if let EventMsg::SessionRenamed(SessionRenamedEvent { name }) = ev {
summary.name = Some(name);
}
}
}
}

if tail_limit != 0 {
let (tail, updated_at, latest_name) = read_tail_records(path, tail_limit).await?;
let (tail, updated_at) = read_tail_records(path, tail_limit).await?;
summary.tail = tail;
summary.updated_at = updated_at;
// Prefer the most recent rename event discovered from the tail scan; fallback to any name seen in head.
if latest_name.is_some() {
summary.name = latest_name;
}
}
Ok(summary)
}

async fn read_tail_records(
path: &Path,
max_records: usize,
) -> io::Result<(Vec<serde_json::Value>, Option<String>, Option<String>)> {
) -> io::Result<(Vec<serde_json::Value>, Option<String>)> {
use std::io::SeekFrom;
use tokio::io::AsyncReadExt;
use tokio::io::AsyncSeekExt;

if max_records == 0 {
return Ok((Vec::new(), None, None));
return Ok((Vec::new(), None));
}

const CHUNK_SIZE: usize = 8192;

let mut file = tokio::fs::File::open(path).await?;
let mut pos = file.seek(SeekFrom::End(0)).await?;
if pos == 0 {
return Ok((Vec::new(), None, None));
return Ok((Vec::new(), None));
}

let mut buffer: Vec<u8> = Vec::new();
let mut latest_timestamp: Option<String> = None;
let mut latest_name: Option<String> = None;

loop {
let slice_start = match (pos > 0, buffer.iter().position(|&b| b == b'\n')) {
(true, Some(idx)) => idx + 1,
_ => 0,
};
let (tail, newest_ts, name_opt) =
collect_last_response_values(&buffer[slice_start..], max_records);
let (tail, newest_ts) = collect_last_response_values(&buffer[slice_start..], max_records);
if latest_timestamp.is_none() {
latest_timestamp = newest_ts.clone();
}
if latest_name.is_none() {
latest_name = name_opt.clone();
}
if tail.len() >= max_records || pos == 0 {
return Ok((tail, latest_timestamp.or(newest_ts), latest_name));
return Ok((tail, latest_timestamp.or(newest_ts)));
}

let read_size = CHUNK_SIZE.min(pos as usize);
if read_size == 0 {
return Ok((tail, latest_timestamp.or(newest_ts), latest_name));
return Ok((tail, latest_timestamp.or(newest_ts)));
}
pos -= read_size as u64;
file.seek(SeekFrom::Start(pos)).await?;
Expand All @@ -463,17 +446,16 @@ async fn read_tail_records(
fn collect_last_response_values(
buffer: &[u8],
max_records: usize,
) -> (Vec<serde_json::Value>, Option<String>, Option<String>) {
) -> (Vec<serde_json::Value>, Option<String>) {
use std::borrow::Cow;

if buffer.is_empty() || max_records == 0 {
return (Vec::new(), None, None);
return (Vec::new(), None);
}

let text: Cow<'_, str> = String::from_utf8_lossy(buffer);
let mut collected_rev: Vec<serde_json::Value> = Vec::new();
let mut latest_timestamp: Option<String> = None;
let mut latest_name: Option<String> = None;
for line in text.lines().rev() {
let trimmed = line.trim();
if trimmed.is_empty() {
Expand All @@ -482,30 +464,20 @@ fn collect_last_response_values(
let parsed: serde_json::Result<RolloutLine> = serde_json::from_str(trimmed);
let Ok(rollout_line) = parsed else { continue };
let RolloutLine { timestamp, item } = rollout_line;
match item {
RolloutItem::ResponseItem(item) => {
if let Ok(val) = serde_json::to_value(&item) {
if latest_timestamp.is_none() {
latest_timestamp = Some(timestamp.clone());
}
collected_rev.push(val);
if collected_rev.len() == max_records {
break;
}
}
if let RolloutItem::ResponseItem(item) = item
&& let Ok(val) = serde_json::to_value(&item)
{
if latest_timestamp.is_none() {
latest_timestamp = Some(timestamp.clone());
}
RolloutItem::EventMsg(ev) => {
if latest_name.is_none()
&& let EventMsg::SessionRenamed(SessionRenamedEvent { name }) = ev
{
latest_name = Some(name);
}
collected_rev.push(val);
if collected_rev.len() == max_records {
break;
}
_ => {}
}
}
collected_rev.reverse();
(collected_rev, latest_timestamp, latest_name)
(collected_rev, latest_timestamp)
}

/// Locate a recorded conversation rollout file by its UUID string using the existing
Expand Down
1 change: 0 additions & 1 deletion codex-rs/core/src/rollout/policy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ pub(crate) fn should_persist_event_msg(ev: &EventMsg) -> bool {
| EventMsg::AgentMessage(_)
| EventMsg::AgentReasoning(_)
| EventMsg::AgentReasoningRawContent(_)
| EventMsg::SessionRenamed(_)
| EventMsg::TokenCount(_)
| EventMsg::EnteredReviewMode(_)
| EventMsg::ExitedReviewMode(_)
Expand Down
12 changes: 0 additions & 12 deletions codex-rs/core/src/rollout/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,23 +196,20 @@ async fn test_list_conversations_latest_first() {
path: p1,
head: head_3,
tail: Vec::new(),
name: None,
created_at: Some("2025-01-03T12-00-00".into()),
updated_at: Some("2025-01-03T12-00-00".into()),
},
ConversationItem {
path: p2,
head: head_2,
tail: Vec::new(),
name: None,
created_at: Some("2025-01-02T12-00-00".into()),
updated_at: Some("2025-01-02T12-00-00".into()),
},
ConversationItem {
path: p3,
head: head_1,
tail: Vec::new(),
name: None,
created_at: Some("2025-01-01T12-00-00".into()),
updated_at: Some("2025-01-01T12-00-00".into()),
},
Expand Down Expand Up @@ -320,15 +317,13 @@ async fn test_pagination_cursor() {
path: p5,
head: head_5,
tail: Vec::new(),
name: None,
created_at: Some("2025-03-05T09-00-00".into()),
updated_at: Some("2025-03-05T09-00-00".into()),
},
ConversationItem {
path: p4,
head: head_4,
tail: Vec::new(),
name: None,
created_at: Some("2025-03-04T09-00-00".into()),
updated_at: Some("2025-03-04T09-00-00".into()),
},
Expand Down Expand Up @@ -385,15 +380,13 @@ async fn test_pagination_cursor() {
path: p3,
head: head_3,
tail: Vec::new(),
name: None,
created_at: Some("2025-03-03T09-00-00".into()),
updated_at: Some("2025-03-03T09-00-00".into()),
},
ConversationItem {
path: p2,
head: head_2,
tail: Vec::new(),
name: None,
created_at: Some("2025-03-02T09-00-00".into()),
updated_at: Some("2025-03-02T09-00-00".into()),
},
Expand Down Expand Up @@ -434,7 +427,6 @@ async fn test_pagination_cursor() {
path: p1,
head: head_1,
tail: Vec::new(),
name: None,
created_at: Some("2025-03-01T09-00-00".into()),
updated_at: Some("2025-03-01T09-00-00".into()),
}],
Expand Down Expand Up @@ -483,7 +475,6 @@ async fn test_get_conversation_contents() {
path: expected_path,
head: expected_head,
tail: Vec::new(),
name: None,
created_at: Some(ts.into()),
updated_at: Some(ts.into()),
}],
Expand Down Expand Up @@ -832,15 +823,13 @@ async fn test_stable_ordering_same_second_pagination() {
path: p3,
head: head(u3),
tail: Vec::new(),
name: None,
created_at: Some(ts.to_string()),
updated_at: Some(ts.to_string()),
},
ConversationItem {
path: p2,
head: head(u2),
tail: Vec::new(),
name: None,
created_at: Some(ts.to_string()),
updated_at: Some(ts.to_string()),
},
Expand Down Expand Up @@ -871,7 +860,6 @@ async fn test_stable_ordering_same_second_pagination() {
path: p1,
head: head(u1),
tail: Vec::new(),
name: None,
created_at: Some(ts.to_string()),
updated_at: Some(ts.to_string()),
}],
Expand Down
1 change: 0 additions & 1 deletion codex-rs/exec/src/event_processor_with_human_output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,6 @@ impl EventProcessor for EventProcessorWithHumanOutput {
},
EventMsg::ShutdownComplete => return CodexStatus::Shutdown,
EventMsg::ConversationPath(_) => {}
EventMsg::SessionRenamed(_) => {}
EventMsg::UserMessage(_) => {}
EventMsg::EnteredReviewMode(_) => {}
EventMsg::ExitedReviewMode(_) => {}
Expand Down
1 change: 0 additions & 1 deletion codex-rs/mcp-server/src/codex_tool_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,6 @@ async fn run_codex_tool_session_inner(
| EventMsg::TurnAborted(_)
| EventMsg::ConversationPath(_)
| EventMsg::UserMessage(_)
| EventMsg::SessionRenamed(_)
| EventMsg::ShutdownComplete
| EventMsg::ViewImageToolCall(_)
| EventMsg::EnteredReviewMode(_)
Expand Down
13 changes: 0 additions & 13 deletions codex-rs/protocol/src/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,11 +171,6 @@ pub enum Op {
/// to generate a summary which will be returned as an AgentMessage event.
Compact,

/// Set a human-friendly name for the current session.
/// The agent will persist this to the rollout as an event so that UIs can
/// surface it when listing sessions.
SetSessionName { name: String },

/// Request a code review from the agent.
Review { review_request: ReviewRequest },

Expand Down Expand Up @@ -463,9 +458,6 @@ pub enum EventMsg {
/// Signaled when the model begins a new reasoning summary section (e.g., a new titled block).
AgentReasoningSectionBreak(AgentReasoningSectionBreakEvent),

/// Session was given a human-friendly name by the user.
SessionRenamed(SessionRenamedEvent),

/// Ack the client's configure message.
SessionConfigured(SessionConfiguredEvent),

Expand Down Expand Up @@ -903,11 +895,6 @@ pub struct WebSearchEndEvent {
pub query: String,
}

#[derive(Debug, Clone, Deserialize, Serialize, TS)]
pub struct SessionRenamedEvent {
pub name: String,
}

/// Response payload for `Op::GetHistory` containing the current session's
/// in-memory transcript.
#[derive(Debug, Clone, Deserialize, Serialize, TS)]
Expand Down
3 changes: 0 additions & 3 deletions codex-rs/tui/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,9 +381,6 @@ impl App {
AppEvent::OpenReviewCustomPrompt => {
self.chat_widget.show_review_custom_prompt();
}
AppEvent::SetSessionName(name) => {
self.chat_widget.begin_set_session_name(name);
}
AppEvent::FullScreenApprovalRequest(request) => match request {
ApprovalRequest::ApplyPatch { cwd, changes, .. } => {
let _ = tui.enter_alt_screen();
Expand Down
3 changes: 0 additions & 3 deletions codex-rs/tui/src/app_event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,6 @@ pub(crate) enum AppEvent {
/// Open the custom prompt option from the review popup.
OpenReviewCustomPrompt,

/// Begin setting a human-readable name for the current session.
SetSessionName(String),

/// Open the approval popup.
FullScreenApprovalRequest(ApprovalRequest),
}
2 changes: 1 addition & 1 deletion codex-rs/tui/src/bottom_pane/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub mod custom_prompt_view;
mod file_search_popup;
mod footer;
mod list_selection_view;
pub mod prompt_args;
mod prompt_args;
pub(crate) use list_selection_view::SelectionViewParams;
mod paste_burst;
pub mod popup_consts;
Expand Down
Loading
Loading