-
Notifications
You must be signed in to change notification settings - Fork 5.6k
core(rollout): extract rollout module, add listing API, and return file heads #1634
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
codex-rs/core/src/session_manager.rs
Outdated
/// Directory layout: `~/.codex/sessions/YYYY/MM/DD/rollout-YYYY-MM-DDThh-mm-ss-<uuid>.jsonl` | ||
/// The first JSONL line is a `SessionMeta` object; subsequent lines are response/state records. | ||
/// | ||
/// Returned structure (earliest first): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to reverse this? i.e. latest first
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my bad
codex-rs/core/src/session_manager.rs
Outdated
.and_then(|s| s.parse::<u8>().ok()) | ||
.map(|m| (m, e.path())) | ||
}) | ||
.collect(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic is repeated a few times, do we want to refactor it into a helper function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
codex-rs/core/src/session_manager.rs
Outdated
/// Returned page of sessions. | ||
#[derive(Debug)] | ||
pub struct SessionsPage { | ||
pub sessions: Vec<Value>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Curious why we're using Value here instead of parsing the session files into SavedSession
objects?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's great idea. My PR is just too big. Maybe in the next PR I can do that. I don't see a problem now in returning the value because jsonl is a bunch of json objects.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM - reasonable to follow up on the SavedSession
change in a subsequent PR
codex-rs/core/src/session_manager.rs
Outdated
/// The first JSONL line is a `SessionMeta` object; subsequent lines are response/state records. | ||
/// | ||
/// Returned structure (latest (newest) first): | ||
fn traverse_directories( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure the complexity of pagination/filtering is worth it here.
We can easily list 1000 sessions in one page and I doubt users ever care about more than 10 last sessions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's right, but I think it wouldn't hurt to have, right? what if we want to construct a memory or sth that requires looking at a lot of sessions.
codex-rs/core/src/session_manager.rs
Outdated
.to_string(); | ||
|
||
match mode { | ||
SessionsMode::Full => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Who is using SessionsMode::Full?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The client when loading one session.
Summary Adds a new Review Nice addition—clean directory traversal, clear filtering logic, and thorough unit tests.
Overall, the feature is well-structured and ready to merge after any minor tweaks you deem worthwhile. |
codex-rs/core/src/session_manager.rs
Outdated
page_size: usize, | ||
cursor: Option<&str>, | ||
) -> io::Result<ConversationsPage> { | ||
if page_size == 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is special casing this? I think page_size == 0
should "just work" and it's not worth optimizing this case since it's not useful from the caller's perspective
codex-rs/core/src/session_manager.rs
Outdated
/// Pagination cursor token format: "<file_ts>|<uuid>" where `file_ts` matches the | ||
/// filename timestamp portion (YYYY-MM-DDThh-mm-ss) used in rollout filenames. | ||
/// The cursor orders files by timestamp desc, then UUID desc. | ||
fn parse_cursor_token(token: &str) -> Option<(OffsetDateTime, Uuid)> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fn parse_cursor_token(token: &str) -> Option<(OffsetDateTime, Uuid)> { | |
fn parse_cursor(cursor: &str) -> Option<(OffsetDateTime, Uuid)> { |
codex-rs/core/src/session_manager.rs
Outdated
fn parse_timestamp_uuid_from_filename(name: &str) -> Option<(OffsetDateTime, Uuid)> { | ||
// Format: rollout-YYYY-MM-DDThh-mm-ss-<uuid>.jsonl | ||
let core = name.strip_prefix("rollout-")?.strip_suffix(".jsonl")?; | ||
if core.len() < 37 { | ||
return None; | ||
} // need at least dt + '-' + 36 | ||
let uuid_part = &core[core.len() - 36..]; | ||
let dt_part = &core[..core.len() - 37]; // strip trailing '-' before uuid | ||
let Ok(uuid) = Uuid::parse_str(uuid_part) else { | ||
return None; | ||
}; | ||
let format: &[FormatItem] = | ||
format_description!("[year]-[month]-[day]T[hour]-[minute]-[second]"); | ||
let ts = PrimitiveDateTime::parse(dt_part, format).ok()?.assume_utc(); | ||
Some((ts, uuid)) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this work? It doesn't rely on hard coding offsets
use time::{OffsetDateTime, PrimitiveDateTime, macros::format_description};
use uuid::Uuid;
fn parse_timestamp_uuid_from_filename(name: &str) -> Option<(OffsetDateTime, Uuid)> {
// Expected: rollout-YYYY-MM-DDThh-mm-ss-<uuid>.jsonl
let core = name.strip_prefix("rollout-")?.strip_suffix(".jsonl")?;
// Split at the last '-' so the timestamp (which contains '-') stays intact.
let (ts_str, uuid_str) = core.rsplit_once('-')?;
let uuid = Uuid::parse_str(uuid_str).ok()?;
let fmt = format_description!("[year]-[month]-[day]T[hour]-[minute]-[second]");
let ts = PrimitiveDateTime::parse(ts_str, fmt).ok()?.assume_utc();
Some((ts, uuid))
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The uuid has -
in them. However, I did something less card coded. have a look.
codex-rs/core/src/session_manager.rs
Outdated
Ok(vec) | ||
} | ||
|
||
// Helper: collect files in `parent`, parse with `parse(name_str, path)` into arbitrary value. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Helper: collect files in `parent`, parse with `parse(name_str, path)` into arbitrary value. | |
// Collects files in a directory and parses them with `parse`. |
codex-rs/core/src/session_manager.rs
Outdated
let (anchor_ts, anchor_id) = | ||
anchor.unwrap_or_else(|| (OffsetDateTime::UNIX_EPOCH, Uuid::nil())); | ||
|
||
let year_dirs = collect_dirs_desc(&root, |s| s.parse::<i32>().ok())?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let year_dirs = collect_dirs_desc(&root, |s| s.parse::<i32>().ok())?; | |
let year_dirs = collect_dirs_desc(&root, |s| s.parse::<u16>().ok())?; |
Does this work
codex-rs/core/src/session_manager.rs
Outdated
)) | ||
} | ||
|
||
// Helper: collect immediate subdirectories of `parent`, parse their (string) names with `parse`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Helper: collect immediate subdirectories of `parent`, parse their (string) names with `parse`, | |
/// Collect immediate subdirectories of `parent`, parse their (string) names with `parse`, |
4f29301
to
88656cd
Compare
@codex review this in detail. |
You have reached your rate limits for code reviews, please try again later |
@codex review this in detail. |
You have reached your rate limits for code reviews, please try again later |
|
||
/// Load conversation file paths from disk using directory traversal. | ||
/// | ||
/// Directory layout: `~/.codex/sessions/YYYY/MM/DD/rollout-YYYY-MM-DDThh-mm-ss-<uuid>.jsonl` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe use just a uuid v7? and you won't need YYYYMMDDs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good idea.
…pagination test; document API fields
…ts and re-exports
…}; update traversal and tests
…r::list_conversations; move listing here and re-export APIs; remove session_manager
…and remove from mod
9ce793e
to
7733155
Compare
Work in progress for this issue: #2080 |
Uh oh!
There was an error while loading. Please reload this page.