mirror of
https://github.com/openai/codex.git
synced 2026-11-13 14:46:14 +00:00
Centralize compacted rollout item construction (#34533)
## What changed - Pass only compaction message and window metadata into `Session::replace_compacted_history`. - Build the persisted `CompactedItem` there after assigning any missing response item IDs, so its replacement history matches the live history without callers cloning or assembling it themselves. GitOrigin-RevId: a6106c33b6d3eef39ac0b563a50e17f6782970dc
This commit is contained in:
1 parent
c44c4de7b4
commit
f69f88f811
4 files changed
+41
-38
No files matched your search
@@ -18,6 +18,7 @@ use crate::session::session::Session;
|
|||||||
use crate::session::step_context::StepContext;
|
use crate::session::step_context::StepContext;
|
||||||
use crate::session::turn::get_last_assistant_message_from_turn;
|
use crate::session::turn::get_last_assistant_message_from_turn;
|
||||||
use crate::session::turn_context::TurnContext;
|
use crate::session::turn_context::TurnContext;
|
||||||
|
use crate::state::AutoCompactWindowIds;
|
||||||
use crate::util::backoff;
|
use crate::util::backoff;
|
||||||
use codex_analytics::CodexCompactionEvent;
|
use codex_analytics::CodexCompactionEvent;
|
||||||
use codex_analytics::CompactionImplementation;
|
use codex_analytics::CompactionImplementation;
|
||||||
@@ -35,7 +36,6 @@ use codex_protocol::models::ContentItem;
|
|||||||
use codex_protocol::models::InternalChatMessageMetadataPassthrough;
|
use codex_protocol::models::InternalChatMessageMetadataPassthrough;
|
||||||
use codex_protocol::models::ResponseInputItem;
|
use codex_protocol::models::ResponseInputItem;
|
||||||
use codex_protocol::models::ResponseItem;
|
use codex_protocol::models::ResponseItem;
|
||||||
use codex_protocol::protocol::CompactedItem;
|
|
||||||
use codex_protocol::protocol::EventMsg;
|
use codex_protocol::protocol::EventMsg;
|
||||||
use codex_protocol::protocol::RawResponseCompletedEvent;
|
use codex_protocol::protocol::RawResponseCompletedEvent;
|
||||||
use codex_protocol::protocol::TurnStartedEvent;
|
use codex_protocol::protocol::TurnStartedEvent;
|
||||||
@@ -72,6 +72,16 @@ pub(crate) enum InitialContextInjection {
|
|||||||
DoNotInject,
|
DoNotInject,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Metadata for a new compaction checkpoint, kept separate from its replacement history.
|
||||||
|
///
|
||||||
|
/// `Session::replace_compacted_history` assigns missing item IDs before constructing the persisted
|
||||||
|
/// `CompactedItem`, ensuring the live and persisted histories remain identical.
|
||||||
|
pub(crate) struct CompactedHistoryMetadata {
|
||||||
|
pub(crate) message: String,
|
||||||
|
pub(crate) window_number: u64,
|
||||||
|
pub(crate) window_ids: AutoCompactWindowIds,
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) async fn build_compaction_initial_context(
|
pub(crate) async fn build_compaction_initial_context(
|
||||||
sess: &Session,
|
sess: &Session,
|
||||||
initial_context_injection: &InitialContextInjection,
|
initial_context_injection: &InitialContextInjection,
|
||||||
@@ -357,20 +367,16 @@ async fn run_compact_task_inner_impl(
|
|||||||
Some(turn_context.to_turn_context_item())
|
Some(turn_context.to_turn_context_item())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let compacted_item = CompactedItem {
|
|
||||||
message: summary_text.clone(),
|
|
||||||
replacement_history: Some(new_history.clone()),
|
|
||||||
window_number: Some(window_number),
|
|
||||||
first_window_id: Some(window_ids.first_window_id.to_string()),
|
|
||||||
previous_window_id: window_ids.previous_window_id.map(|id| id.to_string()),
|
|
||||||
window_id: Some(window_ids.window_id.to_string()),
|
|
||||||
};
|
|
||||||
sess.replace_compacted_history(
|
sess.replace_compacted_history(
|
||||||
turn_context.as_ref(),
|
turn_context.as_ref(),
|
||||||
new_history,
|
new_history,
|
||||||
reference_context_item,
|
reference_context_item,
|
||||||
world_state_baseline,
|
world_state_baseline,
|
||||||
compacted_item,
|
CompactedHistoryMetadata {
|
||||||
|
message: summary_text,
|
||||||
|
window_number,
|
||||||
|
window_ids,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
sess.recompute_token_usage(&turn_context).await;
|
sess.recompute_token_usage(&turn_context).await;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::OnceLock;
|
use std::sync::OnceLock;
|
||||||
|
|
||||||
|
use crate::compact::CompactedHistoryMetadata;
|
||||||
use crate::compact::CompactionAnalyticsAttempt;
|
use crate::compact::CompactionAnalyticsAttempt;
|
||||||
use crate::compact::CompactionAnalyticsDetails;
|
use crate::compact::CompactionAnalyticsDetails;
|
||||||
use crate::compact::InitialContextInjection;
|
use crate::compact::InitialContextInjection;
|
||||||
@@ -32,7 +33,6 @@ use codex_protocol::models::BaseInstructions;
|
|||||||
use codex_protocol::models::FunctionCallOutputBody;
|
use codex_protocol::models::FunctionCallOutputBody;
|
||||||
use codex_protocol::models::FunctionCallOutputPayload;
|
use codex_protocol::models::FunctionCallOutputPayload;
|
||||||
use codex_protocol::models::ResponseItem;
|
use codex_protocol::models::ResponseItem;
|
||||||
use codex_protocol::protocol::CompactedItem;
|
|
||||||
use codex_protocol::protocol::EventMsg;
|
use codex_protocol::protocol::EventMsg;
|
||||||
use codex_protocol::protocol::TurnStartedEvent;
|
use codex_protocol::protocol::TurnStartedEvent;
|
||||||
use codex_rollout_trace::CompactionCheckpointTracePayload;
|
use codex_rollout_trace::CompactionCheckpointTracePayload;
|
||||||
@@ -269,14 +269,6 @@ async fn run_remote_compact_task_inner_impl(
|
|||||||
Some(compaction_turn_context.to_turn_context_item())
|
Some(compaction_turn_context.to_turn_context_item())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let compacted_item = CompactedItem {
|
|
||||||
message: String::new(),
|
|
||||||
replacement_history: Some(new_history.clone()),
|
|
||||||
window_number: Some(new_window_number),
|
|
||||||
first_window_id: Some(new_window_ids.first_window_id.to_string()),
|
|
||||||
previous_window_id: new_window_ids.previous_window_id.map(|id| id.to_string()),
|
|
||||||
window_id: Some(new_window_ids.window_id.to_string()),
|
|
||||||
};
|
|
||||||
// Install is the semantic boundary where the compact endpoint's output becomes live
|
// Install is the semantic boundary where the compact endpoint's output becomes live
|
||||||
// thread history. Keep it distinct from the later inference request so the reducer can
|
// thread history. Keep it distinct from the later inference request so the reducer can
|
||||||
// still represent repeated developer/context prefix items exactly as the model saw them.
|
// still represent repeated developer/context prefix items exactly as the model saw them.
|
||||||
@@ -291,7 +283,11 @@ async fn run_remote_compact_task_inner_impl(
|
|||||||
new_history,
|
new_history,
|
||||||
reference_context_item,
|
reference_context_item,
|
||||||
world_state_baseline,
|
world_state_baseline,
|
||||||
compacted_item,
|
CompactedHistoryMetadata {
|
||||||
|
message: String::new(),
|
||||||
|
window_number: new_window_number,
|
||||||
|
window_ids: new_window_ids,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
sess.recompute_token_usage(compaction_turn_context).await;
|
sess.recompute_token_usage(compaction_turn_context).await;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ use crate::Prompt;
|
|||||||
use crate::ResponseStream;
|
use crate::ResponseStream;
|
||||||
use crate::client::ModelClientSession;
|
use crate::client::ModelClientSession;
|
||||||
use crate::client_common::ResponseEvent;
|
use crate::client_common::ResponseEvent;
|
||||||
|
use crate::compact::CompactedHistoryMetadata;
|
||||||
use crate::compact::CompactionAnalyticsAttempt;
|
use crate::compact::CompactionAnalyticsAttempt;
|
||||||
use crate::compact::CompactionAnalyticsDetails;
|
use crate::compact::CompactionAnalyticsDetails;
|
||||||
use crate::compact::InitialContextInjection;
|
use crate::compact::InitialContextInjection;
|
||||||
@@ -33,7 +34,6 @@ use codex_protocol::items::ContextCompactionItem;
|
|||||||
use codex_protocol::items::TurnItem;
|
use codex_protocol::items::TurnItem;
|
||||||
use codex_protocol::models::ContentItem;
|
use codex_protocol::models::ContentItem;
|
||||||
use codex_protocol::models::ResponseItem;
|
use codex_protocol::models::ResponseItem;
|
||||||
use codex_protocol::protocol::CompactedItem;
|
|
||||||
use codex_protocol::protocol::EventMsg;
|
use codex_protocol::protocol::EventMsg;
|
||||||
use codex_protocol::protocol::TokenUsage;
|
use codex_protocol::protocol::TokenUsage;
|
||||||
use codex_protocol::protocol::TruncationPolicy;
|
use codex_protocol::protocol::TruncationPolicy;
|
||||||
@@ -293,14 +293,6 @@ async fn run_remote_compact_task_inner_impl(
|
|||||||
Some(compaction_turn_context.to_turn_context_item())
|
Some(compaction_turn_context.to_turn_context_item())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let compacted_item = CompactedItem {
|
|
||||||
message: String::new(),
|
|
||||||
replacement_history: Some(new_history.clone()),
|
|
||||||
window_number: Some(new_window_number),
|
|
||||||
first_window_id: Some(new_window_ids.first_window_id.to_string()),
|
|
||||||
previous_window_id: new_window_ids.previous_window_id.map(|id| id.to_string()),
|
|
||||||
window_id: Some(new_window_ids.window_id.to_string()),
|
|
||||||
};
|
|
||||||
if let Some(trace_input_history) = trace_input_history.as_deref() {
|
if let Some(trace_input_history) = trace_input_history.as_deref() {
|
||||||
compaction_trace.record_installed(&CompactionCheckpointTracePayload {
|
compaction_trace.record_installed(&CompactionCheckpointTracePayload {
|
||||||
input_history: trace_input_history,
|
input_history: trace_input_history,
|
||||||
@@ -312,7 +304,11 @@ async fn run_remote_compact_task_inner_impl(
|
|||||||
new_history,
|
new_history,
|
||||||
reference_context_item,
|
reference_context_item,
|
||||||
world_state_baseline,
|
world_state_baseline,
|
||||||
compacted_item,
|
CompactedHistoryMetadata {
|
||||||
|
message: String::new(),
|
||||||
|
window_number: new_window_number,
|
||||||
|
window_ids: new_window_ids,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
sess.recompute_token_usage(compaction_turn_context).await;
|
sess.recompute_token_usage(compaction_turn_context).await;
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ use crate::attestation::AttestationProvider;
|
|||||||
use crate::audio_preparation::prepare_response_items as prepare_audio_response_items;
|
use crate::audio_preparation::prepare_response_items as prepare_audio_response_items;
|
||||||
use crate::build_available_skills;
|
use crate::build_available_skills;
|
||||||
use crate::compact;
|
use crate::compact;
|
||||||
|
use crate::compact::CompactedHistoryMetadata;
|
||||||
use crate::config::ManagedFeatures;
|
use crate::config::ManagedFeatures;
|
||||||
use crate::config::resolve_tool_suggest_config_from_layer_stack;
|
use crate::config::resolve_tool_suggest_config_from_layer_stack;
|
||||||
use crate::context::ApprovedCommandPrefixSaved;
|
use crate::context::ApprovedCommandPrefixSaved;
|
||||||
@@ -3052,7 +3053,7 @@ impl Session {
|
|||||||
items: Vec<ResponseItem>,
|
items: Vec<ResponseItem>,
|
||||||
reference_context_item: Option<TurnContextItem>,
|
reference_context_item: Option<TurnContextItem>,
|
||||||
world_state_baseline: Option<Arc<WorldState>>,
|
world_state_baseline: Option<Arc<WorldState>>,
|
||||||
compacted_item: CompactedItem,
|
metadata: CompactedHistoryMetadata,
|
||||||
) {
|
) {
|
||||||
let items = if turn_context.item_ids_enabled() {
|
let items = if turn_context.item_ids_enabled() {
|
||||||
Self::assign_missing_response_item_ids(Cow::Owned(items)).into_owned()
|
Self::assign_missing_response_item_ids(Cow::Owned(items)).into_owned()
|
||||||
@@ -3060,8 +3061,15 @@ impl Session {
|
|||||||
items
|
items
|
||||||
};
|
};
|
||||||
let compacted_item = CompactedItem {
|
let compacted_item = CompactedItem {
|
||||||
|
message: metadata.message,
|
||||||
replacement_history: Some(items.clone()),
|
replacement_history: Some(items.clone()),
|
||||||
..compacted_item
|
window_number: Some(metadata.window_number),
|
||||||
|
first_window_id: Some(metadata.window_ids.first_window_id.to_string()),
|
||||||
|
previous_window_id: metadata
|
||||||
|
.window_ids
|
||||||
|
.previous_window_id
|
||||||
|
.map(|id| id.to_string()),
|
||||||
|
window_id: Some(metadata.window_ids.window_id.to_string()),
|
||||||
};
|
};
|
||||||
// Compaction starts a new history window, so its WorldState baseline must be full.
|
// Compaction starts a new history window, so its WorldState baseline must be full.
|
||||||
let mut world_state_item = None;
|
let mut world_state_item = None;
|
||||||
@@ -3544,13 +3552,10 @@ impl Session {
|
|||||||
context_items,
|
context_items,
|
||||||
Some(turn_context_item),
|
Some(turn_context_item),
|
||||||
Some(world_state),
|
Some(world_state),
|
||||||
CompactedItem {
|
CompactedHistoryMetadata {
|
||||||
message: String::new(),
|
message: String::new(),
|
||||||
replacement_history: None,
|
window_number,
|
||||||
window_number: Some(window_number),
|
window_ids,
|
||||||
first_window_id: Some(window_ids.first_window_id.to_string()),
|
|
||||||
previous_window_id: window_ids.previous_window_id.map(|id| id.to_string()),
|
|
||||||
window_id: Some(window_ids.window_id.to_string()),
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|||||||
Reference in new issue
Block a user