mirror of
https://github.com/openai/codex.git
synced 2026-11-14 21:40:39 +00:00
## What changed Add `codex_history::CompactionCheckpoint` to keep a checkpoint and its recorded producer model hash together, with shared checks for usability and reviewer compatibility. Replace `ConversationHistorySnapshot::latest_compaction_model_hash()` with `latest_compaction()` and use the shared abstraction in Guardian context selection, review sessions, and parent compaction reuse. Preserve selection of the latest checkpoint even when unusable, and leave missing producer metadata unknown. ## Testing Add coverage showing that the latest checkpoint retains its own provenance even with missing or empty encrypted content, and that compatibility requires matching producer and reviewer hashes. Adapt existing history, migration, and parent compaction tests to the new API. GitOrigin-RevId: 98e794644edf979c98fcc8294baa48ff82ea0ed0
62 lines
1.9 KiB
Rust
62 lines
1.9 KiB
Rust
//! Borrows the latest opaque checkpoint and its recorded producer as one history item.
|
|
//! Malformed checkpoints remain visible so consumers cannot fall back to an older grant.
|
|
|
|
use codex_protocol::models::ResponseItem;
|
|
|
|
use crate::ResponseItemEnvelope;
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
|
pub struct CompactionCheckpoint<'a> {
|
|
pub item: &'a ResponseItem,
|
|
pub model_hash: Option<&'a str>,
|
|
}
|
|
|
|
impl<'a> CompactionCheckpoint<'a> {
|
|
pub fn latest(items: &'a [ResponseItemEnvelope]) -> Option<Self> {
|
|
items.iter().rev().find_map(|envelope| {
|
|
Self::from_item(
|
|
&envelope.item,
|
|
envelope
|
|
.metadata
|
|
.as_ref()
|
|
.and_then(|metadata| metadata.compaction_model_hash.as_deref()),
|
|
)
|
|
})
|
|
}
|
|
|
|
/// Missing producer metadata stays unknown, including when the active model changes.
|
|
pub fn from_item(item: &'a ResponseItem, model_hash: Option<&'a str>) -> Option<Self> {
|
|
matches!(
|
|
item,
|
|
ResponseItem::Compaction { .. } | ResponseItem::ContextCompaction { .. }
|
|
)
|
|
.then_some(Self { item, model_hash })
|
|
}
|
|
|
|
pub fn is_usable(self) -> bool {
|
|
match self.item {
|
|
ResponseItem::Compaction {
|
|
id: Some(_),
|
|
encrypted_content,
|
|
..
|
|
}
|
|
| ResponseItem::ContextCompaction {
|
|
id: Some(_),
|
|
encrypted_content: Some(encrypted_content),
|
|
..
|
|
} => !encrypted_content.is_empty(),
|
|
_ => false,
|
|
}
|
|
}
|
|
|
|
pub fn is_compatible_with(self, reviewer_model_hash: Option<&str>) -> bool {
|
|
self.model_hash
|
|
.zip(reviewer_model_hash)
|
|
.is_some_and(|(producer, reviewer)| !producer.is_empty() && producer == reviewer)
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
#[path = "compaction_checkpoint_tests.rs"]
|
|
mod tests;
|