mirror of
https://github.com/openai/codex.git
synced 2026-11-13 14:46:14 +00:00
Distinguish rollout IDs from thread IDs (#38127)
## Why `thread/revert` preserves a thread ID while creating a new immutable rollout. Rollout persistence and filesystem fallback therefore need to distinguish the logical thread from each physical history file. ## What changed - Add a `RolloutId` alias and canonical filename parsing for both ordinary rollouts and reverted rollouts with a distinct rollout ID. - Allow the recorder to create a replacement rollout without changing the thread ID, and add lookup by either the stable thread ID or an exact rollout ID. - Index history references and compression safety checks by rollout ID so multiple rollouts for one thread remain distinct. - Preserve the rollout path selected in SQLite when filesystem repair encounters another rollout for the same thread. ## Testing Add coverage for filename round trips, replacement rollout metadata, thread and rollout lookup, reference indexing, compression, and database path preservation. GitOrigin-RevId: 14b1d0b4a9432b341a1307afc0abadd507e7ae7d
This commit is contained in:
1 parent
2230d64464
commit
4ef836f883
18 files changed
+513
-178
No files matched your search
@@ -23,6 +23,7 @@ use crate::INTERACTIVE_SESSION_SOURCES;
|
||||
use crate::ResponseItemEnvelope;
|
||||
use crate::RolloutItem;
|
||||
use crate::RolloutLine;
|
||||
use crate::find_rollout_path_by_rollout_id;
|
||||
use crate::find_thread_path_by_id_str;
|
||||
use crate::list::Cursor;
|
||||
use crate::list::ThreadItem;
|
||||
@@ -132,7 +133,53 @@ async fn find_thread_path_falls_back_when_db_path_is_stale() {
|
||||
.await
|
||||
.expect("lookup should succeed");
|
||||
assert_eq!(found, Some(fs_rollout_path.clone()));
|
||||
assert_state_db_rollout_path(home, thread_id, Some(fs_rollout_path.as_path())).await;
|
||||
assert_state_db_rollout_path(home, thread_id, Some(stale_db_path.as_path())).await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn filesystem_lookup_distinguishes_thread_ids_from_rollout_ids() {
|
||||
let temp = TempDir::new().unwrap();
|
||||
let home = temp.path();
|
||||
let thread_uuid = Uuid::from_u128(401);
|
||||
let rollout_uuid = Uuid::from_u128(402);
|
||||
let original_ts = "2025-01-03T13-00-00";
|
||||
let reverted_ts = "2025-01-04T13-00-00";
|
||||
write_session_file(
|
||||
home,
|
||||
original_ts,
|
||||
thread_uuid,
|
||||
/*num_records*/ 1,
|
||||
Some(SessionSource::Cli),
|
||||
)
|
||||
.unwrap();
|
||||
write_session_file(
|
||||
home,
|
||||
reverted_ts,
|
||||
thread_uuid,
|
||||
/*num_records*/ 1,
|
||||
Some(SessionSource::Cli),
|
||||
)
|
||||
.unwrap();
|
||||
let reverted_source = home.join(format!(
|
||||
"sessions/2025/01/04/rollout-{reverted_ts}-{thread_uuid}.jsonl"
|
||||
));
|
||||
let reverted_path = home.join(format!(
|
||||
"sessions/2025/01/04/rollout-{reverted_ts}-{thread_uuid}_{rollout_uuid}.jsonl"
|
||||
));
|
||||
fs::rename(reverted_source, reverted_path.as_path()).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
find_thread_path_by_id_str(home, &thread_uuid.to_string(), /*state_db_ctx*/ None)
|
||||
.await
|
||||
.unwrap(),
|
||||
Some(reverted_path.clone())
|
||||
);
|
||||
assert_eq!(
|
||||
find_rollout_path_by_rollout_id(home, thread_id_from_uuid(rollout_uuid))
|
||||
.await
|
||||
.unwrap(),
|
||||
Some(reverted_path)
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -212,7 +259,7 @@ async fn find_thread_path_falls_back_when_db_path_points_to_another_thread() {
|
||||
.await
|
||||
.expect("lookup should succeed");
|
||||
assert_eq!(found, Some(fs_rollout_path.clone()));
|
||||
assert_state_db_rollout_path(home, thread_id, Some(fs_rollout_path.as_path())).await;
|
||||
assert_state_db_rollout_path(home, thread_id, Some(stale_db_path.as_path())).await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
||||
Reference in new issue
Block a user