Codex Handbook
core/src/session/rollout_reconstruction_tests.rs 1618 lines
use super::*;use super::tests::make_session_and_context;use codex_protocol::AgentPath;use codex_protocol::ThreadId;use codex_protocol::models::ContentItem;use codex_protocol::models::ResponseItem;use codex_protocol::protocol::CompactedItem;use codex_protocol::protocol::InitialHistory;use codex_protocol::protocol::InterAgentCommunication;use codex_protocol::protocol::ResumedHistory;use pretty_assertions::assert_eq;use std::path::PathBuf;fn user_message(text: &str) -> ResponseItem {    ResponseItem::Message {        id: None,        role: "user".to_string(),        content: vec![ContentItem::InputText {            text: text.to_string(),        }],        phase: None,        metadata: None,    }}fn assistant_message(text: &str) -> ResponseItem {    ResponseItem::Message {        id: None,        role: "assistant".to_string(),        content: vec![ContentItem::OutputText {            text: text.to_string(),        }],        phase: None,        metadata: None,    }}fn inter_agent_assistant_message(text: &str) -> ResponseItem {    let communication = InterAgentCommunication::new(        AgentPath::root(),        AgentPath::root().join("worker").unwrap(),        Vec::new(),        text.to_string(),        /*trigger_turn*/ true,    );    ResponseItem::Message {        id: None,        role: "assistant".to_string(),        content: vec![ContentItem::OutputText {            text: serde_json::to_string(&communication).unwrap(),        }],        phase: None,        metadata: None,    }}#[tokio::test]async fn record_initial_history_reconstructs_typed_inter_agent_message() {    let (session, _turn_context) = make_session_and_context().await;    let communication = InterAgentCommunication::new(        AgentPath::root().join("worker").expect("worker path"),        AgentPath::root(),        Vec::new(),        "child done".to_string(),        /*trigger_turn*/ false,    );    session        .record_initial_history(InitialHistory::Resumed(ResumedHistory {            conversation_id: ThreadId::default(),            history: vec![RolloutItem::InterAgentCommunication(communication.clone())],            rollout_path: Some(PathBuf::from("/tmp/resume.jsonl")),        }))        .await;    assert_eq!(        session.state.lock().await.clone_history().raw_items(),        &[communication.to_model_input_item()]    );}#[tokio::test]async fn record_initial_history_resumed_bare_turn_context_does_not_hydrate_previous_turn_settings(){    let (session, turn_context) = make_session_and_context().await;    let previous_model = "previous-rollout-model";    let previous_context_item = TurnContextItem {        turn_id: Some(turn_context.sub_id.clone()),        #[allow(deprecated)]        cwd: turn_context.cwd.to_path_buf(),        workspace_roots: None,        current_date: turn_context.current_date.clone(),        timezone: turn_context.timezone.clone(),        approval_policy: turn_context.approval_policy.value(),        sandbox_policy: turn_context.sandbox_policy(),        permission_profile: None,        network: None,        file_system_sandbox_policy: None,        model: previous_model.to_string(),        comp_hash: None,        personality: turn_context.personality,        collaboration_mode: Some(turn_context.collaboration_mode.clone()),        multi_agent_version: None,        realtime_active: Some(turn_context.realtime_active),        effort: turn_context.reasoning_effort.clone(),        summary: codex_protocol::config_types::ReasoningSummary::Auto,    };    let rollout_items = vec![RolloutItem::TurnContext(previous_context_item)];    session        .record_initial_history(InitialHistory::Resumed(ResumedHistory {            conversation_id: ThreadId::default(),            history: rollout_items,            rollout_path: Some(PathBuf::from("/tmp/resume.jsonl")),        }))        .await;    assert_eq!(session.previous_turn_settings().await, None);    assert!(session.reference_context_item().await.is_none());}#[tokio::test]async fn record_initial_history_resumed_hydrates_previous_turn_settings_from_lifecycle_turn_with_missing_turn_context_id() {    let (session, turn_context) = make_session_and_context().await;    let previous_model = "previous-rollout-model";    let mut previous_context_item = TurnContextItem {        turn_id: Some(turn_context.sub_id.clone()),        #[allow(deprecated)]        cwd: turn_context.cwd.to_path_buf(),        workspace_roots: None,        current_date: turn_context.current_date.clone(),        timezone: turn_context.timezone.clone(),        approval_policy: turn_context.approval_policy.value(),        sandbox_policy: turn_context.sandbox_policy(),        permission_profile: None,        network: None,        file_system_sandbox_policy: None,        model: previous_model.to_string(),        comp_hash: Some("comp-hash-a".to_string()),        personality: turn_context.personality,        collaboration_mode: Some(turn_context.collaboration_mode.clone()),        multi_agent_version: None,        realtime_active: Some(turn_context.realtime_active),        effort: turn_context.reasoning_effort.clone(),        summary: codex_protocol::config_types::ReasoningSummary::Auto,    };    let turn_id = previous_context_item        .turn_id        .clone()        .expect("turn context should have turn_id");    previous_context_item.turn_id = None;    let rollout_items = vec![        RolloutItem::EventMsg(EventMsg::TurnStarted(            codex_protocol::protocol::TurnStartedEvent {                turn_id: turn_id.clone(),                trace_id: None,                started_at: None,                model_context_window: Some(128_000),                collaboration_mode_kind: ModeKind::Default,            },        )),        RolloutItem::EventMsg(EventMsg::UserMessage(            codex_protocol::protocol::UserMessageEvent {                client_id: None,                message: "seed".to_string(),                images: None,                local_images: Vec::new(),                text_elements: Vec::new(),                ..Default::default()            },        )),        RolloutItem::TurnContext(previous_context_item),        RolloutItem::EventMsg(EventMsg::TurnComplete(            codex_protocol::protocol::TurnCompleteEvent {                turn_id,                last_agent_message: None,                completed_at: None,                duration_ms: None,                time_to_first_token_ms: None,            },        )),    ];    session        .record_initial_history(InitialHistory::Resumed(ResumedHistory {            conversation_id: ThreadId::default(),            history: rollout_items,            rollout_path: Some(PathBuf::from("/tmp/resume.jsonl")),        }))        .await;    assert_eq!(        session.previous_turn_settings().await,        Some(PreviousTurnSettings {            model: previous_model.to_string(),            comp_hash: Some("comp-hash-a".to_string()),            realtime_active: Some(turn_context.realtime_active),        })    );}#[tokio::test]async fn reconstruct_history_rollback_keeps_history_and_metadata_in_sync_for_completed_turns() {    let (session, turn_context) = make_session_and_context().await;    let first_context_item = turn_context.to_turn_context_item();    let first_turn_id = first_context_item        .turn_id        .clone()        .expect("turn context should have turn_id");    let mut rolled_back_context_item = first_context_item.clone();    rolled_back_context_item.turn_id = Some("rolled-back-turn".to_string());    rolled_back_context_item.model = "rolled-back-model".to_string();    let rolled_back_turn_id = rolled_back_context_item        .turn_id        .clone()        .expect("turn context should have turn_id");    let turn_one_user = user_message("turn 1 user");    let turn_one_assistant = assistant_message("turn 1 assistant");    let turn_two_user = user_message("turn 2 user");    let turn_two_assistant = assistant_message("turn 2 assistant");    let rollout_items = vec![        RolloutItem::EventMsg(EventMsg::TurnStarted(            codex_protocol::protocol::TurnStartedEvent {                turn_id: first_turn_id.clone(),                trace_id: None,                started_at: None,                model_context_window: Some(128_000),                collaboration_mode_kind: ModeKind::Default,            },        )),        RolloutItem::EventMsg(EventMsg::UserMessage(            codex_protocol::protocol::UserMessageEvent {                client_id: None,                message: "turn 1 user".to_string(),                images: None,                local_images: Vec::new(),                text_elements: Vec::new(),                ..Default::default()            },        )),        RolloutItem::TurnContext(first_context_item.clone()),        RolloutItem::ResponseItem(turn_one_user.clone()),        RolloutItem::ResponseItem(turn_one_assistant.clone()),        RolloutItem::EventMsg(EventMsg::TurnComplete(            codex_protocol::protocol::TurnCompleteEvent {                turn_id: first_turn_id,                last_agent_message: None,                completed_at: None,                duration_ms: None,                time_to_first_token_ms: None,            },        )),        RolloutItem::EventMsg(EventMsg::TurnStarted(            codex_protocol::protocol::TurnStartedEvent {                turn_id: rolled_back_turn_id.clone(),                trace_id: None,                started_at: None,                model_context_window: Some(128_000),                collaboration_mode_kind: ModeKind::Default,            },        )),        RolloutItem::EventMsg(EventMsg::UserMessage(            codex_protocol::protocol::UserMessageEvent {                client_id: None,                message: "turn 2 user".to_string(),                images: None,                local_images: Vec::new(),                text_elements: Vec::new(),                ..Default::default()            },        )),        RolloutItem::TurnContext(rolled_back_context_item),        RolloutItem::ResponseItem(turn_two_user),        RolloutItem::ResponseItem(turn_two_assistant),        RolloutItem::EventMsg(EventMsg::TurnComplete(            codex_protocol::protocol::TurnCompleteEvent {                turn_id: rolled_back_turn_id,                last_agent_message: None,                completed_at: None,                duration_ms: None,                time_to_first_token_ms: None,            },        )),        RolloutItem::EventMsg(EventMsg::ThreadRolledBack(            codex_protocol::protocol::ThreadRolledBackEvent { num_turns: 1 },        )),    ];    let reconstructed = session        .reconstruct_history_from_rollout(&turn_context, &rollout_items)        .await;    assert_eq!(        reconstructed.history,        vec![turn_one_user, turn_one_assistant]    );    assert_eq!(        reconstructed.previous_turn_settings,        Some(PreviousTurnSettings {            model: turn_context.model_info.slug.clone(),            comp_hash: None,            realtime_active: Some(turn_context.realtime_active),        })    );    assert_eq!(        serde_json::to_value(reconstructed.reference_context_item)            .expect("serialize reconstructed reference context item"),        serde_json::to_value(Some(first_context_item))            .expect("serialize expected reference context item")    );}#[tokio::test]async fn reconstruct_history_rollback_keeps_history_and_metadata_in_sync_for_incomplete_turn() {    let (session, turn_context) = make_session_and_context().await;    let first_context_item = turn_context.to_turn_context_item();    let first_turn_id = first_context_item        .turn_id        .clone()        .expect("turn context should have turn_id");    let incomplete_turn_id = "incomplete-rolled-back-turn".to_string();    let turn_one_user = user_message("turn 1 user");    let turn_one_assistant = assistant_message("turn 1 assistant");    let turn_two_user = user_message("turn 2 user");    let rollout_items = vec![        RolloutItem::EventMsg(EventMsg::TurnStarted(            codex_protocol::protocol::TurnStartedEvent {                turn_id: first_turn_id.clone(),                trace_id: None,                started_at: None,                model_context_window: Some(128_000),                collaboration_mode_kind: ModeKind::Default,            },        )),        RolloutItem::EventMsg(EventMsg::UserMessage(            codex_protocol::protocol::UserMessageEvent {                client_id: None,                message: "turn 1 user".to_string(),                images: None,                local_images: Vec::new(),                text_elements: Vec::new(),                ..Default::default()            },        )),        RolloutItem::TurnContext(first_context_item.clone()),        RolloutItem::ResponseItem(turn_one_user.clone()),        RolloutItem::ResponseItem(turn_one_assistant.clone()),        RolloutItem::EventMsg(EventMsg::TurnComplete(            codex_protocol::protocol::TurnCompleteEvent {                turn_id: first_turn_id,                last_agent_message: None,                completed_at: None,                duration_ms: None,                time_to_first_token_ms: None,            },        )),        RolloutItem::EventMsg(EventMsg::TurnStarted(            codex_protocol::protocol::TurnStartedEvent {                turn_id: incomplete_turn_id,                trace_id: None,                started_at: None,                model_context_window: Some(128_000),                collaboration_mode_kind: ModeKind::Default,            },        )),        RolloutItem::EventMsg(EventMsg::UserMessage(            codex_protocol::protocol::UserMessageEvent {                client_id: None,                message: "turn 2 user".to_string(),                images: None,                local_images: Vec::new(),                text_elements: Vec::new(),                ..Default::default()            },        )),        RolloutItem::ResponseItem(turn_two_user),        RolloutItem::EventMsg(EventMsg::ThreadRolledBack(            codex_protocol::protocol::ThreadRolledBackEvent { num_turns: 1 },        )),    ];    let reconstructed = session        .reconstruct_history_from_rollout(&turn_context, &rollout_items)        .await;    assert_eq!(        reconstructed.history,        vec![turn_one_user, turn_one_assistant]    );    assert_eq!(        reconstructed.previous_turn_settings,        Some(PreviousTurnSettings {            model: turn_context.model_info.slug.clone(),            comp_hash: None,            realtime_active: Some(turn_context.realtime_active),        })    );    assert_eq!(        serde_json::to_value(reconstructed.reference_context_item)            .expect("serialize reconstructed reference context item"),        serde_json::to_value(Some(first_context_item))            .expect("serialize expected reference context item")    );}#[tokio::test]async fn reconstruct_history_rollback_skips_non_user_turns_for_history_and_metadata() {    let (session, turn_context) = make_session_and_context().await;    let first_context_item = turn_context.to_turn_context_item();    let first_turn_id = first_context_item        .turn_id        .clone()        .expect("turn context should have turn_id");    let second_turn_id = "rolled-back-user-turn".to_string();    let standalone_turn_id = "standalone-turn".to_string();    let turn_one_user = user_message("turn 1 user");    let turn_one_assistant = assistant_message("turn 1 assistant");    let turn_two_user = user_message("turn 2 user");    let turn_two_assistant = assistant_message("turn 2 assistant");    let standalone_assistant = assistant_message("standalone assistant");    let rollout_items = vec![        RolloutItem::EventMsg(EventMsg::TurnStarted(            codex_protocol::protocol::TurnStartedEvent {                turn_id: first_turn_id.clone(),                trace_id: None,                started_at: None,                model_context_window: Some(128_000),                collaboration_mode_kind: ModeKind::Default,            },        )),        RolloutItem::EventMsg(EventMsg::UserMessage(            codex_protocol::protocol::UserMessageEvent {                client_id: None,                message: "turn 1 user".to_string(),                images: None,                local_images: Vec::new(),                text_elements: Vec::new(),                ..Default::default()            },        )),        RolloutItem::TurnContext(first_context_item.clone()),        RolloutItem::ResponseItem(turn_one_user.clone()),        RolloutItem::ResponseItem(turn_one_assistant.clone()),        RolloutItem::EventMsg(EventMsg::TurnComplete(            codex_protocol::protocol::TurnCompleteEvent {                turn_id: first_turn_id,                last_agent_message: None,                completed_at: None,                duration_ms: None,                time_to_first_token_ms: None,            },        )),        RolloutItem::EventMsg(EventMsg::TurnStarted(            codex_protocol::protocol::TurnStartedEvent {                turn_id: second_turn_id.clone(),                trace_id: None,                started_at: None,                model_context_window: Some(128_000),                collaboration_mode_kind: ModeKind::Default,            },        )),        RolloutItem::EventMsg(EventMsg::UserMessage(            codex_protocol::protocol::UserMessageEvent {                client_id: None,                message: "turn 2 user".to_string(),                images: None,                local_images: Vec::new(),                text_elements: Vec::new(),                ..Default::default()            },        )),        RolloutItem::ResponseItem(turn_two_user),        RolloutItem::ResponseItem(turn_two_assistant),        RolloutItem::EventMsg(EventMsg::TurnComplete(            codex_protocol::protocol::TurnCompleteEvent {                turn_id: second_turn_id,                last_agent_message: None,                completed_at: None,                duration_ms: None,                time_to_first_token_ms: None,            },        )),        RolloutItem::EventMsg(EventMsg::TurnStarted(            codex_protocol::protocol::TurnStartedEvent {                turn_id: standalone_turn_id.clone(),                trace_id: None,                started_at: None,                model_context_window: Some(128_000),                collaboration_mode_kind: ModeKind::Default,            },        )),        RolloutItem::ResponseItem(standalone_assistant),        RolloutItem::EventMsg(EventMsg::TurnComplete(            codex_protocol::protocol::TurnCompleteEvent {                turn_id: standalone_turn_id,                last_agent_message: None,                completed_at: None,                duration_ms: None,                time_to_first_token_ms: None,            },        )),        RolloutItem::EventMsg(EventMsg::ThreadRolledBack(            codex_protocol::protocol::ThreadRolledBackEvent { num_turns: 1 },        )),    ];    let reconstructed = session        .reconstruct_history_from_rollout(&turn_context, &rollout_items)        .await;    assert_eq!(        reconstructed.history,        vec![turn_one_user, turn_one_assistant]    );    assert_eq!(        reconstructed.previous_turn_settings,        Some(PreviousTurnSettings {            model: turn_context.model_info.slug.clone(),            comp_hash: None,            realtime_active: Some(turn_context.realtime_active),        })    );    assert_eq!(        serde_json::to_value(reconstructed.reference_context_item)            .expect("serialize reconstructed reference context item"),        serde_json::to_value(Some(first_context_item))            .expect("serialize expected reference context item")    );}#[tokio::test]async fn reconstruct_history_rollback_counts_inter_agent_assistant_turns() {    let (session, turn_context) = make_session_and_context().await;    let first_context_item = turn_context.to_turn_context_item();    let first_turn_id = first_context_item        .turn_id        .clone()        .expect("turn context should have turn_id");    let assistant_turn_id = "assistant-instruction-turn".to_string();    let assistant_turn_context = TurnContextItem {        turn_id: Some(assistant_turn_id.clone()),        ..first_context_item.clone()    };    let assistant_instruction = inter_agent_assistant_message("continue");    let assistant_reply = assistant_message("worker reply");    let rollout_items = vec![        RolloutItem::EventMsg(EventMsg::TurnStarted(            codex_protocol::protocol::TurnStartedEvent {                turn_id: first_turn_id.clone(),                trace_id: None,                started_at: None,                model_context_window: Some(128_000),                collaboration_mode_kind: ModeKind::Default,            },        )),        RolloutItem::EventMsg(EventMsg::UserMessage(            codex_protocol::protocol::UserMessageEvent {                client_id: None,                message: "turn 1 user".to_string(),                images: None,                local_images: Vec::new(),                text_elements: Vec::new(),                ..Default::default()            },        )),        RolloutItem::TurnContext(first_context_item.clone()),        RolloutItem::ResponseItem(user_message("turn 1 user")),        RolloutItem::ResponseItem(assistant_message("turn 1 assistant")),        RolloutItem::EventMsg(EventMsg::TurnComplete(            codex_protocol::protocol::TurnCompleteEvent {                turn_id: first_turn_id,                last_agent_message: None,                completed_at: None,                duration_ms: None,                time_to_first_token_ms: None,            },        )),        RolloutItem::EventMsg(EventMsg::TurnStarted(            codex_protocol::protocol::TurnStartedEvent {                turn_id: assistant_turn_id.clone(),                trace_id: None,                started_at: None,                model_context_window: Some(128_000),                collaboration_mode_kind: ModeKind::Default,            },        )),        RolloutItem::TurnContext(assistant_turn_context),        RolloutItem::ResponseItem(assistant_instruction),        RolloutItem::ResponseItem(assistant_reply),        RolloutItem::EventMsg(EventMsg::TurnComplete(            codex_protocol::protocol::TurnCompleteEvent {                turn_id: assistant_turn_id,                last_agent_message: None,                completed_at: None,                duration_ms: None,                time_to_first_token_ms: None,            },        )),        RolloutItem::EventMsg(EventMsg::ThreadRolledBack(            codex_protocol::protocol::ThreadRolledBackEvent { num_turns: 1 },        )),    ];    let reconstructed = session        .reconstruct_history_from_rollout(&turn_context, &rollout_items)        .await;    assert_eq!(        reconstructed.history,        vec![            user_message("turn 1 user"),            assistant_message("turn 1 assistant")        ]    );    assert_eq!(        reconstructed.previous_turn_settings,        Some(PreviousTurnSettings {            model: turn_context.model_info.slug.clone(),            comp_hash: None,            realtime_active: Some(turn_context.realtime_active),        })    );    assert_eq!(        serde_json::to_value(reconstructed.reference_context_item)            .expect("serialize reconstructed reference context item"),        serde_json::to_value(Some(first_context_item))            .expect("serialize expected reference context item")    );}#[tokio::test]async fn reconstruct_history_rollback_clears_history_and_metadata_when_exceeding_user_turns() {    let (session, turn_context) = make_session_and_context().await;    let only_context_item = turn_context.to_turn_context_item();    let only_turn_id = only_context_item        .turn_id        .clone()        .expect("turn context should have turn_id");    let rollout_items = vec![        RolloutItem::EventMsg(EventMsg::TurnStarted(            codex_protocol::protocol::TurnStartedEvent {                turn_id: only_turn_id.clone(),                trace_id: None,                started_at: None,                model_context_window: Some(128_000),                collaboration_mode_kind: ModeKind::Default,            },        )),        RolloutItem::EventMsg(EventMsg::UserMessage(            codex_protocol::protocol::UserMessageEvent {                client_id: None,                message: "only user".to_string(),                images: None,                local_images: Vec::new(),                text_elements: Vec::new(),                ..Default::default()            },        )),        RolloutItem::TurnContext(only_context_item),        RolloutItem::ResponseItem(user_message("only user")),        RolloutItem::ResponseItem(assistant_message("only assistant")),        RolloutItem::EventMsg(EventMsg::TurnComplete(            codex_protocol::protocol::TurnCompleteEvent {                turn_id: only_turn_id,                last_agent_message: None,                completed_at: None,                duration_ms: None,                time_to_first_token_ms: None,            },        )),        RolloutItem::EventMsg(EventMsg::ThreadRolledBack(            codex_protocol::protocol::ThreadRolledBackEvent { num_turns: 99 },        )),    ];    let reconstructed = session        .reconstruct_history_from_rollout(&turn_context, &rollout_items)        .await;    assert_eq!(reconstructed.history, Vec::new());    assert_eq!(reconstructed.previous_turn_settings, None);    assert!(reconstructed.reference_context_item.is_none());}#[tokio::test]async fn record_initial_history_resumed_rollback_skips_only_user_turns() {    let (session, turn_context) = make_session_and_context().await;    let previous_context_item = turn_context.to_turn_context_item();    let user_turn_id = previous_context_item        .turn_id        .clone()        .expect("turn context should have turn_id");    let standalone_turn_id = "standalone-task-turn".to_string();    let rollout_items = vec![        RolloutItem::EventMsg(EventMsg::TurnStarted(            codex_protocol::protocol::TurnStartedEvent {                turn_id: user_turn_id.clone(),                trace_id: None,                started_at: None,                model_context_window: Some(128_000),                collaboration_mode_kind: ModeKind::Default,            },        )),        RolloutItem::EventMsg(EventMsg::UserMessage(            codex_protocol::protocol::UserMessageEvent {                client_id: None,                message: "seed".to_string(),                images: None,                local_images: Vec::new(),                text_elements: Vec::new(),                ..Default::default()            },        )),        RolloutItem::TurnContext(previous_context_item),        RolloutItem::EventMsg(EventMsg::TurnComplete(            codex_protocol::protocol::TurnCompleteEvent {                turn_id: user_turn_id,                last_agent_message: None,                completed_at: None,                duration_ms: None,                time_to_first_token_ms: None,            },        )),        // Standalone task turn (no UserMessage) should not consume rollback skips.        RolloutItem::EventMsg(EventMsg::TurnStarted(            codex_protocol::protocol::TurnStartedEvent {                turn_id: standalone_turn_id.clone(),                trace_id: None,                started_at: None,                model_context_window: Some(128_000),                collaboration_mode_kind: ModeKind::Default,            },        )),        RolloutItem::EventMsg(EventMsg::TurnComplete(            codex_protocol::protocol::TurnCompleteEvent {                turn_id: standalone_turn_id,                last_agent_message: None,                completed_at: None,                duration_ms: None,                time_to_first_token_ms: None,            },        )),        RolloutItem::EventMsg(EventMsg::ThreadRolledBack(            codex_protocol::protocol::ThreadRolledBackEvent { num_turns: 1 },        )),    ];    session        .record_initial_history(InitialHistory::Resumed(ResumedHistory {            conversation_id: ThreadId::default(),            history: rollout_items,            rollout_path: Some(PathBuf::from("/tmp/resume.jsonl")),        }))        .await;    assert_eq!(session.previous_turn_settings().await, None);    assert!(session.reference_context_item().await.is_none());}#[tokio::test]async fn record_initial_history_resumed_rollback_drops_incomplete_user_turn_compaction_metadata() {    let (session, turn_context) = make_session_and_context().await;    let previous_context_item = turn_context.to_turn_context_item();    let previous_turn_id = previous_context_item        .turn_id        .clone()        .expect("turn context should have turn_id");    let incomplete_turn_id = "incomplete-compacted-user-turn".to_string();    let rollout_items = vec![        RolloutItem::EventMsg(EventMsg::TurnStarted(            codex_protocol::protocol::TurnStartedEvent {                turn_id: previous_turn_id.clone(),                trace_id: None,                started_at: None,                model_context_window: Some(128_000),                collaboration_mode_kind: ModeKind::Default,            },        )),        RolloutItem::EventMsg(EventMsg::UserMessage(            codex_protocol::protocol::UserMessageEvent {                client_id: None,                message: "seed".to_string(),                images: None,                local_images: Vec::new(),                text_elements: Vec::new(),                ..Default::default()            },        )),        RolloutItem::TurnContext(previous_context_item.clone()),        RolloutItem::EventMsg(EventMsg::TurnComplete(            codex_protocol::protocol::TurnCompleteEvent {                turn_id: previous_turn_id,                last_agent_message: None,                completed_at: None,                duration_ms: None,                time_to_first_token_ms: None,            },        )),        RolloutItem::EventMsg(EventMsg::TurnStarted(            codex_protocol::protocol::TurnStartedEvent {                turn_id: incomplete_turn_id,                trace_id: None,                started_at: None,                model_context_window: Some(128_000),                collaboration_mode_kind: ModeKind::Default,            },        )),        RolloutItem::EventMsg(EventMsg::UserMessage(            codex_protocol::protocol::UserMessageEvent {                client_id: None,                message: "rolled back".to_string(),                images: None,                local_images: Vec::new(),                text_elements: Vec::new(),                ..Default::default()            },        )),        RolloutItem::Compacted(CompactedItem {            message: String::new(),            replacement_history: Some(Vec::new()),            window_id: None,        }),        RolloutItem::EventMsg(EventMsg::ThreadRolledBack(            codex_protocol::protocol::ThreadRolledBackEvent { num_turns: 1 },        )),    ];    session        .record_initial_history(InitialHistory::Resumed(ResumedHistory {            conversation_id: ThreadId::default(),            history: rollout_items,            rollout_path: Some(PathBuf::from("/tmp/resume.jsonl")),        }))        .await;    assert_eq!(        session.previous_turn_settings().await,        Some(PreviousTurnSettings {            model: turn_context.model_info.slug.clone(),            comp_hash: None,            realtime_active: Some(turn_context.realtime_active),        })    );    assert_eq!(        serde_json::to_value(session.reference_context_item().await)            .expect("serialize seeded reference context item"),        serde_json::to_value(Some(previous_context_item))            .expect("serialize expected reference context item")    );}#[tokio::test]async fn record_initial_history_resumed_bare_turn_context_does_not_seed_reference_context_item() {    let (session, turn_context) = make_session_and_context().await;    let previous_context_item = turn_context.to_turn_context_item();    let rollout_items = vec![RolloutItem::TurnContext(previous_context_item.clone())];    session        .record_initial_history(InitialHistory::Resumed(ResumedHistory {            conversation_id: ThreadId::default(),            history: rollout_items,            rollout_path: Some(PathBuf::from("/tmp/resume.jsonl")),        }))        .await;    assert!(session.reference_context_item().await.is_none());}#[tokio::test]async fn record_initial_history_resumed_does_not_seed_reference_context_item_after_compaction() {    let (session, turn_context) = make_session_and_context().await;    let previous_context_item = turn_context.to_turn_context_item();    let rollout_items = vec![        RolloutItem::TurnContext(previous_context_item),        RolloutItem::Compacted(CompactedItem {            message: String::new(),            replacement_history: Some(Vec::new()),            window_id: None,        }),    ];    session        .record_initial_history(InitialHistory::Resumed(ResumedHistory {            conversation_id: ThreadId::default(),            history: rollout_items,            rollout_path: Some(PathBuf::from("/tmp/resume.jsonl")),        }))        .await;    assert_eq!(session.previous_turn_settings().await, None);    assert!(session.reference_context_item().await.is_none());}#[tokio::test]async fn reconstruct_history_legacy_compaction_without_replacement_history_does_not_inject_current_initial_context() {    let (session, turn_context) = make_session_and_context().await;    let rollout_items = vec![        RolloutItem::ResponseItem(user_message("before compact")),        RolloutItem::ResponseItem(assistant_message("assistant reply")),        RolloutItem::Compacted(CompactedItem {            message: "legacy summary".to_string(),            replacement_history: None,            window_id: None,        }),    ];    let reconstructed = session        .reconstruct_history_from_rollout(&turn_context, &rollout_items)        .await;    assert_eq!(        reconstructed.history,        vec![            user_message("before compact"),            user_message("legacy summary"),        ]    );    assert!(reconstructed.reference_context_item.is_none());}#[tokio::test]async fn reconstruct_history_legacy_compaction_without_replacement_history_clears_later_reference_context_item() {    let (session, turn_context) = make_session_and_context().await;    let current_context_item = turn_context.to_turn_context_item();    let current_turn_id = current_context_item        .turn_id        .clone()        .expect("turn context should have turn_id");    let rollout_items = vec![        RolloutItem::ResponseItem(user_message("before compact")),        RolloutItem::Compacted(CompactedItem {            message: "legacy summary".to_string(),            replacement_history: None,            window_id: None,        }),        RolloutItem::EventMsg(EventMsg::TurnStarted(            codex_protocol::protocol::TurnStartedEvent {                turn_id: current_turn_id.clone(),                trace_id: None,                started_at: None,                model_context_window: Some(128_000),                collaboration_mode_kind: ModeKind::Default,            },        )),        RolloutItem::EventMsg(EventMsg::UserMessage(            codex_protocol::protocol::UserMessageEvent {                client_id: None,                message: "after legacy compact".to_string(),                images: None,                local_images: Vec::new(),                text_elements: Vec::new(),                ..Default::default()            },        )),        RolloutItem::TurnContext(current_context_item),        RolloutItem::EventMsg(EventMsg::TurnComplete(            codex_protocol::protocol::TurnCompleteEvent {                turn_id: current_turn_id,                last_agent_message: None,                completed_at: None,                duration_ms: None,                time_to_first_token_ms: None,            },        )),    ];    let reconstructed = session        .reconstruct_history_from_rollout(&turn_context, &rollout_items)        .await;    assert!(reconstructed.reference_context_item.is_none());}#[tokio::test]async fn record_initial_history_resumed_turn_context_after_compaction_reestablishes_reference_context_item() {    let (session, turn_context) = make_session_and_context().await;    let previous_model = "previous-rollout-model";    let previous_context_item = TurnContextItem {        turn_id: Some(turn_context.sub_id.clone()),        #[allow(deprecated)]        cwd: turn_context.cwd.to_path_buf(),        workspace_roots: None,        current_date: turn_context.current_date.clone(),        timezone: turn_context.timezone.clone(),        approval_policy: turn_context.approval_policy.value(),        sandbox_policy: turn_context.sandbox_policy(),        permission_profile: None,        network: None,        file_system_sandbox_policy: None,        model: previous_model.to_string(),        comp_hash: None,        personality: turn_context.personality,        collaboration_mode: Some(turn_context.collaboration_mode.clone()),        multi_agent_version: None,        realtime_active: Some(turn_context.realtime_active),        effort: turn_context.reasoning_effort.clone(),        summary: codex_protocol::config_types::ReasoningSummary::Auto,    };    let previous_turn_id = previous_context_item        .turn_id        .clone()        .expect("turn context should have turn_id");    let rollout_items = vec![        RolloutItem::EventMsg(EventMsg::TurnStarted(            codex_protocol::protocol::TurnStartedEvent {                turn_id: previous_turn_id.clone(),                trace_id: None,                started_at: None,                model_context_window: Some(128_000),                collaboration_mode_kind: ModeKind::Default,            },        )),        RolloutItem::EventMsg(EventMsg::UserMessage(            codex_protocol::protocol::UserMessageEvent {                client_id: None,                message: "seed".to_string(),                images: None,                local_images: Vec::new(),                text_elements: Vec::new(),                ..Default::default()            },        )),        // Compaction clears baseline until a later TurnContextItem re-establishes it.        RolloutItem::Compacted(CompactedItem {            message: String::new(),            replacement_history: Some(Vec::new()),            window_id: None,        }),        RolloutItem::TurnContext(previous_context_item),        RolloutItem::EventMsg(EventMsg::TurnComplete(            codex_protocol::protocol::TurnCompleteEvent {                turn_id: previous_turn_id,                last_agent_message: None,                completed_at: None,                duration_ms: None,                time_to_first_token_ms: None,            },        )),    ];    session        .record_initial_history(InitialHistory::Resumed(ResumedHistory {            conversation_id: ThreadId::default(),            history: rollout_items,            rollout_path: Some(PathBuf::from("/tmp/resume.jsonl")),        }))        .await;    assert_eq!(        session.previous_turn_settings().await,        Some(PreviousTurnSettings {            model: previous_model.to_string(),            comp_hash: None,            realtime_active: Some(turn_context.realtime_active),        })    );    assert_eq!(        serde_json::to_value(session.reference_context_item().await)            .expect("serialize seeded reference context item"),        serde_json::to_value(Some(TurnContextItem {            turn_id: Some(turn_context.sub_id.clone()),            #[allow(deprecated)]            cwd: turn_context.cwd.to_path_buf(),            workspace_roots: None,            current_date: turn_context.current_date.clone(),            timezone: turn_context.timezone.clone(),            approval_policy: turn_context.approval_policy.value(),            sandbox_policy: turn_context.sandbox_policy(),            permission_profile: None,            network: None,            file_system_sandbox_policy: None,            model: previous_model.to_string(),            comp_hash: None,            personality: turn_context.personality,            collaboration_mode: Some(turn_context.collaboration_mode.clone()),            multi_agent_version: None,            realtime_active: Some(turn_context.realtime_active),            effort: turn_context.reasoning_effort.clone(),            summary: codex_protocol::config_types::ReasoningSummary::Auto,        }))        .expect("serialize expected reference context item")    );}#[tokio::test]async fn record_initial_history_resumed_aborted_turn_without_id_clears_active_turn_for_compaction_accounting() {    let (session, turn_context) = make_session_and_context().await;    let previous_model = "previous-rollout-model";    let previous_context_item = TurnContextItem {        turn_id: Some(turn_context.sub_id.clone()),        #[allow(deprecated)]        cwd: turn_context.cwd.to_path_buf(),        workspace_roots: None,        current_date: turn_context.current_date.clone(),        timezone: turn_context.timezone.clone(),        approval_policy: turn_context.approval_policy.value(),        sandbox_policy: turn_context.sandbox_policy(),        permission_profile: None,        network: None,        file_system_sandbox_policy: None,        model: previous_model.to_string(),        comp_hash: None,        personality: turn_context.personality,        collaboration_mode: Some(turn_context.collaboration_mode.clone()),        multi_agent_version: None,        realtime_active: Some(turn_context.realtime_active),        effort: turn_context.reasoning_effort.clone(),        summary: codex_protocol::config_types::ReasoningSummary::Auto,    };    let previous_turn_id = previous_context_item        .turn_id        .clone()        .expect("turn context should have turn_id");    let aborted_turn_id = "aborted-turn-without-id".to_string();    let rollout_items = vec![        RolloutItem::EventMsg(EventMsg::TurnStarted(            codex_protocol::protocol::TurnStartedEvent {                turn_id: previous_turn_id.clone(),                trace_id: None,                started_at: None,                model_context_window: Some(128_000),                collaboration_mode_kind: ModeKind::Default,            },        )),        RolloutItem::EventMsg(EventMsg::UserMessage(            codex_protocol::protocol::UserMessageEvent {                client_id: None,                message: "seed".to_string(),                images: None,                local_images: Vec::new(),                text_elements: Vec::new(),                ..Default::default()            },        )),        RolloutItem::TurnContext(previous_context_item),        RolloutItem::EventMsg(EventMsg::TurnComplete(            codex_protocol::protocol::TurnCompleteEvent {                turn_id: previous_turn_id,                last_agent_message: None,                completed_at: None,                duration_ms: None,                time_to_first_token_ms: None,            },        )),        RolloutItem::EventMsg(EventMsg::TurnStarted(            codex_protocol::protocol::TurnStartedEvent {                turn_id: aborted_turn_id,                trace_id: None,                started_at: None,                model_context_window: Some(128_000),                collaboration_mode_kind: ModeKind::Default,            },        )),        RolloutItem::EventMsg(EventMsg::UserMessage(            codex_protocol::protocol::UserMessageEvent {                client_id: None,                message: "aborted".to_string(),                images: None,                local_images: Vec::new(),                text_elements: Vec::new(),                ..Default::default()            },        )),        RolloutItem::EventMsg(EventMsg::TurnAborted(            codex_protocol::protocol::TurnAbortedEvent {                turn_id: None,                reason: TurnAbortReason::Interrupted,                completed_at: None,                duration_ms: None,            },        )),        RolloutItem::Compacted(CompactedItem {            message: String::new(),            replacement_history: Some(Vec::new()),            window_id: None,        }),    ];    session        .record_initial_history(InitialHistory::Resumed(ResumedHistory {            conversation_id: ThreadId::default(),            history: rollout_items,            rollout_path: Some(PathBuf::from("/tmp/resume.jsonl")),        }))        .await;    assert_eq!(        session.previous_turn_settings().await,        Some(PreviousTurnSettings {            model: previous_model.to_string(),            comp_hash: None,            realtime_active: Some(turn_context.realtime_active),        })    );    assert!(session.reference_context_item().await.is_none());}#[tokio::test]async fn record_initial_history_resumed_unmatched_abort_preserves_active_turn_for_later_turn_context() {    let (session, turn_context) = make_session_and_context().await;    let previous_context_item = turn_context.to_turn_context_item();    let previous_turn_id = previous_context_item        .turn_id        .clone()        .expect("turn context should have turn_id");    let current_model = "current-rollout-model";    let current_turn_id = "current-turn".to_string();    let unmatched_abort_turn_id = "other-turn".to_string();    let current_context_item = TurnContextItem {        turn_id: Some(current_turn_id.clone()),        #[allow(deprecated)]        cwd: turn_context.cwd.to_path_buf(),        workspace_roots: None,        current_date: turn_context.current_date.clone(),        timezone: turn_context.timezone.clone(),        approval_policy: turn_context.approval_policy.value(),        sandbox_policy: turn_context.sandbox_policy(),        permission_profile: None,        network: None,        file_system_sandbox_policy: None,        model: current_model.to_string(),        comp_hash: None,        personality: turn_context.personality,        collaboration_mode: Some(turn_context.collaboration_mode.clone()),        multi_agent_version: None,        realtime_active: Some(turn_context.realtime_active),        effort: turn_context.reasoning_effort.clone(),        summary: codex_protocol::config_types::ReasoningSummary::Auto,    };    let rollout_items = vec![        RolloutItem::EventMsg(EventMsg::TurnStarted(            codex_protocol::protocol::TurnStartedEvent {                turn_id: previous_turn_id.clone(),                trace_id: None,                started_at: None,                model_context_window: Some(128_000),                collaboration_mode_kind: ModeKind::Default,            },        )),        RolloutItem::EventMsg(EventMsg::UserMessage(            codex_protocol::protocol::UserMessageEvent {                client_id: None,                message: "seed".to_string(),                images: None,                local_images: Vec::new(),                text_elements: Vec::new(),                ..Default::default()            },        )),        RolloutItem::TurnContext(previous_context_item),        RolloutItem::EventMsg(EventMsg::TurnComplete(            codex_protocol::protocol::TurnCompleteEvent {                turn_id: previous_turn_id,                last_agent_message: None,                completed_at: None,                duration_ms: None,                time_to_first_token_ms: None,            },        )),        RolloutItem::EventMsg(EventMsg::TurnStarted(            codex_protocol::protocol::TurnStartedEvent {                turn_id: current_turn_id.clone(),                trace_id: None,                started_at: None,                model_context_window: Some(128_000),                collaboration_mode_kind: ModeKind::Default,            },        )),        RolloutItem::EventMsg(EventMsg::UserMessage(            codex_protocol::protocol::UserMessageEvent {                client_id: None,                message: "current".to_string(),                images: None,                local_images: Vec::new(),                text_elements: Vec::new(),                ..Default::default()            },        )),        RolloutItem::EventMsg(EventMsg::TurnAborted(            codex_protocol::protocol::TurnAbortedEvent {                turn_id: Some(unmatched_abort_turn_id),                reason: TurnAbortReason::Interrupted,                completed_at: None,                duration_ms: None,            },        )),        RolloutItem::TurnContext(current_context_item.clone()),        RolloutItem::EventMsg(EventMsg::TurnComplete(            codex_protocol::protocol::TurnCompleteEvent {                turn_id: current_turn_id,                last_agent_message: None,                completed_at: None,                duration_ms: None,                time_to_first_token_ms: None,            },        )),    ];    session        .record_initial_history(InitialHistory::Resumed(ResumedHistory {            conversation_id: ThreadId::default(),            history: rollout_items,            rollout_path: Some(PathBuf::from("/tmp/resume.jsonl")),        }))        .await;    assert_eq!(        session.previous_turn_settings().await,        Some(PreviousTurnSettings {            model: current_model.to_string(),            comp_hash: None,            realtime_active: Some(turn_context.realtime_active),        })    );    assert_eq!(        serde_json::to_value(session.reference_context_item().await)            .expect("serialize seeded reference context item"),        serde_json::to_value(Some(current_context_item))            .expect("serialize expected reference context item")    );}#[tokio::test]async fn record_initial_history_resumed_trailing_incomplete_turn_compaction_clears_reference_context_item() {    let (session, turn_context) = make_session_and_context().await;    let previous_model = "previous-rollout-model";    let previous_context_item = TurnContextItem {        turn_id: Some(turn_context.sub_id.clone()),        #[allow(deprecated)]        cwd: turn_context.cwd.to_path_buf(),        workspace_roots: None,        current_date: turn_context.current_date.clone(),        timezone: turn_context.timezone.clone(),        approval_policy: turn_context.approval_policy.value(),        sandbox_policy: turn_context.sandbox_policy(),        permission_profile: None,        network: None,        file_system_sandbox_policy: None,        model: previous_model.to_string(),        comp_hash: None,        personality: turn_context.personality,        collaboration_mode: Some(turn_context.collaboration_mode.clone()),        multi_agent_version: None,        realtime_active: Some(turn_context.realtime_active),        effort: turn_context.reasoning_effort.clone(),        summary: codex_protocol::config_types::ReasoningSummary::Auto,    };    let previous_turn_id = previous_context_item        .turn_id        .clone()        .expect("turn context should have turn_id");    let incomplete_turn_id = "trailing-incomplete-turn".to_string();    let rollout_items = vec![        RolloutItem::EventMsg(EventMsg::TurnStarted(            codex_protocol::protocol::TurnStartedEvent {                turn_id: previous_turn_id.clone(),                trace_id: None,                started_at: None,                model_context_window: Some(128_000),                collaboration_mode_kind: ModeKind::Default,            },        )),        RolloutItem::EventMsg(EventMsg::UserMessage(            codex_protocol::protocol::UserMessageEvent {                client_id: None,                message: "seed".to_string(),                images: None,                local_images: Vec::new(),                text_elements: Vec::new(),                ..Default::default()            },        )),        RolloutItem::TurnContext(previous_context_item),        RolloutItem::EventMsg(EventMsg::TurnComplete(            codex_protocol::protocol::TurnCompleteEvent {                turn_id: previous_turn_id,                last_agent_message: None,                completed_at: None,                duration_ms: None,                time_to_first_token_ms: None,            },        )),        RolloutItem::EventMsg(EventMsg::TurnStarted(            codex_protocol::protocol::TurnStartedEvent {                turn_id: incomplete_turn_id,                trace_id: None,                started_at: None,                model_context_window: Some(128_000),                collaboration_mode_kind: ModeKind::Default,            },        )),        RolloutItem::EventMsg(EventMsg::UserMessage(            codex_protocol::protocol::UserMessageEvent {                client_id: None,                message: "incomplete".to_string(),                images: None,                local_images: Vec::new(),                text_elements: Vec::new(),                ..Default::default()            },        )),        RolloutItem::Compacted(CompactedItem {            message: String::new(),            replacement_history: Some(Vec::new()),            window_id: None,        }),    ];    session        .record_initial_history(InitialHistory::Resumed(ResumedHistory {            conversation_id: ThreadId::default(),            history: rollout_items,            rollout_path: Some(PathBuf::from("/tmp/resume.jsonl")),        }))        .await;    assert_eq!(        session.previous_turn_settings().await,        Some(PreviousTurnSettings {            model: previous_model.to_string(),            comp_hash: None,            realtime_active: Some(turn_context.realtime_active),        })    );    assert!(session.reference_context_item().await.is_none());}#[tokio::test]async fn record_initial_history_resumed_trailing_incomplete_turn_preserves_turn_context_item() {    let (session, turn_context) = make_session_and_context().await;    let current_context_item = turn_context.to_turn_context_item();    let current_turn_id = current_context_item        .turn_id        .clone()        .expect("turn context should have turn_id");    let rollout_items = vec![        RolloutItem::EventMsg(EventMsg::TurnStarted(            codex_protocol::protocol::TurnStartedEvent {                turn_id: current_turn_id,                trace_id: None,                started_at: None,                model_context_window: Some(128_000),                collaboration_mode_kind: ModeKind::Default,            },        )),        RolloutItem::EventMsg(EventMsg::UserMessage(            codex_protocol::protocol::UserMessageEvent {                client_id: None,                message: "incomplete".to_string(),                images: None,                local_images: Vec::new(),                text_elements: Vec::new(),                ..Default::default()            },        )),        RolloutItem::TurnContext(current_context_item.clone()),    ];    session        .record_initial_history(InitialHistory::Resumed(ResumedHistory {            conversation_id: ThreadId::default(),            history: rollout_items,            rollout_path: Some(PathBuf::from("/tmp/resume.jsonl")),        }))        .await;    assert_eq!(        session.previous_turn_settings().await,        Some(PreviousTurnSettings {            model: turn_context.model_info.slug.clone(),            comp_hash: None,            realtime_active: Some(turn_context.realtime_active),        })    );    assert_eq!(        serde_json::to_value(session.reference_context_item().await)            .expect("serialize seeded reference context item"),        serde_json::to_value(Some(current_context_item))            .expect("serialize expected reference context item")    );}#[tokio::test]async fn record_initial_history_resumed_replaced_incomplete_compacted_turn_clears_reference_context_item() {    let (session, turn_context) = make_session_and_context().await;    let previous_model = "previous-rollout-model";    let previous_context_item = TurnContextItem {        turn_id: Some(turn_context.sub_id.clone()),        #[allow(deprecated)]        cwd: turn_context.cwd.to_path_buf(),        workspace_roots: None,        current_date: turn_context.current_date.clone(),        timezone: turn_context.timezone.clone(),        approval_policy: turn_context.approval_policy.value(),        sandbox_policy: turn_context.sandbox_policy(),        permission_profile: None,        network: None,        file_system_sandbox_policy: None,        model: previous_model.to_string(),        comp_hash: None,        personality: turn_context.personality,        collaboration_mode: Some(turn_context.collaboration_mode.clone()),        multi_agent_version: None,        realtime_active: Some(turn_context.realtime_active),        effort: turn_context.reasoning_effort.clone(),        summary: codex_protocol::config_types::ReasoningSummary::Auto,    };    let previous_turn_id = previous_context_item        .turn_id        .clone()        .expect("turn context should have turn_id");    let compacted_incomplete_turn_id = "compacted-incomplete-turn".to_string();    let replacing_turn_id = "replacing-turn".to_string();    let rollout_items = vec![        RolloutItem::EventMsg(EventMsg::TurnStarted(            codex_protocol::protocol::TurnStartedEvent {                turn_id: previous_turn_id.clone(),                trace_id: None,                started_at: None,                model_context_window: Some(128_000),                collaboration_mode_kind: ModeKind::Default,            },        )),        RolloutItem::EventMsg(EventMsg::UserMessage(            codex_protocol::protocol::UserMessageEvent {                client_id: None,                message: "seed".to_string(),                images: None,                local_images: Vec::new(),                text_elements: Vec::new(),                ..Default::default()            },        )),        RolloutItem::TurnContext(previous_context_item),        RolloutItem::EventMsg(EventMsg::TurnComplete(            codex_protocol::protocol::TurnCompleteEvent {                turn_id: previous_turn_id,                last_agent_message: None,                completed_at: None,                duration_ms: None,                time_to_first_token_ms: None,            },        )),        RolloutItem::EventMsg(EventMsg::TurnStarted(            codex_protocol::protocol::TurnStartedEvent {                turn_id: compacted_incomplete_turn_id,                trace_id: None,                started_at: None,                model_context_window: Some(128_000),                collaboration_mode_kind: ModeKind::Default,            },        )),        RolloutItem::EventMsg(EventMsg::UserMessage(            codex_protocol::protocol::UserMessageEvent {                client_id: None,                message: "compacted".to_string(),                images: None,                local_images: Vec::new(),                text_elements: Vec::new(),                ..Default::default()            },        )),        RolloutItem::Compacted(CompactedItem {            message: String::new(),            replacement_history: Some(Vec::new()),            window_id: None,        }),        // A newer TurnStarted replaces the incomplete compacted turn without a matching        // completion/abort for the old one.        RolloutItem::EventMsg(EventMsg::TurnStarted(            codex_protocol::protocol::TurnStartedEvent {                turn_id: replacing_turn_id,                trace_id: None,                started_at: None,                model_context_window: Some(128_000),                collaboration_mode_kind: ModeKind::Default,            },        )),    ];    session        .record_initial_history(InitialHistory::Resumed(ResumedHistory {            conversation_id: ThreadId::default(),            history: rollout_items,            rollout_path: Some(PathBuf::from("/tmp/resume.jsonl")),        }))        .await;    assert_eq!(        session.previous_turn_settings().await,        Some(PreviousTurnSettings {            model: previous_model.to_string(),            comp_hash: None,            realtime_active: Some(turn_context.realtime_active),        })    );    assert!(session.reference_context_item().await.is_none());}