diff --git a/codex-rs/core/src/compact.rs b/codex-rs/core/src/compact.rs index 40e6284deb..17963a04f8 100644 --- a/codex-rs/core/src/compact.rs +++ b/codex-rs/core/src/compact.rs @@ -11,6 +11,7 @@ use crate::error::Result as CodexResult; use crate::features::Feature; use crate::protocol::CompactedItem; use crate::protocol::ContextCompactedEvent; +use crate::protocol::ContextCompactionStartedEvent; use crate::protocol::EventMsg; use crate::protocol::TurnContextItem; use crate::protocol::TurnStartedEvent; @@ -70,6 +71,9 @@ async fn run_compact_task_inner( turn_context: Arc, input: Vec, ) { + let start_event = EventMsg::ContextCompactionStarted(ContextCompactionStartedEvent {}); + sess.send_event(&turn_context, start_event).await; + let initial_input_for_turn: ResponseInputItem = ResponseInputItem::from(input); let mut history = sess.clone_history().await; diff --git a/codex-rs/core/src/compact_remote.rs b/codex-rs/core/src/compact_remote.rs index dd038c5287..bb360db3f2 100644 --- a/codex-rs/core/src/compact_remote.rs +++ b/codex-rs/core/src/compact_remote.rs @@ -6,6 +6,7 @@ use crate::codex::TurnContext; use crate::error::Result as CodexResult; use crate::protocol::CompactedItem; use crate::protocol::ContextCompactedEvent; +use crate::protocol::ContextCompactionStartedEvent; use crate::protocol::EventMsg; use crate::protocol::RolloutItem; use crate::protocol::TurnStartedEvent; @@ -40,6 +41,9 @@ async fn run_remote_compact_task_inner_impl( sess: &Arc, turn_context: &Arc, ) -> CodexResult<()> { + let start_event = EventMsg::ContextCompactionStarted(ContextCompactionStartedEvent {}); + sess.send_event(turn_context, start_event).await; + let history = sess.clone_history().await; // Required to keep `/undo` available after compaction diff --git a/codex-rs/core/src/rollout/policy.rs b/codex-rs/core/src/rollout/policy.rs index 2d4a79cc22..4312650a95 100644 --- a/codex-rs/core/src/rollout/policy.rs +++ b/codex-rs/core/src/rollout/policy.rs @@ -42,6 +42,7 @@ pub(crate) fn should_persist_event_msg(ev: &EventMsg) -> bool { | EventMsg::AgentReasoning(_) | EventMsg::AgentReasoningRawContent(_) | EventMsg::TokenCount(_) + | EventMsg::ContextCompactionStarted(_) | EventMsg::ContextCompacted(_) | EventMsg::EnteredReviewMode(_) | EventMsg::ExitedReviewMode(_) diff --git a/codex-rs/exec/src/event_processor_with_human_output.rs b/codex-rs/exec/src/event_processor_with_human_output.rs index c4a5c27d9c..d6c17d4906 100644 --- a/codex-rs/exec/src/event_processor_with_human_output.rs +++ b/codex-rs/exec/src/event_processor_with_human_output.rs @@ -568,8 +568,11 @@ impl EventProcessor for EventProcessorWithHumanOutput { ts_msg!(self, "task aborted: review ended"); } }, + EventMsg::ContextCompactionStarted(_) => { + ts_msg!(self, "compact started"); + } EventMsg::ContextCompacted(_) => { - ts_msg!(self, "context compacted"); + ts_msg!(self, "compact ended"); } EventMsg::CollabAgentSpawnBegin(_) | EventMsg::CollabAgentSpawnEnd(_) diff --git a/codex-rs/mcp-server/src/codex_tool_runner.rs b/codex-rs/mcp-server/src/codex_tool_runner.rs index b268b8f1b4..20a49c4fce 100644 --- a/codex-rs/mcp-server/src/codex_tool_runner.rs +++ b/codex-rs/mcp-server/src/codex_tool_runner.rs @@ -359,6 +359,7 @@ async fn run_codex_tool_session_inner( | EventMsg::UndoCompleted(_) | EventMsg::ExitedReviewMode(_) | EventMsg::RequestUserInput(_) + | EventMsg::ContextCompactionStarted(_) | EventMsg::ContextCompacted(_) | EventMsg::ThreadRolledBack(_) | EventMsg::CollabAgentSpawnBegin(_) diff --git a/codex-rs/protocol/src/protocol.rs b/codex-rs/protocol/src/protocol.rs index d5accde8e8..42d85934c3 100644 --- a/codex-rs/protocol/src/protocol.rs +++ b/codex-rs/protocol/src/protocol.rs @@ -658,6 +658,9 @@ pub enum EventMsg { /// indicates the turn continued but the user should still be notified. Warning(WarningEvent), + /// Conversation history compaction has started. + ContextCompactionStarted(ContextCompactionStartedEvent), + /// Conversation history was compacted (either automatically or manually). ContextCompacted(ContextCompactedEvent), @@ -1049,6 +1052,9 @@ pub struct WarningEvent { pub message: String, } +#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)] +pub struct ContextCompactionStartedEvent; + #[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)] pub struct ContextCompactedEvent; diff --git a/codex-rs/tui/src/chatwidget.rs b/codex-rs/tui/src/chatwidget.rs index 2518eb41bc..ff0a0eee50 100644 --- a/codex-rs/tui/src/chatwidget.rs +++ b/codex-rs/tui/src/chatwidget.rs @@ -2530,7 +2530,10 @@ impl ChatWidget { self.on_entered_review_mode(review_request, from_replay) } EventMsg::ExitedReviewMode(review) => self.on_exited_review_mode(review), - EventMsg::ContextCompacted(_) => self.on_agent_message("Context compacted".to_owned()), + EventMsg::ContextCompactionStarted(_) => { + self.on_agent_message("Compact started".to_owned()) + } + EventMsg::ContextCompacted(_) => self.on_agent_message("Compact ended".to_owned()), EventMsg::CollabAgentSpawnBegin(_) => {} EventMsg::CollabAgentSpawnEnd(ev) => self.on_collab_event(collab::spawn_end(ev)), EventMsg::CollabAgentInteractionBegin(_) => {} diff --git a/codex-rs/tui2/src/chatwidget.rs b/codex-rs/tui2/src/chatwidget.rs index ffc763e214..90eac1be9c 100644 --- a/codex-rs/tui2/src/chatwidget.rs +++ b/codex-rs/tui2/src/chatwidget.rs @@ -2301,7 +2301,10 @@ impl ChatWidget { self.on_entered_review_mode(review_request) } EventMsg::ExitedReviewMode(review) => self.on_exited_review_mode(review), - EventMsg::ContextCompacted(_) => self.on_agent_message("Context compacted".to_owned()), + EventMsg::ContextCompactionStarted(_) => { + self.on_agent_message("Compact started".to_owned()) + } + EventMsg::ContextCompacted(_) => self.on_agent_message("Compact ended".to_owned()), EventMsg::CollabAgentSpawnBegin(_) => {} EventMsg::CollabAgentSpawnEnd(ev) => self.on_collab_event(collab::spawn_end(ev)), EventMsg::CollabAgentInteractionBegin(_) => {}