diff --git a/codex-rs/core/src/codex_thread.rs b/codex-rs/core/src/codex_thread.rs index b1c9f3e3f8..537f3c8972 100644 --- a/codex-rs/core/src/codex_thread.rs +++ b/codex-rs/core/src/codex_thread.rs @@ -167,7 +167,6 @@ impl CodexThread { } pub async fn emit_thread_resume_lifecycle(&self) { - let thread_settings = ThreadSettingsSnapshot::from(self.config_snapshot().await); for contributor in self .codex .session @@ -177,7 +176,6 @@ impl CodexThread { { contributor .on_thread_resume(codex_extension_api::ThreadResumeInput { - thread_settings: &thread_settings, session_store: &self.codex.session.services.session_extension_data, thread_store: &self.codex.session.services.thread_extension_data, }) diff --git a/codex-rs/core/src/session/mod.rs b/codex-rs/core/src/session/mod.rs index ab48e68d4a..245047c925 100644 --- a/codex-rs/core/src/session/mod.rs +++ b/codex-rs/core/src/session/mod.rs @@ -2667,11 +2667,6 @@ impl Session { state.session_configuration.collaboration_mode.clone() } - pub(crate) async fn thread_config_snapshot(&self) -> ThreadConfigSnapshot { - let state = self.state.lock().await; - state.session_configuration.thread_config_snapshot() - } - async fn send_raw_response_items(&self, turn_context: &TurnContext, items: &[ResponseItem]) { for item in items { self.send_event( diff --git a/codex-rs/core/src/tasks/idle_extension.rs b/codex-rs/core/src/tasks/idle_extension.rs index bb58b384da..785d44dba1 100644 --- a/codex-rs/core/src/tasks/idle_extension.rs +++ b/codex-rs/core/src/tasks/idle_extension.rs @@ -4,7 +4,8 @@ use std::sync::Arc; use codex_extension_api::ResponseInjectionItem; use codex_extension_api::ThreadIdleRequest; -use codex_protocol::protocol::ThreadSettingsSnapshot; +use codex_protocol::config_types::CollaborationMode; +use codex_protocol::config_types::ModeKind; use crate::session::TurnInput; use crate::session::session::Session; @@ -102,11 +103,9 @@ pub(crate) async fn maybe_start_turn(session: Arc) { } async fn notify_thread_idle(session: &Session) { - let thread_settings = thread_settings_snapshot(session).await; for contributor in session.services.extensions.thread_lifecycle_contributors() { contributor .on_thread_idle(codex_extension_api::ThreadIdleInput { - thread_settings: &thread_settings, session_store: &session.services.session_extension_data, thread_store: &session.services.thread_extension_data, }) @@ -132,7 +131,7 @@ struct IdleTurnCandidate { } async fn next_idle_turn_candidate(session: &Session) -> Option { - let thread_settings = thread_settings_snapshot(session).await; + let collaboration_mode = session.collaboration_mode().await; for (contributor_index, contributor) in session .services .extensions @@ -140,9 +139,11 @@ async fn next_idle_turn_candidate(session: &Session) -> Option bool { } } +fn idle_turn_policy_allows_mode( + policy: codex_extension_api::IdleTurnPolicy, + collaboration_mode: &CollaborationMode, +) -> bool { + !matches!(collaboration_mode.mode, ModeKind::Plan) || policy.allows_plan_mode() +} + async fn should_start_idle_turn(session: &Session, candidate: &IdleTurnCandidate) -> bool { let Some(contributor) = session .services @@ -177,10 +185,12 @@ async fn should_start_idle_turn(session: &Session, candidate: &IdleTurnCandidate else { return false; }; - let thread_settings = thread_settings_snapshot(session).await; + let collaboration_mode = session.collaboration_mode().await; + if !idle_turn_policy_allows_mode(contributor.idle_turn_policy(), &collaboration_mode) { + return false; + } contributor .should_start_thread_idle_turn(codex_extension_api::ThreadIdleTurnStartInput { - thread_settings: &thread_settings, request: &candidate.request, session_store: &session.services.session_extension_data, thread_store: &session.services.thread_extension_data, @@ -188,10 +198,6 @@ async fn should_start_idle_turn(session: &Session, candidate: &IdleTurnCandidate .await } -async fn thread_settings_snapshot(session: &Session) -> ThreadSettingsSnapshot { - ThreadSettingsSnapshot::from(session.thread_config_snapshot().await) -} - async fn reserve_idle_turn(session: &Session) -> bool { let mut active_turn = session.active_turn.lock().await; if active_turn.is_some() { diff --git a/codex-rs/ext/extension-api/src/contributors.rs b/codex-rs/ext/extension-api/src/contributors.rs index 8cdc24e7ae..b90c013d73 100644 --- a/codex-rs/ext/extension-api/src/contributors.rs +++ b/codex-rs/ext/extension-api/src/contributors.rs @@ -19,6 +19,7 @@ mod turn_lifecycle; pub use prompt::PromptFragment; pub use prompt::PromptSlot; +pub use thread_lifecycle::IdleTurnPolicy; pub use thread_lifecycle::ThreadIdleInput; pub use thread_lifecycle::ThreadIdleRequest; pub use thread_lifecycle::ThreadIdleTurnStartInput; @@ -80,9 +81,15 @@ pub type ThreadIdleTurnStartFuture<'a> = std::pin::Pin