mirror of
https://github.com/openai/codex.git
synced 2026-10-26 18:38:47 +00:00
Box session metadata and compaction payloads in RolloutItem (#55733)
## What changed Store `RolloutItem::SessionMeta` and `RolloutItem::Compacted` payloads in `Box` values and update their producers, consumers, and test fixtures. Preserve the existing serialized rollout format. GitOrigin-RevId: 59fcc4beb47d23160872dcb6e95ace9b142d3d11
This commit is contained in:
@@ -4602,7 +4602,7 @@ mod tests {
|
||||
model_context_window: None,
|
||||
collaboration_mode_kind: Default::default(),
|
||||
})),
|
||||
RolloutItem::Compacted(CompactedItem {
|
||||
RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: String::new(),
|
||||
replacement_history: None,
|
||||
retained_context: None,
|
||||
@@ -4615,7 +4615,7 @@ mod tests {
|
||||
compaction_response_id: None,
|
||||
latest_token_usage_record: None,
|
||||
resume_metadata: None,
|
||||
}),
|
||||
})),
|
||||
RolloutItem::EventMsg(EventMsg::TurnComplete(TurnCompleteEvent {
|
||||
root_turn_id: None,
|
||||
turn_id: "turn-compact".into(),
|
||||
|
||||
@@ -210,7 +210,7 @@ fn ignores_legacy_abort_without_turn_id_and_context_only_records() {
|
||||
duration_ms: None,
|
||||
},
|
||||
)));
|
||||
let compacted = project(RolloutItem::Compacted(CompactedItem {
|
||||
let compacted = project(RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: String::new(),
|
||||
replacement_history: None,
|
||||
retained_context: None,
|
||||
@@ -223,7 +223,7 @@ fn ignores_legacy_abort_without_turn_id_and_context_only_records() {
|
||||
compaction_response_id: None,
|
||||
latest_token_usage_record: None,
|
||||
resume_metadata: None,
|
||||
}));
|
||||
})));
|
||||
let security_risk = project(RolloutItem::SecurityRiskScore(SecurityRiskScore {
|
||||
scores: BTreeMap::from([("action_risk".to_string(), 0.92)]),
|
||||
call_id: None,
|
||||
|
||||
@@ -742,7 +742,7 @@ mod tests {
|
||||
let mut lines = vec![RolloutLine {
|
||||
timestamp: "2026-07-24T00:00:00Z".to_string(),
|
||||
ordinal: None,
|
||||
item: RolloutItem::SessionMeta(SessionMetaLine {
|
||||
item: RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: codex_protocol::protocol::SessionMeta {
|
||||
cwd: tempdir.path().to_path_buf(),
|
||||
base_instructions: Some(codex_protocol::models::BaseInstructions {
|
||||
@@ -752,7 +752,7 @@ mod tests {
|
||||
..Default::default()
|
||||
},
|
||||
git: None,
|
||||
}),
|
||||
})),
|
||||
}];
|
||||
lines.extend(turns.iter().map(|(turn_id, model, effort)| {
|
||||
RolloutLine {
|
||||
|
||||
@@ -989,10 +989,10 @@ mod thread_processor_behavior_tests {
|
||||
let line = RolloutLine {
|
||||
timestamp: timestamp.clone(),
|
||||
ordinal: None,
|
||||
item: RolloutItem::SessionMeta(SessionMetaLine {
|
||||
item: RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: session_meta.clone(),
|
||||
git: None,
|
||||
}),
|
||||
})),
|
||||
};
|
||||
|
||||
fs::write(&path, format!("{}\n", serde_json::to_string(&line)?))?;
|
||||
@@ -1057,10 +1057,10 @@ mod thread_processor_behavior_tests {
|
||||
let line = RolloutLine {
|
||||
timestamp,
|
||||
ordinal: None,
|
||||
item: RolloutItem::SessionMeta(SessionMetaLine {
|
||||
item: RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: session_meta,
|
||||
git: None,
|
||||
}),
|
||||
})),
|
||||
};
|
||||
fs::write(&path, format!("{}\n", serde_json::to_string(&line)?))?;
|
||||
|
||||
@@ -1100,10 +1100,10 @@ mod thread_processor_behavior_tests {
|
||||
let line = RolloutLine {
|
||||
timestamp,
|
||||
ordinal: None,
|
||||
item: RolloutItem::SessionMeta(SessionMetaLine {
|
||||
item: RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: session_meta,
|
||||
git: None,
|
||||
}),
|
||||
})),
|
||||
};
|
||||
fs::write(&path, format!("{}\n", serde_json::to_string(&line)?))?;
|
||||
|
||||
|
||||
@@ -173,7 +173,11 @@ async fn thread_fork_creates_new_thread_and_emits_started() -> Result<()> {
|
||||
);
|
||||
let mut session_meta = read_session_meta_line(&original_path).await?;
|
||||
session_meta.meta.multi_agent_version = Some(MultiAgentVersion::V1);
|
||||
append_rollout_item_to_path(&original_path, &RolloutItem::SessionMeta(session_meta)).await?;
|
||||
append_rollout_item_to_path(
|
||||
&original_path,
|
||||
&RolloutItem::SessionMeta(Box::new(session_meta)),
|
||||
)
|
||||
.await?;
|
||||
let original_contents = std::fs::read_to_string(&original_path)?;
|
||||
|
||||
let mut mcp = TestAppServer::builder()
|
||||
|
||||
@@ -1678,8 +1678,11 @@ async fn thread_list_reports_loaded_subagent_direct_input_capability() -> Result
|
||||
let parent_rollout_path = rollout_path(codex_home.path(), "2025-02-01T09-00-00", &cli_id);
|
||||
let mut parent_meta = read_session_meta_line(&parent_rollout_path).await?;
|
||||
parent_meta.meta.multi_agent_version = Some(MultiAgentVersion::V2);
|
||||
append_rollout_item_to_path(&parent_rollout_path, &RolloutItem::SessionMeta(parent_meta))
|
||||
.await?;
|
||||
append_rollout_item_to_path(
|
||||
&parent_rollout_path,
|
||||
&RolloutItem::SessionMeta(Box::new(parent_meta)),
|
||||
)
|
||||
.await?;
|
||||
// Legacy children resume before the root restores the V2 registry from persisted spawn edges.
|
||||
let mut expected = vec![(cli_id.clone(), None, false)];
|
||||
let mut threads_to_resume = vec![(cli_id.clone(), SessionSource::Cli, Some(true))];
|
||||
@@ -1736,7 +1739,8 @@ async fn thread_list_reports_loaded_subagent_direct_input_capability() -> Result
|
||||
let source = SessionSource::from(session_meta.meta.source.clone());
|
||||
if let Some(version) = version {
|
||||
session_meta.meta.multi_agent_version = Some(version);
|
||||
append_rollout_item_to_path(&path, &RolloutItem::SessionMeta(session_meta)).await?;
|
||||
append_rollout_item_to_path(&path, &RolloutItem::SessionMeta(Box::new(session_meta)))
|
||||
.await?;
|
||||
}
|
||||
if should_resume {
|
||||
let resume = (thread_id.clone(), source, capability);
|
||||
|
||||
@@ -195,7 +195,7 @@ async fn thread_resume_paginated_model_context_preserves_original_metadata() ->
|
||||
}))?;
|
||||
append_rollout_item_to_path(
|
||||
&path,
|
||||
&RolloutItem::Compacted(CompactedItem {
|
||||
&RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: "compacted history".to_string(),
|
||||
replacement_history: Some(Vec::new()),
|
||||
retained_context: None,
|
||||
@@ -208,7 +208,7 @@ async fn thread_resume_paginated_model_context_preserves_original_metadata() ->
|
||||
compaction_response_id: None,
|
||||
latest_token_usage_record: None,
|
||||
resume_metadata: None,
|
||||
}),
|
||||
})),
|
||||
)
|
||||
.await?;
|
||||
append_rollout_item_to_path(
|
||||
@@ -2158,7 +2158,7 @@ async fn unloaded_thread_goal_mutations_respect_parent_ownership() -> Result<()>
|
||||
// must take precedence, just as it does when the thread resumes.
|
||||
let mut meta = read_session_meta_line(&path).await?;
|
||||
meta.meta.multi_agent_version = version;
|
||||
append_rollout_item_to_path(&path, &RolloutItem::SessionMeta(meta)).await?;
|
||||
append_rollout_item_to_path(&path, &RolloutItem::SessionMeta(Box::new(meta))).await?;
|
||||
|
||||
for (method, params) in [
|
||||
(
|
||||
@@ -6487,8 +6487,11 @@ async fn setup_rollout_fixture(codex_home: &Path, server_uri: &str) -> Result<Ro
|
||||
let rollout_file_path = rollout_path(codex_home, filename_ts, &conversation_id);
|
||||
let mut session_meta = read_session_meta_line(&rollout_file_path).await?;
|
||||
session_meta.meta.multi_agent_version = Some(MultiAgentVersion::V1);
|
||||
append_rollout_item_to_path(&rollout_file_path, &RolloutItem::SessionMeta(session_meta))
|
||||
.await?;
|
||||
append_rollout_item_to_path(
|
||||
&rollout_file_path,
|
||||
&RolloutItem::SessionMeta(Box::new(session_meta)),
|
||||
)
|
||||
.await?;
|
||||
set_rollout_mtime(rollout_file_path.as_path(), expected_updated_at_rfc3339)?;
|
||||
Ok(RolloutFixture {
|
||||
conversation_id,
|
||||
|
||||
@@ -1332,20 +1332,22 @@ mod tests {
|
||||
let rollout_line = RolloutLine {
|
||||
timestamp: timestamp.to_string(),
|
||||
ordinal: None,
|
||||
item: RolloutItem::SessionMeta(codex_protocol::protocol::SessionMetaLine {
|
||||
meta: codex_protocol::protocol::SessionMeta {
|
||||
session_id: parsed_thread_id.into(),
|
||||
id: parsed_thread_id,
|
||||
timestamp: timestamp.to_string(),
|
||||
cwd: self.codex_home.path().to_path_buf(),
|
||||
originator: "test".to_string(),
|
||||
cli_version: "test".to_string(),
|
||||
source: SessionSource::Cli,
|
||||
model_provider: Some("test-provider".to_string()),
|
||||
..Default::default()
|
||||
item: RolloutItem::SessionMeta(Box::new(
|
||||
codex_protocol::protocol::SessionMetaLine {
|
||||
meta: codex_protocol::protocol::SessionMeta {
|
||||
session_id: parsed_thread_id.into(),
|
||||
id: parsed_thread_id,
|
||||
timestamp: timestamp.to_string(),
|
||||
cwd: self.codex_home.path().to_path_buf(),
|
||||
originator: "test".to_string(),
|
||||
cli_version: "test".to_string(),
|
||||
source: SessionSource::Cli,
|
||||
model_provider: Some("test-provider".to_string()),
|
||||
..Default::default()
|
||||
},
|
||||
git: None,
|
||||
},
|
||||
git: None,
|
||||
}),
|
||||
)),
|
||||
};
|
||||
let contents = serde_json::to_string(&rollout_line).expect("rollout line");
|
||||
std::fs::write(&path, format!("{contents}\n")).expect("rollout file");
|
||||
|
||||
@@ -2695,7 +2695,7 @@ async fn spawn_agent_fork_sanitizes_inherited_compaction_metadata() {
|
||||
parent_thread
|
||||
.session
|
||||
.persist_rollout_items(&[
|
||||
RolloutItem::Compacted(CompactedItem {
|
||||
RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: String::new(),
|
||||
replacement_history: Some(vec![user_message("compacted parent context").into()]),
|
||||
retained_context: None,
|
||||
@@ -2708,7 +2708,7 @@ async fn spawn_agent_fork_sanitizes_inherited_compaction_metadata() {
|
||||
compaction_response_id: None,
|
||||
latest_token_usage_record: Some(parent_record.clone()),
|
||||
resume_metadata: Some(parent_resume_metadata.clone()),
|
||||
}),
|
||||
})),
|
||||
RolloutItem::TokenUsageRecord(parent_record),
|
||||
rollout_response_item(spawn_agent_call(&parent_spawn_call_id)),
|
||||
])
|
||||
@@ -3378,7 +3378,7 @@ async fn spawn_agent_fork_strips_parent_usage_hints_from_compacted_history(marke
|
||||
parent_thread
|
||||
.session
|
||||
.persist_rollout_items(&[
|
||||
RolloutItem::Compacted(CompactedItem {
|
||||
RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: String::new(),
|
||||
replacement_history: Some(
|
||||
replacement_history
|
||||
@@ -3399,7 +3399,7 @@ async fn spawn_agent_fork_strips_parent_usage_hints_from_compacted_history(marke
|
||||
compaction_response_id: None,
|
||||
latest_token_usage_record: None,
|
||||
resume_metadata: None,
|
||||
}),
|
||||
})),
|
||||
RolloutItem::RetainedContext(answer_event),
|
||||
RolloutItem::ResponseItem(delivery),
|
||||
RolloutItem::TurnContext(turn_context.to_turn_context_item()),
|
||||
@@ -3609,7 +3609,7 @@ async fn spawn_agent_full_fork_restores_instructions_after_compaction_discards_p
|
||||
phase: None,
|
||||
internal_chat_message_metadata_passthrough: None,
|
||||
}),
|
||||
RolloutItem::Compacted(CompactedItem {
|
||||
RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: String::new(),
|
||||
replacement_history: Some(
|
||||
replacement_history.into_iter().map(Into::into).collect(),
|
||||
@@ -3624,7 +3624,7 @@ async fn spawn_agent_full_fork_restores_instructions_after_compaction_discards_p
|
||||
compaction_response_id: None,
|
||||
latest_token_usage_record: None,
|
||||
resume_metadata: None,
|
||||
}),
|
||||
})),
|
||||
RolloutItem::TurnContext(turn_context.to_turn_context_item()),
|
||||
rollout_response_item(spawn_agent_call(&parent_spawn_call_id)),
|
||||
])
|
||||
@@ -3805,7 +3805,7 @@ async fn spawn_agent_full_fork_legacy_compaction_rebuilds_child_instructions_onc
|
||||
.await;
|
||||
let mut rollout_items = vec![
|
||||
rollout_response_item(parent_user_message),
|
||||
RolloutItem::Compacted(CompactedItem {
|
||||
RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: "legacy compacted summary".to_string(),
|
||||
replacement_history: None,
|
||||
retained_context: None,
|
||||
@@ -3828,7 +3828,7 @@ async fn spawn_agent_full_fork_legacy_compaction_rebuilds_child_instructions_onc
|
||||
realtime_active: None,
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
})),
|
||||
];
|
||||
if let Some(instructions) = parent_developer_instructions {
|
||||
rollout_items.push(rollout_response_item(ResponseItem::Message {
|
||||
|
||||
@@ -12,7 +12,7 @@ impl Session {
|
||||
let state = self.state.lock().await;
|
||||
let history = &state.history;
|
||||
let window_ids = state.auto_compact_window_ids();
|
||||
let mut items = vec![RolloutItem::Compacted(CompactedItem {
|
||||
let mut items = vec![RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: String::new(),
|
||||
replacement_history: Some(history.annotated_items().to_vec()),
|
||||
guardian_history: history.guardian_history_checkpoint(),
|
||||
@@ -25,7 +25,7 @@ impl Session {
|
||||
compaction_response_id: None,
|
||||
latest_token_usage_record: state.latest_token_usage_record.clone(),
|
||||
resume_metadata: None,
|
||||
})];
|
||||
}))];
|
||||
if let Some(world_state) = history.world_state_checkpoint() {
|
||||
items.push(RolloutItem::WorldState(world_state));
|
||||
}
|
||||
|
||||
@@ -4416,7 +4416,7 @@ impl Session {
|
||||
}
|
||||
let world_state_item = WorldStateItem::full(world_state_baseline.into_object());
|
||||
let rollout_items = [
|
||||
RolloutItem::Compacted(compacted_item),
|
||||
RolloutItem::Compacted(Box::new(compacted_item)),
|
||||
RolloutItem::WorldState(world_state_item),
|
||||
RolloutItem::TurnContext(reference_context_item),
|
||||
// The frozen turn context must not override current settings in persisted metadata.
|
||||
|
||||
@@ -173,7 +173,7 @@ async fn sender_context_follows_its_delivery_through_checkpoint_and_rollback() {
|
||||
checkpoint.replacement_history = Some(live.annotated_items().to_vec());
|
||||
checkpoint.retained_context = Some(live.retained_context().clone());
|
||||
let mut checkpointed = items.clone();
|
||||
checkpointed.push(RolloutItem::Compacted(checkpoint));
|
||||
checkpointed.push(RolloutItem::Compacted(Box::new(checkpoint)));
|
||||
for (num_turns, expected) in [(1, &snapshots[1]), (2, &snapshots[0])] {
|
||||
let mut rolled_back = live.clone();
|
||||
rolled_back.drop_last_n_user_turns(num_turns);
|
||||
@@ -1304,7 +1304,7 @@ async fn record_initial_history_resumed_rollback_drops_incomplete_user_turn_comp
|
||||
..Default::default()
|
||||
},
|
||||
)),
|
||||
RolloutItem::Compacted(CompactedItem {
|
||||
RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: String::new(),
|
||||
replacement_history: Some(Vec::new()),
|
||||
retained_context: None,
|
||||
@@ -1317,7 +1317,7 @@ async fn record_initial_history_resumed_rollback_drops_incomplete_user_turn_comp
|
||||
compaction_response_id: None,
|
||||
latest_token_usage_record: None,
|
||||
resume_metadata: None,
|
||||
}),
|
||||
})),
|
||||
RolloutItem::EventMsg(EventMsg::ThreadRolledBack(
|
||||
codex_protocol::protocol::ThreadRolledBackEvent { num_turns: 1 },
|
||||
)),
|
||||
@@ -1371,7 +1371,7 @@ async fn record_initial_history_requires_surviving_full_snapshot_without_user_tu
|
||||
}
|
||||
MissingContextBaseline::CompactedSnapshot => vec![
|
||||
RolloutItem::WorldState(WorldStateItem::full(object!({}))),
|
||||
RolloutItem::Compacted(CompactedItem {
|
||||
RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: String::new(),
|
||||
replacement_history: Some(Vec::new()),
|
||||
retained_context: None,
|
||||
@@ -1384,7 +1384,7 @@ async fn record_initial_history_requires_surviving_full_snapshot_without_user_tu
|
||||
compaction_response_id: None,
|
||||
latest_token_usage_record: None,
|
||||
resume_metadata: None,
|
||||
}),
|
||||
})),
|
||||
],
|
||||
};
|
||||
rollout_items.push(RolloutItem::TurnContext(
|
||||
@@ -1409,7 +1409,7 @@ async fn record_initial_history_resumed_does_not_seed_reference_context_item_aft
|
||||
let previous_context_item = turn_context.to_turn_context_item();
|
||||
let rollout_items = vec![
|
||||
RolloutItem::TurnContext(previous_context_item),
|
||||
RolloutItem::Compacted(CompactedItem {
|
||||
RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: String::new(),
|
||||
replacement_history: Some(Vec::new()),
|
||||
retained_context: None,
|
||||
@@ -1422,7 +1422,7 @@ async fn record_initial_history_resumed_does_not_seed_reference_context_item_aft
|
||||
compaction_response_id: None,
|
||||
latest_token_usage_record: None,
|
||||
resume_metadata: None,
|
||||
}),
|
||||
})),
|
||||
];
|
||||
|
||||
session
|
||||
@@ -1443,7 +1443,7 @@ async fn reconstruct_history_restores_initial_window_from_session_meta() {
|
||||
let (session, turn_context) = make_session_and_context().await;
|
||||
let thread_id = ThreadId::default();
|
||||
let initial_window_id = Uuid::now_v7();
|
||||
let rollout_items = vec![RolloutItem::SessionMeta(SessionMetaLine {
|
||||
let rollout_items = vec![RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: SessionMeta {
|
||||
session_id: thread_id.into(),
|
||||
id: thread_id,
|
||||
@@ -1453,7 +1453,7 @@ async fn reconstruct_history_restores_initial_window_from_session_meta() {
|
||||
..SessionMeta::default()
|
||||
},
|
||||
git: None,
|
||||
})];
|
||||
}))];
|
||||
|
||||
let reconstructed = session
|
||||
.reconstruct_history_from_rollout(&turn_context, &rollout_items)
|
||||
@@ -1474,7 +1474,7 @@ async fn reconstruct_history_prefers_compacted_window_over_session_meta() {
|
||||
let compacted_previous_window_id = Uuid::now_v7();
|
||||
let compacted_window_id = Uuid::now_v7();
|
||||
let rollout_items = vec![
|
||||
RolloutItem::SessionMeta(SessionMetaLine {
|
||||
RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: SessionMeta {
|
||||
session_id: thread_id.into(),
|
||||
id: thread_id,
|
||||
@@ -1484,8 +1484,8 @@ async fn reconstruct_history_prefers_compacted_window_over_session_meta() {
|
||||
..SessionMeta::default()
|
||||
},
|
||||
git: None,
|
||||
}),
|
||||
RolloutItem::Compacted(CompactedItem {
|
||||
})),
|
||||
RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: String::new(),
|
||||
replacement_history: Some(Vec::new()),
|
||||
retained_context: None,
|
||||
@@ -1498,7 +1498,7 @@ async fn reconstruct_history_prefers_compacted_window_over_session_meta() {
|
||||
compaction_response_id: None,
|
||||
latest_token_usage_record: None,
|
||||
resume_metadata: None,
|
||||
}),
|
||||
})),
|
||||
];
|
||||
|
||||
let reconstructed = session
|
||||
@@ -1526,7 +1526,7 @@ async fn reconstruct_history_replays_world_state_from_latest_compaction_window()
|
||||
RolloutItem::WorldState(WorldStateItem::full(object!({
|
||||
"environment": {"status": "old"}
|
||||
}))),
|
||||
RolloutItem::Compacted(CompactedItem {
|
||||
RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: String::new(),
|
||||
replacement_history: Some(Vec::new()),
|
||||
retained_context: None,
|
||||
@@ -1539,7 +1539,7 @@ async fn reconstruct_history_replays_world_state_from_latest_compaction_window()
|
||||
compaction_response_id: None,
|
||||
latest_token_usage_record: None,
|
||||
resume_metadata: None,
|
||||
}),
|
||||
})),
|
||||
RolloutItem::WorldState(WorldStateItem::full(object!({
|
||||
"environment": {"status": "starting", "cwd": "/workspace"}
|
||||
}))),
|
||||
@@ -1584,7 +1584,7 @@ async fn bounded_replay_matches_full_replay_after_empty_turn_compactions(
|
||||
git: None,
|
||||
};
|
||||
let initial_context = turn_context.to_turn_context_item();
|
||||
let mut rollout_items = vec![RolloutItem::SessionMeta(session_meta.clone())];
|
||||
let mut rollout_items = vec![RolloutItem::SessionMeta(Box::new(session_meta.clone()))];
|
||||
rollout_items.extend(completed_user_turn_rollout(
|
||||
initial_context.clone(),
|
||||
vec![RolloutItem::ResponseItem(
|
||||
@@ -1603,7 +1603,7 @@ async fn bounded_replay_matches_full_replay_after_empty_turn_compactions(
|
||||
let mut wake_items = completed_user_turn_rollout(
|
||||
context.clone(),
|
||||
vec![
|
||||
RolloutItem::Compacted(CompactedItem {
|
||||
RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: String::new(),
|
||||
replacement_history: Some(annotated(vec![object!({
|
||||
"type": "compaction",
|
||||
@@ -1632,7 +1632,7 @@ async fn bounded_replay_matches_full_replay_after_empty_turn_compactions(
|
||||
realtime_active: Some(false),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
})),
|
||||
RolloutItem::WorldState(WorldStateItem::full(object!({
|
||||
"environment": {"window": window_number, "status": "starting"}
|
||||
}))),
|
||||
@@ -1679,7 +1679,7 @@ async fn bounded_replay_matches_full_replay_after_empty_turn_compactions(
|
||||
});
|
||||
assert_eq!(cutoff, Some(latest_compaction_index));
|
||||
let mut bounded_items = scan.finish();
|
||||
bounded_items.insert(0, RolloutItem::SessionMeta(session_meta));
|
||||
bounded_items.insert(0, RolloutItem::SessionMeta(Box::new(session_meta)));
|
||||
let full = session
|
||||
.reconstruct_history_from_rollout(&turn_context, &rollout_items)
|
||||
.await;
|
||||
@@ -1723,7 +1723,7 @@ async fn paginated_compaction_does_not_restore_missing_companions_from_older_his
|
||||
let rollout_items = vec![
|
||||
RolloutItem::TurnContext(turn_context.to_turn_context_item()),
|
||||
RolloutItem::WorldState(WorldStateItem::full(object!({"older": true}))),
|
||||
RolloutItem::Compacted(compacted),
|
||||
RolloutItem::Compacted(Box::new(compacted)),
|
||||
];
|
||||
|
||||
let reconstructed = session
|
||||
@@ -1819,7 +1819,7 @@ async fn reconstruct_attribution_ignores_previous_terminal_after_checkpoint(
|
||||
.pop()
|
||||
.expect("previous turn completion");
|
||||
let mut rollout = vec![
|
||||
RolloutItem::Compacted(object!({
|
||||
RolloutItem::Compacted(Box::new(object!({
|
||||
"message": "summary",
|
||||
"replacement_history": [user_message("original work")],
|
||||
"window_number": 1,
|
||||
@@ -1828,7 +1828,7 @@ async fn reconstruct_attribution_ignores_previous_terminal_after_checkpoint(
|
||||
"turn_attribution": expected,
|
||||
"previous_turn_settings": settings
|
||||
}
|
||||
})),
|
||||
}))),
|
||||
RolloutItem::ResponseItem(user_message("continued work").into()),
|
||||
RolloutItem::TurnContext(context.clone()),
|
||||
late_terminal,
|
||||
@@ -1880,7 +1880,7 @@ async fn completed_turn_suffix_after_compaction_overrides_resume_metadata(
|
||||
realtime_active: newer_context.realtime_active,
|
||||
};
|
||||
let mut rollout_items = vec![
|
||||
RolloutItem::Compacted(object!({
|
||||
RolloutItem::Compacted(Box::new(object!({
|
||||
"message": "summary",
|
||||
"replacement_history": [user_message("seed"), assistant_message("summary")],
|
||||
"window_number": 1,
|
||||
@@ -1892,7 +1892,7 @@ async fn completed_turn_suffix_after_compaction_overrides_resume_metadata(
|
||||
"comp_hash": "metadata-hash"
|
||||
}
|
||||
}
|
||||
})),
|
||||
}))),
|
||||
RolloutItem::WorldState(WorldStateItem::full(object!({}))),
|
||||
];
|
||||
// The bounded suffix starts at the compaction, so the turn start and user input are already in
|
||||
@@ -1959,7 +1959,7 @@ async fn reconstruct_history_preserves_legacy_compaction_count_with_session_meta
|
||||
let thread_id = ThreadId::default();
|
||||
let initial_window_id = Uuid::now_v7();
|
||||
let rollout_items = vec![
|
||||
RolloutItem::SessionMeta(SessionMetaLine {
|
||||
RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: SessionMeta {
|
||||
session_id: thread_id.into(),
|
||||
id: thread_id,
|
||||
@@ -1969,8 +1969,8 @@ async fn reconstruct_history_preserves_legacy_compaction_count_with_session_meta
|
||||
..SessionMeta::default()
|
||||
},
|
||||
git: None,
|
||||
}),
|
||||
RolloutItem::Compacted(CompactedItem {
|
||||
})),
|
||||
RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: "legacy summary".to_string(),
|
||||
replacement_history: None,
|
||||
retained_context: None,
|
||||
@@ -1983,7 +1983,7 @@ async fn reconstruct_history_preserves_legacy_compaction_count_with_session_meta
|
||||
compaction_response_id: None,
|
||||
latest_token_usage_record: None,
|
||||
resume_metadata: None,
|
||||
}),
|
||||
})),
|
||||
];
|
||||
|
||||
let reconstructed = session
|
||||
@@ -2028,7 +2028,7 @@ async fn reconstruct_history_legacy_compaction_without_replacement_history_does_
|
||||
RolloutItem::ResponseItem(user_message("before compact").into()),
|
||||
RolloutItem::ResponseItem(assistant_message("assistant reply").into()),
|
||||
RolloutItem::RetainedContext(answer),
|
||||
RolloutItem::Compacted(CompactedItem {
|
||||
RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: "legacy summary".to_string(),
|
||||
replacement_history: None,
|
||||
retained_context: None,
|
||||
@@ -2041,7 +2041,7 @@ async fn reconstruct_history_legacy_compaction_without_replacement_history_does_
|
||||
compaction_response_id: None,
|
||||
latest_token_usage_record: None,
|
||||
resume_metadata: None,
|
||||
}),
|
||||
})),
|
||||
];
|
||||
|
||||
let reconstructed = session
|
||||
@@ -2070,7 +2070,7 @@ async fn reconstruct_history_legacy_compaction_without_replacement_history_clear
|
||||
.expect("turn context should have turn_id");
|
||||
let rollout_items = vec![
|
||||
RolloutItem::ResponseItem(user_message("before compact").into()),
|
||||
RolloutItem::Compacted(CompactedItem {
|
||||
RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: "legacy summary".to_string(),
|
||||
replacement_history: None,
|
||||
retained_context: None,
|
||||
@@ -2083,7 +2083,7 @@ async fn reconstruct_history_legacy_compaction_without_replacement_history_clear
|
||||
compaction_response_id: None,
|
||||
latest_token_usage_record: None,
|
||||
resume_metadata: None,
|
||||
}),
|
||||
})),
|
||||
RolloutItem::EventMsg(EventMsg::TurnStarted(
|
||||
codex_protocol::protocol::TurnStartedEvent {
|
||||
turn_attribution: None,
|
||||
@@ -2180,7 +2180,7 @@ async fn record_initial_history_resumed_turn_context_after_compaction_reestablis
|
||||
},
|
||||
)),
|
||||
// Compaction clears baseline until a later TurnContextItem re-establishes it.
|
||||
RolloutItem::Compacted(CompactedItem {
|
||||
RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: String::new(),
|
||||
replacement_history: Some(Vec::new()),
|
||||
retained_context: None,
|
||||
@@ -2193,7 +2193,7 @@ async fn record_initial_history_resumed_turn_context_after_compaction_reestablis
|
||||
compaction_response_id: None,
|
||||
latest_token_usage_record: None,
|
||||
resume_metadata: None,
|
||||
}),
|
||||
})),
|
||||
RolloutItem::TurnContext(previous_context_item),
|
||||
RolloutItem::EventMsg(EventMsg::TurnComplete(
|
||||
codex_protocol::protocol::TurnCompleteEvent {
|
||||
@@ -2354,7 +2354,7 @@ async fn record_initial_history_resumed_aborted_turn_without_id_clears_active_tu
|
||||
duration_ms: None,
|
||||
},
|
||||
)),
|
||||
RolloutItem::Compacted(CompactedItem {
|
||||
RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: String::new(),
|
||||
replacement_history: Some(Vec::new()),
|
||||
retained_context: None,
|
||||
@@ -2367,7 +2367,7 @@ async fn record_initial_history_resumed_aborted_turn_without_id_clears_active_tu
|
||||
compaction_response_id: None,
|
||||
latest_token_usage_record: None,
|
||||
resume_metadata: None,
|
||||
}),
|
||||
})),
|
||||
];
|
||||
|
||||
session
|
||||
@@ -2621,7 +2621,7 @@ async fn record_initial_history_resumed_trailing_incomplete_turn_compaction_clea
|
||||
..Default::default()
|
||||
},
|
||||
)),
|
||||
RolloutItem::Compacted(CompactedItem {
|
||||
RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: String::new(),
|
||||
replacement_history: Some(Vec::new()),
|
||||
retained_context: None,
|
||||
@@ -2634,7 +2634,7 @@ async fn record_initial_history_resumed_trailing_incomplete_turn_compaction_clea
|
||||
compaction_response_id: None,
|
||||
latest_token_usage_record: None,
|
||||
resume_metadata: None,
|
||||
}),
|
||||
})),
|
||||
];
|
||||
|
||||
session
|
||||
@@ -2807,7 +2807,7 @@ async fn record_initial_history_resumed_replaced_incomplete_compacted_turn_clear
|
||||
..Default::default()
|
||||
},
|
||||
)),
|
||||
RolloutItem::Compacted(CompactedItem {
|
||||
RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: String::new(),
|
||||
replacement_history: Some(Vec::new()),
|
||||
retained_context: None,
|
||||
@@ -2820,7 +2820,7 @@ async fn record_initial_history_resumed_replaced_incomplete_compacted_turn_clear
|
||||
compaction_response_id: None,
|
||||
latest_token_usage_record: None,
|
||||
resume_metadata: None,
|
||||
}),
|
||||
})),
|
||||
// A newer TurnStarted replaces the incomplete compacted turn without a matching
|
||||
// completion/abort for the old one.
|
||||
RolloutItem::EventMsg(EventMsg::TurnStarted(
|
||||
|
||||
@@ -2469,7 +2469,7 @@ async fn reconstruct_history_uses_replacement_history_verbatim() {
|
||||
let first_window_id = Uuid::now_v7();
|
||||
let previous_window_id = Uuid::now_v7();
|
||||
let window_id = Uuid::now_v7();
|
||||
let rollout_items = vec![RolloutItem::Compacted(CompactedItem {
|
||||
let rollout_items = vec![RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: String::new(),
|
||||
replacement_history: Some(replacement_history.clone()),
|
||||
retained_context: None,
|
||||
@@ -2482,7 +2482,7 @@ async fn reconstruct_history_uses_replacement_history_verbatim() {
|
||||
compaction_response_id: None,
|
||||
latest_token_usage_record: None,
|
||||
resume_metadata: None,
|
||||
})];
|
||||
}))];
|
||||
|
||||
let reconstructed = session
|
||||
.reconstruct_history_from_rollout(&turn_context, &rollout_items)
|
||||
@@ -2749,7 +2749,7 @@ async fn inter_agent_communication_waits_for_confirmed_delivery_persistence() {
|
||||
compacted.retained_context = Some(live.retained_context().clone());
|
||||
let mut history = resumed.history.as_ref().clone();
|
||||
history.extend([
|
||||
RolloutItem::Compacted(compacted),
|
||||
RolloutItem::Compacted(Box::new(compacted)),
|
||||
RolloutItem::EventMsg(EventMsg::ThreadRolledBack(
|
||||
codex_protocol::protocol::ThreadRolledBackEvent { num_turns: 1 },
|
||||
)),
|
||||
@@ -3280,7 +3280,7 @@ fn session_meta_item(
|
||||
thread_id: ThreadId,
|
||||
multi_agent_version: Option<MultiAgentVersion>,
|
||||
) -> RolloutItem {
|
||||
RolloutItem::SessionMeta(SessionMetaLine {
|
||||
RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: SessionMeta {
|
||||
session_id: thread_id.into(),
|
||||
id: thread_id,
|
||||
@@ -3288,7 +3288,7 @@ fn session_meta_item(
|
||||
..SessionMeta::default()
|
||||
},
|
||||
git: None,
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -3435,7 +3435,7 @@ fn latest_token_usage_record_stops_at_compaction_checkpoint() {
|
||||
thread_token_usage: TokenUsage::default(),
|
||||
};
|
||||
let checkpoint = |latest_token_usage_record| {
|
||||
RolloutItem::Compacted(CompactedItem {
|
||||
RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: String::new(),
|
||||
replacement_history: None,
|
||||
retained_context: None,
|
||||
@@ -3448,7 +3448,7 @@ fn latest_token_usage_record_stops_at_compaction_checkpoint() {
|
||||
compaction_response_id: None,
|
||||
latest_token_usage_record,
|
||||
resume_metadata: None,
|
||||
})
|
||||
}))
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
@@ -7409,7 +7409,7 @@ async fn resumed_subagent_session_restores_persisted_session_id() {
|
||||
InitialHistory::Resumed(ResumedHistory {
|
||||
history_revision: None,
|
||||
conversation_id: thread_id,
|
||||
history: Arc::new(vec![RolloutItem::SessionMeta(SessionMetaLine {
|
||||
history: Arc::new(vec![RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: SessionMeta {
|
||||
session_id: parent_session_id,
|
||||
id: thread_id,
|
||||
@@ -7417,7 +7417,7 @@ async fn resumed_subagent_session_restores_persisted_session_id() {
|
||||
..SessionMeta::default()
|
||||
},
|
||||
git: None,
|
||||
})]),
|
||||
}))]),
|
||||
rollout_path: None,
|
||||
}),
|
||||
session_source,
|
||||
@@ -7443,7 +7443,7 @@ async fn resumed_copied_fork_ignores_source_history_base() {
|
||||
let parent_thread_id = ThreadId::new();
|
||||
let thread_id = ThreadId::new();
|
||||
let history = vec![
|
||||
RolloutItem::SessionMeta(SessionMetaLine {
|
||||
RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: SessionMeta {
|
||||
id: thread_id,
|
||||
session_id: SessionId::from(thread_id),
|
||||
@@ -7451,8 +7451,8 @@ async fn resumed_copied_fork_ignores_source_history_base() {
|
||||
..SessionMeta::default()
|
||||
},
|
||||
git: None,
|
||||
}),
|
||||
RolloutItem::SessionMeta(SessionMetaLine {
|
||||
})),
|
||||
RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: SessionMeta {
|
||||
id: parent_thread_id,
|
||||
session_id: SessionId::from(parent_thread_id),
|
||||
@@ -7465,7 +7465,7 @@ async fn resumed_copied_fork_ignores_source_history_base() {
|
||||
..SessionMeta::default()
|
||||
},
|
||||
git: None,
|
||||
}),
|
||||
})),
|
||||
];
|
||||
let (session, _rx_event) = make_session_with_history_source_and_agent_control_and_rx(
|
||||
InitialHistory::Resumed(ResumedHistory {
|
||||
@@ -13279,7 +13279,7 @@ async fn sample_rollout(
|
||||
let rebuilt1 = compact::build_compacted_history(Vec::new(), &user_messages1, summary1);
|
||||
live_history.replace_annotated(rebuilt1);
|
||||
let (window_number, window_ids) = session.advance_auto_compact_window().await;
|
||||
rollout_items.push(RolloutItem::Compacted(CompactedItem {
|
||||
rollout_items.push(RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: summary1.to_string(),
|
||||
replacement_history: None,
|
||||
retained_context: None,
|
||||
@@ -13292,7 +13292,7 @@ async fn sample_rollout(
|
||||
compaction_response_id: None,
|
||||
latest_token_usage_record: None,
|
||||
resume_metadata: None,
|
||||
}));
|
||||
})));
|
||||
|
||||
let user2 = user_message("second user");
|
||||
live_history.record_items(
|
||||
@@ -13314,7 +13314,7 @@ async fn sample_rollout(
|
||||
let rebuilt2 = compact::build_compacted_history(Vec::new(), &user_messages2, summary2);
|
||||
live_history.replace_annotated(rebuilt2);
|
||||
let (window_number, window_ids) = session.advance_auto_compact_window().await;
|
||||
rollout_items.push(RolloutItem::Compacted(CompactedItem {
|
||||
rollout_items.push(RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: summary2.to_string(),
|
||||
replacement_history: None,
|
||||
retained_context: None,
|
||||
@@ -13327,7 +13327,7 @@ async fn sample_rollout(
|
||||
compaction_response_id: None,
|
||||
latest_token_usage_record: None,
|
||||
resume_metadata: None,
|
||||
}));
|
||||
})));
|
||||
|
||||
let user3 = user_message("third user");
|
||||
live_history.record_items(
|
||||
|
||||
@@ -2022,7 +2022,7 @@ async fn selected_capability_roots_round_trip_through_fork() {
|
||||
}];
|
||||
let inherited = manager
|
||||
.start_thread(StartThreadOptions {
|
||||
initial_history: InitialHistory::Forked(vec![RolloutItem::SessionMeta(
|
||||
initial_history: InitialHistory::Forked(vec![RolloutItem::SessionMeta(Box::new(
|
||||
SessionMetaLine {
|
||||
meta: SessionMeta {
|
||||
selected_capability_roots: selected_roots.clone(),
|
||||
@@ -2030,7 +2030,7 @@ async fn selected_capability_roots_round_trip_through_fork() {
|
||||
},
|
||||
git: None,
|
||||
},
|
||||
)]),
|
||||
))]),
|
||||
environments: Some(Vec::new()),
|
||||
..StartThreadOptions::new(config)
|
||||
})
|
||||
@@ -2117,7 +2117,7 @@ async fn selected_capability_roots_respect_startup_precedence_and_isolation() {
|
||||
}
|
||||
let child = manager
|
||||
.start_thread(StartThreadOptions {
|
||||
initial_history: InitialHistory::Forked(vec![RolloutItem::SessionMeta(
|
||||
initial_history: InitialHistory::Forked(vec![RolloutItem::SessionMeta(Box::new(
|
||||
SessionMetaLine {
|
||||
meta: SessionMeta {
|
||||
selected_capability_roots: vec![root("saved")],
|
||||
@@ -2125,7 +2125,7 @@ async fn selected_capability_roots_respect_startup_precedence_and_isolation() {
|
||||
},
|
||||
git: None,
|
||||
},
|
||||
)]),
|
||||
))]),
|
||||
inherited_environments: Some(parent_environments.clone()),
|
||||
thread_extension_init,
|
||||
..StartThreadOptions::new(config.clone())
|
||||
|
||||
@@ -66,7 +66,7 @@ fn restores_cumulative_item_and_compaction_checkpoints() {
|
||||
};
|
||||
let history = InitialHistory::Forked(vec![
|
||||
RolloutItem::ResponseItem(envelope(Some(initial))),
|
||||
RolloutItem::Compacted(CompactedItem {
|
||||
RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: "summary".to_string(),
|
||||
replacement_history: Some(vec![envelope(Some(cumulative.clone()))]),
|
||||
guardian_history: None,
|
||||
@@ -79,7 +79,7 @@ fn restores_cumulative_item_and_compaction_checkpoints() {
|
||||
compaction_response_id: None,
|
||||
latest_token_usage_record: None,
|
||||
resume_metadata: None,
|
||||
}),
|
||||
})),
|
||||
]);
|
||||
|
||||
assert_eq!(McpAttributionRecorder::new(&history).snapshot(), cumulative);
|
||||
@@ -135,7 +135,7 @@ fn first_error_reason_survives_checkpoints_and_later_sources() {
|
||||
compacted.replacement_history = Some(vec![checkpoint.clone()]);
|
||||
for item in [
|
||||
RolloutItem::ResponseItem(checkpoint),
|
||||
RolloutItem::Compacted(compacted),
|
||||
RolloutItem::Compacted(Box::new(compacted)),
|
||||
] {
|
||||
let restored = McpAttributionRecorder::new(&InitialHistory::Forked(vec![item]));
|
||||
restored.record(source("", "turn_3"));
|
||||
|
||||
@@ -967,13 +967,13 @@ fn tool_call_completeness_survives_waits_without_changing_deltas() {
|
||||
fn paginated_history_allows_fresh_origins_but_rejects_known_ids() {
|
||||
for origin in ["fresh-exec", "old-exec"] {
|
||||
let history = InitialHistory::Forked(vec![
|
||||
RolloutItem::SessionMeta(SessionMetaLine {
|
||||
RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: SessionMeta {
|
||||
history_mode: ThreadHistoryMode::Paginated,
|
||||
..SessionMeta::default()
|
||||
},
|
||||
git: None,
|
||||
}),
|
||||
})),
|
||||
RolloutItem::ResponseItem(exec_input("old-exec").into()),
|
||||
RolloutItem::ResponseItem(exec_output("old-exec").into()),
|
||||
]);
|
||||
|
||||
@@ -673,7 +673,7 @@ async fn synthetic_call_output_id_is_stable_across_resumes() -> anyhow::Result<(
|
||||
RolloutLine {
|
||||
timestamp: "2024-01-01T00:00:00.000Z".to_string(),
|
||||
ordinal: None,
|
||||
item: RolloutItem::SessionMeta(SessionMetaLine {
|
||||
item: RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: SessionMeta {
|
||||
session_id: thread_id.into(),
|
||||
id: thread_id,
|
||||
@@ -686,7 +686,7 @@ async fn synthetic_call_output_id_is_stable_across_resumes() -> anyhow::Result<(
|
||||
..Default::default()
|
||||
},
|
||||
git: None,
|
||||
}),
|
||||
})),
|
||||
},
|
||||
RolloutLine {
|
||||
timestamp: "2024-01-01T00:00:01.000Z".to_string(),
|
||||
@@ -1187,7 +1187,7 @@ async fn resume_replays_legacy_js_repl_image_rollout_shapes() {
|
||||
RolloutLine {
|
||||
timestamp: "2024-01-01T00:00:00.000Z".to_string(),
|
||||
ordinal: None,
|
||||
item: RolloutItem::SessionMeta(SessionMetaLine {
|
||||
item: RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: SessionMeta {
|
||||
session_id: thread_id.into(),
|
||||
id: thread_id,
|
||||
@@ -1200,7 +1200,7 @@ async fn resume_replays_legacy_js_repl_image_rollout_shapes() {
|
||||
..Default::default()
|
||||
},
|
||||
git: None,
|
||||
}),
|
||||
})),
|
||||
},
|
||||
RolloutLine {
|
||||
timestamp: "2024-01-01T00:00:01.000Z".to_string(),
|
||||
@@ -1331,7 +1331,7 @@ async fn resume_replays_image_tool_outputs_with_detail() {
|
||||
RolloutLine {
|
||||
timestamp: "2024-01-01T00:00:00.000Z".to_string(),
|
||||
ordinal: None,
|
||||
item: RolloutItem::SessionMeta(SessionMetaLine {
|
||||
item: RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: SessionMeta {
|
||||
session_id: thread_id.into(),
|
||||
id: thread_id,
|
||||
@@ -1344,7 +1344,7 @@ async fn resume_replays_image_tool_outputs_with_detail() {
|
||||
..Default::default()
|
||||
},
|
||||
git: None,
|
||||
}),
|
||||
})),
|
||||
},
|
||||
RolloutLine {
|
||||
timestamp: "2024-01-01T00:00:01.000Z".to_string(),
|
||||
|
||||
@@ -324,7 +324,7 @@ async fn assert_copied_fork_persists_inherited_history(history_mode: ThreadHisto
|
||||
let source_meta = codex_rollout::read_session_meta_line(source_path.as_path())
|
||||
.await
|
||||
.expect("read source session metadata");
|
||||
let mut supplied_history = vec![RolloutItem::SessionMeta(source_meta)];
|
||||
let mut supplied_history = vec![RolloutItem::SessionMeta(Box::new(source_meta))];
|
||||
supplied_history.extend(source_items.iter().cloned());
|
||||
let NewThread {
|
||||
thread: forked_thread,
|
||||
|
||||
@@ -179,12 +179,14 @@ async fn guardian_revalidates_owning_session_before_allow(
|
||||
test.codex = super::guardian_checkpoint_migration::resume(
|
||||
&test,
|
||||
&test.codex,
|
||||
vec![RolloutItem::Compacted(serde_json::from_value(json!({
|
||||
"message": "old checkpoint",
|
||||
"replacement_history": [{
|
||||
"type": "compaction", "id": "old", "encrypted_content": "unknown producer"
|
||||
}]
|
||||
}))?)],
|
||||
vec![RolloutItem::Compacted(Box::new(serde_json::from_value(
|
||||
json!({
|
||||
"message": "old checkpoint",
|
||||
"replacement_history": [{
|
||||
"type": "compaction", "id": "old", "encrypted_content": "unknown producer"
|
||||
}]
|
||||
}),
|
||||
)?))],
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
@@ -156,12 +156,14 @@ async fn guardian_refreshes_subagent_authorization(change: Change) -> Result<()>
|
||||
test.codex = super::guardian_checkpoint_migration::resume(
|
||||
&test,
|
||||
&test.codex,
|
||||
vec![RolloutItem::Compacted(serde_json::from_value(json!({
|
||||
"message": "old checkpoint",
|
||||
"replacement_history": [{
|
||||
"type": "compaction", "id": "old", "encrypted_content": "unknown producer"
|
||||
}]
|
||||
}))?)],
|
||||
vec![RolloutItem::Compacted(Box::new(serde_json::from_value(
|
||||
json!({
|
||||
"message": "old checkpoint",
|
||||
"replacement_history": [{
|
||||
"type": "compaction", "id": "old", "encrypted_content": "unknown producer"
|
||||
}]
|
||||
}),
|
||||
)?))],
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
@@ -274,7 +274,7 @@ pub(crate) async fn handoff_scenario() -> Result<Vec<ResponsesRequest>> {
|
||||
"message":"Root checkpoint.", "replacement_history":[], "retained_context":history.retained_context(),
|
||||
}))?;
|
||||
test.codex
|
||||
.append_rollout_items(&[RolloutItem::Compacted(checkpoint)])
|
||||
.append_rollout_items(&[RolloutItem::Compacted(Box::new(checkpoint))])
|
||||
.await?;
|
||||
test.codex.flush_rollout().await?;
|
||||
let rollout = test
|
||||
|
||||
@@ -801,7 +801,7 @@ async fn run_guardian_subagent_review(
|
||||
test.codex = super::guardian_checkpoint_migration::resume(
|
||||
&test,
|
||||
&test.codex,
|
||||
vec![RolloutItem::Compacted(checkpoint)],
|
||||
vec![RolloutItem::Compacted(Box::new(checkpoint))],
|
||||
)
|
||||
.await?;
|
||||
assert_eq!(
|
||||
@@ -1678,7 +1678,7 @@ async fn run_guardian_subagent_review(
|
||||
));
|
||||
}
|
||||
checkpoint.replacement_history = Some(replacement_history);
|
||||
root.append_rollout_items(&[RolloutItem::Compacted(checkpoint)])
|
||||
root.append_rollout_items(&[RolloutItem::Compacted(Box::new(checkpoint))])
|
||||
.await?;
|
||||
root.shutdown_and_wait().await?;
|
||||
test.thread_manager.remove_thread(&root_thread_id).await;
|
||||
|
||||
@@ -111,7 +111,7 @@ async fn recovery_without_a_snapshot_keeps_each_threads_originator() -> Result<(
|
||||
let thread = fixture
|
||||
.thread_manager
|
||||
.start_thread(StartThreadOptions {
|
||||
initial_history: InitialHistory::Forked(vec![RolloutItem::SessionMeta(
|
||||
initial_history: InitialHistory::Forked(vec![RolloutItem::SessionMeta(Box::new(
|
||||
SessionMetaLine {
|
||||
meta: SessionMeta {
|
||||
originator: originator.into(),
|
||||
@@ -119,7 +119,7 @@ async fn recovery_without_a_snapshot_keeps_each_threads_originator() -> Result<(
|
||||
},
|
||||
git: None,
|
||||
},
|
||||
)]),
|
||||
))]),
|
||||
environments: Some(
|
||||
fixture
|
||||
.codex
|
||||
|
||||
@@ -48,13 +48,13 @@ async fn selected_capability_roots_survive_environment_reselection(
|
||||
}];
|
||||
let mut thread_extension_init = ExtensionDataInit::new();
|
||||
let initial_history = if from_history {
|
||||
InitialHistory::Forked(vec![RolloutItem::SessionMeta(SessionMetaLine {
|
||||
InitialHistory::Forked(vec![RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: SessionMeta {
|
||||
selected_capability_roots: roots.clone(),
|
||||
..SessionMeta::default()
|
||||
},
|
||||
git: None,
|
||||
})])
|
||||
}))])
|
||||
} else {
|
||||
thread_extension_init.insert(roots.clone());
|
||||
InitialHistory::New
|
||||
|
||||
@@ -592,7 +592,7 @@ async fn backfill_scans_existing_rollouts() -> Result<()> {
|
||||
RolloutLine {
|
||||
timestamp: "2026-01-27T12:00:00Z".to_string(),
|
||||
ordinal: None,
|
||||
item: RolloutItem::SessionMeta(session_meta_line),
|
||||
item: RolloutItem::SessionMeta(Box::new(session_meta_line)),
|
||||
},
|
||||
RolloutLine {
|
||||
timestamp: "2026-01-27T12:00:01Z".to_string(),
|
||||
|
||||
@@ -213,13 +213,13 @@ impl Borrow<ResponseItem> for ResponseItemEnvelope {
|
||||
/// Persisted rollout item used by core history and rollout storage.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum RolloutItem {
|
||||
SessionMeta(SessionMetaLine),
|
||||
SessionMeta(Box<SessionMetaLine>),
|
||||
ResponseItem(ResponseItemEnvelope),
|
||||
InterAgentCommunication(InterAgentCommunication),
|
||||
InterAgentCommunicationMetadata {
|
||||
trigger_turn: bool,
|
||||
},
|
||||
Compacted(CompactedItem),
|
||||
Compacted(Box<CompactedItem>),
|
||||
TurnContext(TurnContextItem),
|
||||
TokenUsageRecord(TokenUsageRecord),
|
||||
WorldState(WorldStateItem),
|
||||
|
||||
@@ -166,7 +166,9 @@ impl<'a> From<&'a RolloutItem> for RolloutItemWire<'a> {
|
||||
impl From<RolloutItemWire<'_>> for RolloutItem {
|
||||
fn from(item: RolloutItemWire<'_>) -> Self {
|
||||
match item {
|
||||
RolloutItemWire::SessionMeta { payload } => Self::SessionMeta(payload.into_owned()),
|
||||
RolloutItemWire::SessionMeta { payload } => {
|
||||
Self::SessionMeta(Box::new(payload.into_owned()))
|
||||
}
|
||||
RolloutItemWire::ResponseItem { payload, metadata } => {
|
||||
if let (
|
||||
ResponseItem::Message {
|
||||
@@ -218,7 +220,9 @@ impl From<RolloutItemWire<'_>> for RolloutItem {
|
||||
trigger_turn: payload.trigger_turn,
|
||||
}
|
||||
}
|
||||
RolloutItemWire::Compacted { payload } => Self::Compacted(payload.into_owned()),
|
||||
RolloutItemWire::Compacted { payload } => {
|
||||
Self::Compacted(Box::new(payload.into_owned()))
|
||||
}
|
||||
RolloutItemWire::TurnContext { payload } => Self::TurnContext(payload.into_owned()),
|
||||
RolloutItemWire::TokenUsageRecord { payload } => {
|
||||
Self::TokenUsageRecord(payload.into_owned())
|
||||
|
||||
@@ -682,7 +682,7 @@ fn compacted_metadata_remains_compatible_with_legacy_response_item_readers() ->
|
||||
])?)?,
|
||||
crate::GuardianHistoryCheckpoint(vec![response_item.clone().into()]),
|
||||
);
|
||||
let compacted_line = serde_json::to_value(RolloutItem::Compacted(CompactedItem {
|
||||
let compacted_line = serde_json::to_value(RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: "summary".to_string(),
|
||||
replacement_history: Some(vec![envelope]),
|
||||
retained_context: None,
|
||||
@@ -700,7 +700,7 @@ fn compacted_metadata_remains_compatible_with_legacy_response_item_readers() ->
|
||||
turn_attribution: None,
|
||||
previous_turn_settings: None,
|
||||
}),
|
||||
}))?;
|
||||
})))?;
|
||||
|
||||
let restored: RolloutItem = serde_json::from_value(compacted_line.clone())?;
|
||||
let RolloutItem::Compacted(restored) = restored else {
|
||||
@@ -959,7 +959,7 @@ fn compacted_item_migrates_legacy_numeric_window_id() -> Result<()> {
|
||||
#[test]
|
||||
fn copied_history_uses_persisted_history_mode() -> Result<()> {
|
||||
let thread_id = ThreadId::from_string("00000000-0000-0000-0000-000000000001")?;
|
||||
let session_meta = RolloutItem::SessionMeta(SessionMetaLine {
|
||||
let session_meta = RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: SessionMeta {
|
||||
session_id: thread_id.into(),
|
||||
id: thread_id,
|
||||
@@ -967,7 +967,7 @@ fn copied_history_uses_persisted_history_mode() -> Result<()> {
|
||||
..SessionMeta::default()
|
||||
},
|
||||
git: None,
|
||||
});
|
||||
}));
|
||||
let history = InitialHistory::Resumed(ResumedHistory {
|
||||
history_revision: None,
|
||||
conversation_id: thread_id,
|
||||
@@ -1025,8 +1025,8 @@ fn multi_agent_version_uses_newest_present_session_meta_value() -> Result<()> {
|
||||
assert_eq!(
|
||||
multi_agent_version_from_items(
|
||||
&[
|
||||
RolloutItem::SessionMeta(older_meta),
|
||||
RolloutItem::SessionMeta(newer_meta_without_version),
|
||||
RolloutItem::SessionMeta(Box::new(older_meta)),
|
||||
RolloutItem::SessionMeta(Box::new(newer_meta_without_version)),
|
||||
],
|
||||
Some(thread_id),
|
||||
),
|
||||
@@ -1045,7 +1045,8 @@ fn multi_agent_version_uses_compaction_metadata_without_turn_context() -> Result
|
||||
}))?;
|
||||
|
||||
assert_eq!(
|
||||
InitialHistory::Forked(vec![RolloutItem::Compacted(compacted)]).get_multi_agent_version(),
|
||||
InitialHistory::Forked(vec![RolloutItem::Compacted(Box::new(compacted))])
|
||||
.get_multi_agent_version(),
|
||||
Some(MultiAgentVersion::V2)
|
||||
);
|
||||
Ok(())
|
||||
|
||||
@@ -1155,7 +1155,7 @@ fn write_rollout(path: &std::path::Path, thread_id: ThreadId, message: &str) ->
|
||||
RolloutLine {
|
||||
timestamp: "2025-01-03T12:00:00Z".to_string(),
|
||||
ordinal: None,
|
||||
item: RolloutItem::SessionMeta(session_meta_line),
|
||||
item: RolloutItem::SessionMeta(Box::new(session_meta_line)),
|
||||
},
|
||||
RolloutLine {
|
||||
timestamp: "2025-01-03T12:00:01Z".to_string(),
|
||||
|
||||
@@ -1204,7 +1204,7 @@ pub async fn read_session_meta_line(path: &Path) -> io::Result<SessionMetaLine>
|
||||
continue;
|
||||
};
|
||||
match rollout_line.item {
|
||||
RolloutItem::SessionMeta(session_meta_line) => return Ok(session_meta_line),
|
||||
RolloutItem::SessionMeta(session_meta_line) => return Ok(*session_meta_line),
|
||||
RolloutItem::ResponseItem(_) | RolloutItem::InterAgentCommunication(_) => {
|
||||
return Err(io::Error::other(MetadataReadError {
|
||||
reason: "response_before_metadata",
|
||||
|
||||
@@ -152,7 +152,7 @@ async fn extract_metadata_from_rollout_uses_session_meta() {
|
||||
let rollout_line = RolloutLine {
|
||||
timestamp: "2026-01-27T12:34:56Z".to_string(),
|
||||
ordinal: Some(0),
|
||||
item: RolloutItem::SessionMeta(session_meta_line.clone()),
|
||||
item: RolloutItem::SessionMeta(Box::new(session_meta_line.clone())),
|
||||
};
|
||||
let json = serde_json::to_string(&rollout_line).expect("rollout json");
|
||||
let mut file = File::create(&path).expect("create rollout");
|
||||
@@ -164,7 +164,7 @@ async fn extract_metadata_from_rollout_uses_session_meta() {
|
||||
let parent_line = RolloutLine {
|
||||
timestamp: rollout_line.timestamp.clone(),
|
||||
ordinal: Some(1),
|
||||
item: RolloutItem::SessionMeta(parent),
|
||||
item: RolloutItem::SessionMeta(Box::new(parent)),
|
||||
};
|
||||
writeln!(
|
||||
file,
|
||||
@@ -206,7 +206,7 @@ async fn extract_metadata_from_rollout_rejects_unknown_history_mode() {
|
||||
let mut rollout_line = serde_json::to_value(RolloutLine {
|
||||
timestamp: "2026-01-27T12:34:56Z".to_string(),
|
||||
ordinal: None,
|
||||
item: RolloutItem::SessionMeta(SessionMetaLine {
|
||||
item: RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: SessionMeta {
|
||||
session_id: id.into(),
|
||||
id,
|
||||
@@ -217,7 +217,7 @@ async fn extract_metadata_from_rollout_rejects_unknown_history_mode() {
|
||||
..SessionMeta::default()
|
||||
},
|
||||
git: None,
|
||||
}),
|
||||
})),
|
||||
})
|
||||
.expect("serialize rollout line");
|
||||
rollout_line["payload"]["history_mode"] = serde_json::json!("future");
|
||||
@@ -278,18 +278,18 @@ async fn extract_metadata_from_rollout_returns_latest_memory_mode() {
|
||||
RolloutLine {
|
||||
timestamp: "2026-01-27T12:34:56Z".to_string(),
|
||||
ordinal: None,
|
||||
item: RolloutItem::SessionMeta(SessionMetaLine {
|
||||
item: RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: session_meta,
|
||||
git: None,
|
||||
}),
|
||||
})),
|
||||
},
|
||||
RolloutLine {
|
||||
timestamp: "2026-01-27T12:35:00Z".to_string(),
|
||||
ordinal: None,
|
||||
item: RolloutItem::SessionMeta(SessionMetaLine {
|
||||
item: RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: polluted_meta,
|
||||
git: None,
|
||||
}),
|
||||
})),
|
||||
},
|
||||
];
|
||||
let mut file = File::create(&path).expect("create rollout");
|
||||
@@ -316,7 +316,7 @@ fn builder_from_items_falls_back_to_filename() {
|
||||
let path = dir
|
||||
.path()
|
||||
.join(format!("rollout-2026-01-27T12-34-56-{uuid}.jsonl"));
|
||||
let items = vec![RolloutItem::Compacted(CompactedItem {
|
||||
let items = vec![RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: "noop".to_string(),
|
||||
replacement_history: None,
|
||||
retained_context: None,
|
||||
@@ -329,7 +329,7 @@ fn builder_from_items_falls_back_to_filename() {
|
||||
compaction_response_id: None,
|
||||
latest_token_usage_record: None,
|
||||
resume_metadata: None,
|
||||
})];
|
||||
}))];
|
||||
|
||||
let builder = builder_from_items(items.as_slice(), path.as_path()).expect("builder");
|
||||
let naive = NaiveDateTime::parse_from_str("2026-01-27T12-34-56", "%Y-%m-%dT%H-%M-%S")
|
||||
@@ -625,7 +625,7 @@ fn write_rollout_in_sessions_with_cwd(
|
||||
let rollout_line = RolloutLine {
|
||||
timestamp: event_ts.to_string(),
|
||||
ordinal: None,
|
||||
item: RolloutItem::SessionMeta(session_meta_line),
|
||||
item: RolloutItem::SessionMeta(Box::new(session_meta_line)),
|
||||
};
|
||||
let json = serde_json::to_string(&rollout_line).expect("serialize rollout");
|
||||
let mut file = File::create(&path).expect("create rollout");
|
||||
|
||||
@@ -2039,7 +2039,7 @@ async fn write_session_meta(
|
||||
git: git_info,
|
||||
};
|
||||
|
||||
let rollout_item = RolloutItem::SessionMeta(session_meta_line);
|
||||
let rollout_item = RolloutItem::SessionMeta(Box::new(session_meta_line));
|
||||
if let Some(writer) = writer.as_mut() {
|
||||
let ordinal = ordinal_state.current()?;
|
||||
writer.write_rollout_item(&rollout_item, ordinal).await?;
|
||||
|
||||
@@ -48,7 +48,7 @@ fn test_config(codex_home: &Path) -> RolloutConfig {
|
||||
}
|
||||
|
||||
fn paginated_session_meta_item(thread_id: ThreadId, cwd: &Path) -> RolloutItem {
|
||||
RolloutItem::SessionMeta(SessionMetaLine {
|
||||
RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: SessionMeta {
|
||||
session_id: thread_id.into(),
|
||||
id: thread_id,
|
||||
@@ -61,7 +61,7 @@ fn paginated_session_meta_item(thread_id: ThreadId, cwd: &Path) -> RolloutItem {
|
||||
..SessionMeta::default()
|
||||
},
|
||||
git: None,
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
fn agent_message_item(message: &str) -> RolloutItem {
|
||||
@@ -248,7 +248,7 @@ async fn state_db_init_backfills_before_returning() -> anyhow::Result<()> {
|
||||
RolloutLine {
|
||||
timestamp: "2026-01-27T12:34:56Z".to_string(),
|
||||
ordinal: None,
|
||||
item: RolloutItem::SessionMeta(session_meta_line),
|
||||
item: RolloutItem::SessionMeta(Box::new(session_meta_line)),
|
||||
},
|
||||
RolloutLine {
|
||||
timestamp: "2026-01-27T12:34:57Z".to_string(),
|
||||
|
||||
@@ -33,7 +33,7 @@ fn write_rollout_with_source_and_provider(
|
||||
let line = RolloutLine {
|
||||
timestamp: timestamp.clone(),
|
||||
ordinal: None,
|
||||
item: RolloutItem::SessionMeta(SessionMetaLine {
|
||||
item: RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: SessionMeta {
|
||||
creator_user_id: None,
|
||||
creator_account_id: None,
|
||||
@@ -64,7 +64,7 @@ fn write_rollout_with_source_and_provider(
|
||||
context_window: None,
|
||||
},
|
||||
git: None,
|
||||
}),
|
||||
})),
|
||||
};
|
||||
let body = serde_json::to_string(&line).map_err(std::io::Error::other)?;
|
||||
std::fs::write(path, format!("{body}\n"))
|
||||
|
||||
@@ -323,7 +323,7 @@ fn write_rollout_with_user_message(
|
||||
RolloutLine {
|
||||
timestamp: "2026-06-01T14:26:25Z".to_string(),
|
||||
ordinal: None,
|
||||
item: RolloutItem::SessionMeta(SessionMetaLine {
|
||||
item: RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: SessionMeta {
|
||||
creator_user_id: None,
|
||||
creator_account_id: None,
|
||||
@@ -354,7 +354,7 @@ fn write_rollout_with_user_message(
|
||||
context_window: None,
|
||||
},
|
||||
git: None,
|
||||
}),
|
||||
})),
|
||||
},
|
||||
RolloutLine {
|
||||
timestamp: "2026-06-01T14:26:26Z".to_string(),
|
||||
|
||||
@@ -1591,7 +1591,7 @@ async fn test_updated_at_uses_file_mtime() -> Result<()> {
|
||||
let meta_line = RolloutLine {
|
||||
timestamp: ts.to_string(),
|
||||
ordinal: None,
|
||||
item: RolloutItem::SessionMeta(SessionMetaLine {
|
||||
item: RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: SessionMeta {
|
||||
creator_user_id: None,
|
||||
creator_account_id: None,
|
||||
@@ -1622,7 +1622,7 @@ async fn test_updated_at_uses_file_mtime() -> Result<()> {
|
||||
context_window: None,
|
||||
},
|
||||
git: None,
|
||||
}),
|
||||
})),
|
||||
};
|
||||
writeln!(file, "{}", serde_json::to_string(&meta_line)?)?;
|
||||
|
||||
|
||||
@@ -365,7 +365,7 @@ mod tests {
|
||||
let mut metadata =
|
||||
ThreadMetadataBuilder::new(thread_id, PathBuf::new(), Utc::now(), source.clone())
|
||||
.build("test-provider");
|
||||
let session_meta = RolloutItem::SessionMeta(SessionMetaLine {
|
||||
let session_meta = RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: SessionMeta {
|
||||
session_id: thread_id.into(),
|
||||
id: thread_id,
|
||||
@@ -373,7 +373,7 @@ mod tests {
|
||||
..Default::default()
|
||||
},
|
||||
git: None,
|
||||
});
|
||||
}));
|
||||
apply_rollout_item(&mut metadata, &session_meta, "test-provider");
|
||||
let mut expected = metadata.clone();
|
||||
expected.title = super::GUARDIAN_THREAD_TITLE.to_string();
|
||||
@@ -525,7 +525,7 @@ mod tests {
|
||||
|
||||
apply_rollout_item(
|
||||
&mut metadata,
|
||||
&RolloutItem::SessionMeta(SessionMetaLine {
|
||||
&RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: SessionMeta {
|
||||
creator_user_id: None,
|
||||
creator_account_id: None,
|
||||
@@ -558,7 +558,7 @@ mod tests {
|
||||
context_window: None,
|
||||
},
|
||||
git: None,
|
||||
}),
|
||||
})),
|
||||
"test-provider",
|
||||
);
|
||||
apply_rollout_item(
|
||||
@@ -775,7 +775,7 @@ mod tests {
|
||||
|
||||
apply_rollout_item(
|
||||
&mut metadata,
|
||||
&RolloutItem::SessionMeta(SessionMetaLine {
|
||||
&RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: SessionMeta {
|
||||
creator_user_id: None,
|
||||
creator_account_id: None,
|
||||
@@ -806,7 +806,7 @@ mod tests {
|
||||
context_window: None,
|
||||
},
|
||||
git: None,
|
||||
}),
|
||||
})),
|
||||
"test-provider",
|
||||
);
|
||||
|
||||
|
||||
@@ -2806,7 +2806,7 @@ mod tests {
|
||||
metadata.created_at,
|
||||
SessionSource::Cli,
|
||||
);
|
||||
let items = vec![RolloutItem::SessionMeta(SessionMetaLine {
|
||||
let items = vec![RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: SessionMeta {
|
||||
creator_user_id: None,
|
||||
creator_account_id: None,
|
||||
@@ -2837,7 +2837,7 @@ mod tests {
|
||||
context_window: None,
|
||||
},
|
||||
git: None,
|
||||
})];
|
||||
}))];
|
||||
|
||||
runtime
|
||||
.apply_rollout_items(
|
||||
@@ -2880,7 +2880,7 @@ mod tests {
|
||||
metadata.created_at,
|
||||
SessionSource::Cli,
|
||||
);
|
||||
let items = vec![RolloutItem::SessionMeta(SessionMetaLine {
|
||||
let items = vec![RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: SessionMeta {
|
||||
creator_user_id: None,
|
||||
creator_account_id: None,
|
||||
@@ -2918,7 +2918,7 @@ mod tests {
|
||||
.expect("valid git remote URL"),
|
||||
),
|
||||
}),
|
||||
})];
|
||||
}))];
|
||||
|
||||
runtime
|
||||
.apply_rollout_items(
|
||||
|
||||
@@ -617,10 +617,10 @@ impl InMemoryThreadStore {
|
||||
.histories
|
||||
.entry(params.thread_id)
|
||||
.or_default()
|
||||
.push(RolloutItem::SessionMeta(SessionMetaLine {
|
||||
.push(RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: session_meta,
|
||||
git: None,
|
||||
}));
|
||||
})));
|
||||
state.created_threads.insert(params.thread_id, params);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -185,7 +185,7 @@ async fn metadata_updates_share_ownership_and_resume_compressed_rollouts() -> Te
|
||||
expected.git = None;
|
||||
assert_eq!(
|
||||
json!(items.last()),
|
||||
json!(Some(RolloutItem::SessionMeta(expected.clone())))
|
||||
json!(Some(RolloutItem::SessionMeta(Box::new(expected.clone()))))
|
||||
);
|
||||
|
||||
age(&path)?;
|
||||
@@ -214,7 +214,7 @@ async fn metadata_updates_share_ownership_and_resume_compressed_rollouts() -> Te
|
||||
let (items, _, _) = RolloutRecorder::load_rollout_items(&path).await?;
|
||||
assert_eq!(
|
||||
json!(items.last()),
|
||||
json!(Some(RolloutItem::SessionMeta(expected)))
|
||||
json!(Some(RolloutItem::SessionMeta(Box::new(expected))))
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ pub(super) async fn load_for_fork(
|
||||
let lineage = lineage.truncate_at(history_base).await?;
|
||||
scan_model_context_from_lineage(lineage, session_meta).await
|
||||
}
|
||||
None => Ok(vec![RolloutItem::SessionMeta(session_meta)]),
|
||||
None => Ok(vec![RolloutItem::SessionMeta(Box::new(session_meta))]),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,6 +212,6 @@ fn scan_model_context_from_lineage_blocking(
|
||||
}
|
||||
|
||||
let mut items = scan.finish();
|
||||
items.insert(0, RolloutItem::SessionMeta(session_meta));
|
||||
items.insert(0, RolloutItem::SessionMeta(Box::new(session_meta)));
|
||||
Ok(items)
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ async fn stops_at_newest_usable_compaction_and_keeps_companions() {
|
||||
assert_eq!(
|
||||
serde_json::to_value(context.items).expect("serialize context"),
|
||||
serde_json::to_value(vec![
|
||||
RolloutItem::SessionMeta(session_meta),
|
||||
RolloutItem::SessionMeta(Box::new(session_meta)),
|
||||
compacted("latest compaction", Some(Vec::new())),
|
||||
world_state,
|
||||
turn_context,
|
||||
@@ -129,7 +129,7 @@ async fn loads_recent_context_after_many_empty_wake_turns() {
|
||||
})
|
||||
.await
|
||||
.expect("load model context");
|
||||
expected_suffix.insert(0, RolloutItem::SessionMeta(session_meta));
|
||||
expected_suffix.insert(0, RolloutItem::SessionMeta(Box::new(session_meta)));
|
||||
|
||||
assert_eq!(
|
||||
serde_json::to_value(context.items).expect("serialize context"),
|
||||
@@ -165,7 +165,7 @@ async fn fork_context_excludes_items_after_frozen_cutoff() {
|
||||
.expect("load frozen fork context");
|
||||
|
||||
let expected = vec![
|
||||
RolloutItem::SessionMeta(session_meta),
|
||||
RolloutItem::SessionMeta(Box::new(session_meta)),
|
||||
turn_started("frozen-turn"),
|
||||
user_message("frozen message"),
|
||||
];
|
||||
@@ -201,7 +201,7 @@ async fn fork_version_stops_before_older_segments_once_resolved() {
|
||||
let head = RolloutLine {
|
||||
timestamp: "2025-01-03T13:02:01Z".to_string(),
|
||||
ordinal: Some(0),
|
||||
item: RolloutItem::SessionMeta(source_meta.clone()),
|
||||
item: RolloutItem::SessionMeta(Box::new(source_meta.clone())),
|
||||
};
|
||||
std::fs::write(
|
||||
&child_path,
|
||||
@@ -243,7 +243,7 @@ async fn fork_version_stops_before_older_segments_once_resolved() {
|
||||
source_meta.meta.multi_agent_version = stored_version.or(Some(MultiAgentVersion::V2));
|
||||
assert_eq!(
|
||||
serde_json::to_value(context).expect("serialize fork context"),
|
||||
serde_json::to_value(vec![RolloutItem::SessionMeta(source_meta)])
|
||||
serde_json::to_value(vec![RolloutItem::SessionMeta(Box::new(source_meta))])
|
||||
.expect("serialize expected context")
|
||||
);
|
||||
}
|
||||
@@ -296,7 +296,7 @@ async fn fork_version_respects_inherited_segment_cutoffs() {
|
||||
source_meta.meta.multi_agent_version = Some(MultiAgentVersion::V2);
|
||||
assert_eq!(
|
||||
serde_json::to_value(context).expect("serialize fork context"),
|
||||
serde_json::to_value(vec![RolloutItem::SessionMeta(source_meta)])
|
||||
serde_json::to_value(vec![RolloutItem::SessionMeta(Box::new(source_meta))])
|
||||
.expect("serialize expected context")
|
||||
);
|
||||
}
|
||||
@@ -444,7 +444,7 @@ async fn replays_nested_archived_lineage_from_frozen_prefix() {
|
||||
.await
|
||||
.expect("read child metadata");
|
||||
let expected = vec![
|
||||
RolloutItem::SessionMeta(child_meta),
|
||||
RolloutItem::SessionMeta(Box::new(child_meta)),
|
||||
compacted("root checkpoint", Some(Vec::new())),
|
||||
turn_started("middle-turn"),
|
||||
user_message("middle inherited"),
|
||||
@@ -703,7 +703,7 @@ fn turn_context(root: &Path, turn_id: &str) -> RolloutItem {
|
||||
}
|
||||
|
||||
fn compacted(message: &str, replacement_history: Option<Vec<ResponseItem>>) -> RolloutItem {
|
||||
RolloutItem::Compacted(CompactedItem {
|
||||
RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: message.to_string(),
|
||||
replacement_history: replacement_history
|
||||
.map(|items| items.into_iter().map(Into::into).collect()),
|
||||
@@ -717,5 +717,5 @@ fn compacted(message: &str, replacement_history: Option<Vec<ResponseItem>>) -> R
|
||||
compaction_response_id: None,
|
||||
latest_token_usage_record: None,
|
||||
resume_metadata: None,
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ async fn empty_archived_reads_without_sqlite_preserve_source_and_file_time()
|
||||
let line = RolloutLine {
|
||||
timestamp: timestamp.to_string(),
|
||||
ordinal: None,
|
||||
item: RolloutItem::SessionMeta(SessionMetaLine {
|
||||
item: RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: SessionMeta {
|
||||
id: thread_id,
|
||||
session_id: thread_id.into(),
|
||||
@@ -43,7 +43,7 @@ async fn empty_archived_reads_without_sqlite_preserve_source_and_file_time()
|
||||
..SessionMeta::default()
|
||||
},
|
||||
git: None,
|
||||
}),
|
||||
})),
|
||||
};
|
||||
fs::write(&path, format!("{}\n", serde_json::to_string(&line)?))?;
|
||||
fs::OpenOptions::new()
|
||||
|
||||
@@ -277,7 +277,7 @@ fn write_rollout_under(
|
||||
let initial_ordinal = history_base.map_or(0, |base| base.end_ordinal_exclusive);
|
||||
let mut lines = vec![rollout_line(
|
||||
initial_ordinal,
|
||||
RolloutItem::SessionMeta(SessionMetaLine {
|
||||
RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: SessionMeta {
|
||||
session_id: thread_id.into(),
|
||||
id: thread_id,
|
||||
@@ -286,7 +286,7 @@ fn write_rollout_under(
|
||||
..SessionMeta::default()
|
||||
},
|
||||
git: None,
|
||||
}),
|
||||
})),
|
||||
)];
|
||||
for offset in 1..next_ordinal {
|
||||
let ordinal = initial_ordinal
|
||||
|
||||
@@ -86,7 +86,7 @@ impl RollbackPlan {
|
||||
// A rolled-back turn can still own the empty checkpoint that keeps cold resume from
|
||||
// replaying older history.
|
||||
if let Some(compacted) = self.compacted_items.get(&record_index) {
|
||||
line.item = RolloutItem::Compacted(compacted.clone());
|
||||
line.item = RolloutItem::Compacted(Box::new(compacted.clone()));
|
||||
return Ok(Some(line));
|
||||
}
|
||||
if boundary.is_some_and(|boundary| !self.boundary_alive[boundary]) {
|
||||
@@ -262,7 +262,7 @@ impl RollbackPlanner {
|
||||
record_index: index,
|
||||
boundary_depth: self.boundary_stack.len(),
|
||||
owner,
|
||||
item: item.clone(),
|
||||
item: item.as_ref().clone(),
|
||||
});
|
||||
}
|
||||
RolloutItem::TurnContext(_) => {
|
||||
|
||||
@@ -47,10 +47,10 @@ fn write_rollout(home: &Path, thread_id: ThreadId, history_mode: ThreadHistoryMo
|
||||
..SessionMeta::default()
|
||||
};
|
||||
for (ordinal, item) in [
|
||||
RolloutItem::SessionMeta(SessionMetaLine {
|
||||
RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: metadata,
|
||||
git: None,
|
||||
}),
|
||||
})),
|
||||
RolloutItem::EventMsg(EventMsg::UserMessage(UserMessageEvent {
|
||||
message: "question".to_string(),
|
||||
..UserMessageEvent::default()
|
||||
|
||||
@@ -119,10 +119,10 @@ fn write_rollout_with_fork(
|
||||
model_provider: Some("test-provider".to_string()),
|
||||
..SessionMeta::default()
|
||||
};
|
||||
let items = std::iter::once(RolloutItem::SessionMeta(SessionMetaLine {
|
||||
let items = std::iter::once(RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: metadata,
|
||||
git: None,
|
||||
}))
|
||||
})))
|
||||
.chain(items);
|
||||
for item in items {
|
||||
let line = RolloutLine {
|
||||
@@ -245,7 +245,7 @@ fn started(turn_id: &str) -> RolloutItem {
|
||||
}
|
||||
|
||||
fn compacted(replacement_history: Vec<ResponseItem>) -> RolloutItem {
|
||||
RolloutItem::Compacted(CompactedItem {
|
||||
RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: "checkpoint".to_string(),
|
||||
replacement_history: Some(replacement_history.into_iter().map(Into::into).collect()),
|
||||
retained_context: None,
|
||||
@@ -258,7 +258,7 @@ fn compacted(replacement_history: Vec<ResponseItem>) -> RolloutItem {
|
||||
compaction_response_id: None,
|
||||
latest_token_usage_record: None,
|
||||
resume_metadata: None,
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
fn completed(turn_id: &str) -> RolloutItem {
|
||||
@@ -2077,10 +2077,10 @@ async fn migration_drops_copied_user_fork_metadata_without_creating_a_history_ba
|
||||
SessionSource::Cli,
|
||||
Some(parent_id),
|
||||
vec![
|
||||
RolloutItem::SessionMeta(SessionMetaLine {
|
||||
RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: copied_metadata,
|
||||
git: None,
|
||||
}),
|
||||
})),
|
||||
copied_response,
|
||||
user_message("child question"),
|
||||
agent_message("child answer"),
|
||||
@@ -2142,7 +2142,7 @@ async fn migration_compacts_subagent_prefix_and_does_not_project_it() {
|
||||
thread_id,
|
||||
SessionSource::SubAgent(SubAgentSource::Other("test".to_string())),
|
||||
vec![
|
||||
RolloutItem::Compacted(CompactedItem {
|
||||
RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: "superseded checkpoint".repeat(1024),
|
||||
replacement_history: Some(Vec::new()),
|
||||
retained_context: None,
|
||||
@@ -2155,8 +2155,8 @@ async fn migration_compacts_subagent_prefix_and_does_not_project_it() {
|
||||
compaction_response_id: None,
|
||||
latest_token_usage_record: None,
|
||||
resume_metadata: None,
|
||||
}),
|
||||
RolloutItem::Compacted(CompactedItem {
|
||||
})),
|
||||
RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: "latest checkpoint".to_string(),
|
||||
replacement_history: Some(vec![
|
||||
ResponseItem::Message {
|
||||
@@ -2182,7 +2182,7 @@ async fn migration_compacts_subagent_prefix_and_does_not_project_it() {
|
||||
compaction_response_id: None,
|
||||
latest_token_usage_record: None,
|
||||
resume_metadata: None,
|
||||
}),
|
||||
})),
|
||||
started("child-turn"),
|
||||
RolloutItem::TurnContext(TurnContextItem {
|
||||
turn_id: Some("child-turn".to_string()),
|
||||
|
||||
@@ -1569,7 +1569,7 @@ fn write_rollout_with_end(
|
||||
let mut lines = vec![RolloutLine {
|
||||
timestamp: "2026-07-16T00:00:00.000Z".to_string(),
|
||||
ordinal: Some(initial_ordinal),
|
||||
item: RolloutItem::SessionMeta(SessionMetaLine {
|
||||
item: RolloutItem::SessionMeta(Box::new(SessionMetaLine {
|
||||
meta: SessionMeta {
|
||||
session_id: thread_id.into(),
|
||||
id: thread_id,
|
||||
@@ -1578,7 +1578,7 @@ fn write_rollout_with_end(
|
||||
..SessionMeta::default()
|
||||
},
|
||||
git: None,
|
||||
}),
|
||||
})),
|
||||
}];
|
||||
for offset in 1..next_ordinal {
|
||||
let ordinal = initial_ordinal
|
||||
|
||||
@@ -921,7 +921,7 @@ async fn update_rollout_metadata(
|
||||
};
|
||||
patch(&mut metadata);
|
||||
recorder
|
||||
.record_canonical_items(&[RolloutItem::SessionMeta(metadata)])
|
||||
.record_canonical_items(&[RolloutItem::SessionMeta(Box::new(metadata))])
|
||||
.await
|
||||
.map_err(io_error)?;
|
||||
recorder.flush().await.map_err(io_error)?;
|
||||
@@ -1314,7 +1314,7 @@ mod tests {
|
||||
let (mut expected, _, _) = RolloutRecorder::load_rollout_items(&path).await?;
|
||||
let mut metadata = read_session_meta_line(&path).await?;
|
||||
metadata.meta.memory_mode = Some("disabled".into());
|
||||
expected.push(RolloutItem::SessionMeta(metadata));
|
||||
expected.push(RolloutItem::SessionMeta(Box::new(metadata)));
|
||||
|
||||
let mut shutdown = Box::pin(store.shutdown_thread(thread_id));
|
||||
update_rollout_metadata(&store, thread_id, &path, &writer_lock, |meta| {
|
||||
|
||||
@@ -563,7 +563,7 @@ mod tests {
|
||||
let mut sync = resume_sync(
|
||||
thread_id,
|
||||
vec![
|
||||
RolloutItem::SessionMeta(session_meta(thread_id)),
|
||||
RolloutItem::SessionMeta(Box::new(session_meta(thread_id))),
|
||||
RolloutItem::EventMsg(EventMsg::UserMessage(user_message("hello metadata"))),
|
||||
],
|
||||
);
|
||||
@@ -672,7 +672,7 @@ mod tests {
|
||||
fn metadata_irrelevant_items_coalesce_updated_at_touches() {
|
||||
let thread_id = ThreadId::new();
|
||||
let mut sync = resume_sync(thread_id, Vec::new());
|
||||
let item = RolloutItem::Compacted(CompactedItem {
|
||||
let item = RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: "compacted".to_string(),
|
||||
replacement_history: None,
|
||||
retained_context: None,
|
||||
@@ -685,7 +685,7 @@ mod tests {
|
||||
compaction_response_id: None,
|
||||
latest_token_usage_record: None,
|
||||
resume_metadata: None,
|
||||
});
|
||||
}));
|
||||
|
||||
let first = sync
|
||||
.observe_appended_items(std::slice::from_ref(&item))
|
||||
@@ -804,7 +804,7 @@ mod tests {
|
||||
let mut sync = resume_sync(
|
||||
thread_id,
|
||||
vec![
|
||||
RolloutItem::SessionMeta(session_meta(thread_id)),
|
||||
RolloutItem::SessionMeta(Box::new(session_meta(thread_id))),
|
||||
RolloutItem::EventMsg(EventMsg::UserMessage(user_message("hello metadata"))),
|
||||
],
|
||||
);
|
||||
@@ -836,7 +836,7 @@ mod tests {
|
||||
let sync = resume_sync(
|
||||
thread_id,
|
||||
vec![
|
||||
RolloutItem::SessionMeta(meta),
|
||||
RolloutItem::SessionMeta(Box::new(meta)),
|
||||
RolloutItem::EventMsg(EventMsg::UserMessage(user_message("hello metadata"))),
|
||||
],
|
||||
);
|
||||
|
||||
@@ -1143,12 +1143,12 @@ mod tests {
|
||||
}
|
||||
|
||||
fn session_meta(history_mode: ThreadHistoryMode) -> RolloutItem {
|
||||
RolloutItem::SessionMeta(codex_protocol::protocol::SessionMetaLine {
|
||||
RolloutItem::SessionMeta(Box::new(codex_protocol::protocol::SessionMetaLine {
|
||||
meta: codex_protocol::protocol::SessionMeta {
|
||||
history_mode,
|
||||
..Default::default()
|
||||
},
|
||||
git: None,
|
||||
})
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ fn legacy_transcript_preview_scans_tail_across_compaction() {
|
||||
vec![
|
||||
rollout_user_message("older user"),
|
||||
rollout_agent_message("older assistant"),
|
||||
RolloutItem::Compacted(CompactedItem {
|
||||
RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: String::from("summary that is not transcript text"),
|
||||
replacement_history: None,
|
||||
retained_context: None,
|
||||
@@ -86,7 +86,7 @@ fn legacy_transcript_preview_scans_tail_across_compaction() {
|
||||
compaction_response_id: None,
|
||||
latest_token_usage_record: None,
|
||||
resume_metadata: None,
|
||||
}),
|
||||
})),
|
||||
rollout_user_message("recent user"),
|
||||
rollout_agent_message("commentary one\ncommentary two"),
|
||||
rollout_agent_message("final one\n\n final two "),
|
||||
@@ -209,7 +209,7 @@ fn legacy_transcript_preview_falls_back_for_oversized_hidden_record() {
|
||||
&path,
|
||||
vec![
|
||||
rollout_user_message("older user"),
|
||||
RolloutItem::Compacted(CompactedItem {
|
||||
RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: "x".repeat(MAX_LEGACY_TRANSCRIPT_PREVIEW_SCAN_BYTES),
|
||||
replacement_history: None,
|
||||
retained_context: None,
|
||||
@@ -222,7 +222,7 @@ fn legacy_transcript_preview_falls_back_for_oversized_hidden_record() {
|
||||
compaction_response_id: None,
|
||||
latest_token_usage_record: None,
|
||||
resume_metadata: None,
|
||||
}),
|
||||
})),
|
||||
rollout_agent_message("recent assistant"),
|
||||
],
|
||||
);
|
||||
@@ -241,7 +241,7 @@ fn legacy_transcript_preview_falls_back_for_oversized_hidden_record() {
|
||||
fn legacy_transcript_preview_falls_back_when_scan_budget_is_exhausted() {
|
||||
let temp_dir = tempdir().expect("tempdir");
|
||||
let path = temp_dir.path().join("rollout.jsonl");
|
||||
let compacted = RolloutItem::Compacted(CompactedItem {
|
||||
let compacted = RolloutItem::Compacted(Box::new(CompactedItem {
|
||||
message: "x".repeat(MAX_LEGACY_TRANSCRIPT_PREVIEW_SCAN_BYTES / 8),
|
||||
replacement_history: None,
|
||||
retained_context: None,
|
||||
@@ -254,7 +254,7 @@ fn legacy_transcript_preview_falls_back_when_scan_budget_is_exhausted() {
|
||||
compaction_response_id: None,
|
||||
latest_token_usage_record: None,
|
||||
resume_metadata: None,
|
||||
});
|
||||
}));
|
||||
let mut items = vec![rollout_user_message("older user")];
|
||||
items.extend(std::iter::repeat_n(compacted, 9));
|
||||
items.push(rollout_agent_message("recent assistant"));
|
||||
|
||||
Reference in New Issue
Block a user