diff --git a/codex-rs/core/src/session/prefix_compaction.rs b/codex-rs/core/src/session/prefix_compaction.rs index dce2267845..ac430f3f77 100644 --- a/codex-rs/core/src/session/prefix_compaction.rs +++ b/codex-rs/core/src/session/prefix_compaction.rs @@ -176,7 +176,7 @@ async fn apply_prefix_compact_candidate( return Ok(false); } - let compaction_item = TurnItem::ContextCompaction(ContextCompactionItem::new()); + let compaction_item = TurnItem::ContextCompaction(ContextCompactionItem::new_prefix()); sess.emit_turn_item_started(turn_context, &compaction_item) .await; diff --git a/codex-rs/protocol/src/items.rs b/codex-rs/protocol/src/items.rs index 601858dd5f..d33255c350 100644 --- a/codex-rs/protocol/src/items.rs +++ b/codex-rs/protocol/src/items.rs @@ -130,12 +130,24 @@ pub struct ImageGenerationItem { #[derive(Debug, Clone, Deserialize, Serialize, TS, JsonSchema)] pub struct ContextCompactionItem { pub id: String, + #[serde(default, skip_serializing, skip_deserializing)] + #[schemars(skip)] + #[ts(skip)] + pub is_prefix: bool, } impl ContextCompactionItem { pub fn new() -> Self { Self { id: uuid::Uuid::new_v4().to_string(), + is_prefix: false, + } + } + + pub fn new_prefix() -> Self { + Self { + id: uuid::Uuid::new_v4().to_string(), + is_prefix: true, } } diff --git a/codex-rs/tui/src/app/app_server_adapter.rs b/codex-rs/tui/src/app/app_server_adapter.rs index f0abb5326e..e35531e272 100644 --- a/codex-rs/tui/src/app/app_server_adapter.rs +++ b/codex-rs/tui/src/app/app_server_adapter.rs @@ -894,6 +894,7 @@ fn thread_item_to_core(item: &ThreadItem) -> Option { ThreadItem::ContextCompaction { id } => { Some(TurnItem::ContextCompaction(ContextCompactionItem { id: id.clone(), + is_prefix: false, })) } ThreadItem::CommandExecution { .. } diff --git a/codex-rs/tui/src/chatwidget.rs b/codex-rs/tui/src/chatwidget.rs index 4112ae00b9..825756334f 100644 --- a/codex-rs/tui/src/chatwidget.rs +++ b/codex-rs/tui/src/chatwidget.rs @@ -2206,11 +2206,16 @@ impl ChatWidget { self.request_redraw(); } - fn on_context_compacted(&mut self) { + fn on_context_compacted(&mut self, is_prefix: bool) { self.flush_answer_stream_with_separator(); self.handle_stream_finished(); + let label = if is_prefix { + "Context prefix compacted" + } else { + "Context compacted" + }; self.add_to_history(history_cell::new_info_event( - "Context compacted".to_owned(), + label.to_owned(), /*hint*/ None, )); self.request_redraw(); @@ -5990,7 +5995,7 @@ impl ChatWidget { self.exit_review_mode_after_item(); } ThreadItem::ContextCompaction { .. } => { - self.on_context_compacted(); + self.on_context_compacted(/*is_prefix*/ false); } ThreadItem::HookPrompt { .. } => {} ThreadItem::CollabAgentToolCall { @@ -6913,6 +6918,9 @@ impl ChatWidget { if let codex_protocol::items::TurnItem::Plan(plan_item) = &item { self.on_plan_item_completed(plan_item.text.clone()); } + if let codex_protocol::items::TurnItem::ContextCompaction(item) = &item { + self.on_context_compacted(item.is_prefix); + } if let codex_protocol::items::TurnItem::AgentMessage(item) = item { self.on_agent_message_item_completed(item); }