mirror of
https://github.com/openai/codex.git
synced 2026-04-29 00:55:38 +00:00
Unify rollout reconstruction with resume/fork TurnContext hydration (#12612)
## Summary This PR unifies rollout history reconstruction and resume/fork metadata hydration under a single `Session::reconstruct_history_from_rollout` implementation. The key change from main is that replay metadata now comes from the same reconstruction pass that rebuilds model-visible history, instead of doing a second bespoke rollout scan to recover `previous_model` / `reference_context_item`. ## What Changed ### Unified reconstruction output `reconstruct_history_from_rollout` now returns a single `RolloutReconstruction` bundle containing: - rebuilt `history` - `previous_model` - `reference_context_item` Resume and fork both consume that shared output directly. ### Reverse replay core The reconstruction logic moved into `codex-rs/core/src/codex/rollout_reconstruction.rs` and now scans rollout items newest-to-oldest. That reverse pass: - derives `previous_model` - derives whether `reference_context_item` is preserved or cleared - stops early once it has both resume metadata and a surviving `replacement_history` checkpoint History materialization is still bridged eagerly for now by replaying only the surviving suffix forward, which keeps the history result stable while moving the control flow toward the future lazy reverse loader design. ### Removed bespoke context lookup This deletes `last_rollout_regular_turn_context_lookup` and its separate compaction-aware scan. The previous model / baseline metadata is now computed from the same replay state that rebuilds history, so resume/fork cannot drift from the reconstructed transcript view. ### `TurnContextItem` persistence contract `TurnContextItem` is now treated as the replay source of truth for durable model-visible baselines. This PR keeps the following contract explicit: - persist `TurnContextItem` for the first real user turn so resume can recover `previous_model` - persist it for later turns that emit model-visible context updates - if mid-turn compaction reinjects full initial context into replacement history, persist a fresh `TurnContextItem` after `Compacted` so resume/fork can re-establish the baseline from the rewritten history - do not treat manual compaction or pre-sampling compaction as creating a new durable baseline on their own ## Behavior Preserved - rollback replay stays aligned with `drop_last_n_user_turns` - rollback skips only user turns - incomplete active user turns are dropped before older finalized turns when rollback applies - unmatched aborts do not consume the current active turn - missing abort IDs still conservatively clear stale compaction state - compaction clears `reference_context_item` until a later `TurnContextItem` re-establishes it - `previous_model` still comes from the newest surviving user turn that established one ## Tests Targeted validation run for the current branch shape: - `cd codex-rs && cargo test -p codex-core --lib codex::rollout_reconstruction_tests -- --nocapture` - `cd codex-rs && just fmt` The branch also extracts the rollout reconstruction tests into `codex-rs/core/src/codex/rollout_reconstruction_tests.rs` so this logic has a dedicated home instead of living inline in `codex.rs`.
This commit is contained in:
committed by
GitHub
parent
6046ca19ba
commit
695957a348
@@ -362,7 +362,7 @@ async fn summarize_context_three_requests_and_instructions() {
|
||||
codex.submit(Op::Shutdown).await.unwrap();
|
||||
wait_for_event(&codex, |ev| matches!(ev, EventMsg::ShutdownComplete)).await;
|
||||
|
||||
// Verify rollout contains regular sampling TurnContext entries and a Compacted entry.
|
||||
// Verify rollout contains user-turn TurnContext entries and a Compacted entry.
|
||||
println!("rollout path: {}", rollout_path.display());
|
||||
let text = std::fs::read_to_string(&rollout_path).unwrap_or_else(|e| {
|
||||
panic!(
|
||||
@@ -393,9 +393,9 @@ async fn summarize_context_three_requests_and_instructions() {
|
||||
}
|
||||
}
|
||||
|
||||
assert!(
|
||||
regular_turn_context_count == 2,
|
||||
"expected two regular sampling TurnContext entries in rollout"
|
||||
assert_eq!(
|
||||
regular_turn_context_count, 2,
|
||||
"rollout should contain one TurnContext entry per real user turn"
|
||||
);
|
||||
assert!(
|
||||
saw_compacted_summary,
|
||||
@@ -2080,9 +2080,9 @@ async fn auto_compact_persists_rollout_entries() {
|
||||
}
|
||||
}
|
||||
|
||||
assert!(
|
||||
turn_context_count >= 2,
|
||||
"expected at least two turn context entries, got {turn_context_count}"
|
||||
assert_eq!(
|
||||
turn_context_count, 3,
|
||||
"rollout should contain one TurnContext entry per real user turn"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user