diff --git a/codex-rs/analytics/src/reducer.rs b/codex-rs/analytics/src/reducer.rs index f0eb0ac9a..1be9f624f 100644 --- a/codex-rs/analytics/src/reducer.rs +++ b/codex-rs/analytics/src/reducer.rs @@ -1300,7 +1300,7 @@ impl AnalyticsReducer { thread_metadata.session_id.clone(), connection_state.app_server_client.clone(), connection_state.runtime.clone(), - thread_metadata.thread_source, + thread_metadata.thread_source.clone(), thread_metadata.subagent_source.clone(), thread_metadata.parent_thread_id.clone(), ), diff --git a/codex-rs/app-server/src/extensions.rs b/codex-rs/app-server/src/extensions.rs index 9e0a6e1c4..4916132c5 100644 --- a/codex-rs/app-server/src/extensions.rs +++ b/codex-rs/app-server/src/extensions.rs @@ -26,19 +26,32 @@ use crate::outgoing_message::OutgoingMessageSender; use crate::thread_state::ThreadListenerCommand; use crate::thread_state::ThreadStateManager; +pub(crate) struct ThreadExtensionDependencies { + pub(crate) event_sink: Arc, + pub(crate) auth_manager: Arc, + pub(crate) state_db: Option, + pub(crate) analytics_events_client: AnalyticsEventsClient, + pub(crate) thread_manager: Weak, + pub(crate) goal_service: Arc, + pub(crate) executor_skill_provider: Arc, +} + pub(crate) fn thread_extensions( guardian_agent_spawner: S, - event_sink: Arc, - auth_manager: Arc, - state_db: Option, - analytics_events_client: AnalyticsEventsClient, - thread_manager: Weak, - goal_service: Arc, - executor_skill_provider: Arc, + dependencies: ThreadExtensionDependencies, ) -> Arc> where S: AgentSpawner + 'static, { + let ThreadExtensionDependencies { + event_sink, + auth_manager, + state_db, + analytics_events_client, + thread_manager, + goal_service, + executor_skill_provider, + } = dependencies; let mut builder = ExtensionRegistryBuilder::::with_event_sink(event_sink); if let Some(state_db) = state_db { codex_goal_extension::install_with_backend( diff --git a/codex-rs/app-server/src/mcp_refresh.rs b/codex-rs/app-server/src/mcp_refresh.rs index ff7104883..b5431228d 100644 --- a/codex-rs/app-server/src/mcp_refresh.rs +++ b/codex-rs/app-server/src/mcp_refresh.rs @@ -96,6 +96,7 @@ async fn queue_refresh( #[cfg(test)] mod tests { use super::*; + use crate::extensions::ThreadExtensionDependencies; use crate::extensions::guardian_agent_spawner; use crate::extensions::thread_extensions; use async_trait::async_trait; @@ -193,13 +194,15 @@ mod tests { Arc::clone(&environment_manager), thread_extensions( guardian_agent_spawner(thread_manager.clone()), - Arc::new(NoopExtensionEventSink), - auth_manager.clone(), - Some(state_db.clone()), - codex_analytics::AnalyticsEventsClient::disabled(), - thread_manager.clone(), - Arc::new(codex_goal_extension::GoalService::new()), - Arc::clone(&executor_skill_provider), + ThreadExtensionDependencies { + event_sink: Arc::new(NoopExtensionEventSink), + auth_manager: auth_manager.clone(), + state_db: Some(state_db.clone()), + analytics_events_client: codex_analytics::AnalyticsEventsClient::disabled(), + thread_manager: thread_manager.clone(), + goal_service: Arc::new(codex_goal_extension::GoalService::new()), + executor_skill_provider: Arc::clone(&executor_skill_provider), + }, ), /*analytics_events_client*/ None, Arc::clone(&thread_store), diff --git a/codex-rs/app-server/src/message_processor.rs b/codex-rs/app-server/src/message_processor.rs index 2069d61c7..6bb5121dc 100644 --- a/codex-rs/app-server/src/message_processor.rs +++ b/codex-rs/app-server/src/message_processor.rs @@ -8,6 +8,7 @@ use crate::attestation::app_server_attestation_provider; use crate::config_manager::ConfigManager; use crate::connection_rpc_gate::ConnectionRpcGate; use crate::error_code::invalid_request; +use crate::extensions::ThreadExtensionDependencies; use crate::extensions::app_server_extension_event_sink; use crate::extensions::guardian_agent_spawner; use crate::extensions::thread_extensions; @@ -324,13 +325,18 @@ impl MessageProcessor { environment_manager, thread_extensions( guardian_agent_spawner(thread_manager.clone()), - app_server_extension_event_sink(outgoing.clone(), thread_state_manager.clone()), - auth_manager.clone(), - state_db.clone(), - analytics_events_client.clone(), - thread_manager.clone(), - Arc::clone(&goal_service), - Arc::clone(&executor_skill_provider), + ThreadExtensionDependencies { + event_sink: app_server_extension_event_sink( + outgoing.clone(), + thread_state_manager.clone(), + ), + auth_manager: auth_manager.clone(), + state_db: state_db.clone(), + analytics_events_client: analytics_events_client.clone(), + thread_manager: thread_manager.clone(), + goal_service: Arc::clone(&goal_service), + executor_skill_provider: Arc::clone(&executor_skill_provider), + }, ), Some(analytics_events_client.clone()), Arc::clone(&thread_store), diff --git a/codex-rs/app-server/tests/suite/v2/turn_start.rs b/codex-rs/app-server/tests/suite/v2/turn_start.rs index 508093799..823851b71 100644 --- a/codex-rs/app-server/tests/suite/v2/turn_start.rs +++ b/codex-rs/app-server/tests/suite/v2/turn_start.rs @@ -591,7 +591,15 @@ async fn turn_start_emits_thread_scoped_warning_notification_for_trimmed_skills( write_test_skill(codex_home.path(), "alpha-skill")?; write_test_skill(codex_home.path(), "beta-skill")?; - let mut mcp = TestAppServer::new(codex_home.path()).await?; + let isolated_home = codex_home.path().to_string_lossy(); + let mut mcp = TestAppServer::new_with_env( + codex_home.path(), + &[ + ("HOME", Some(isolated_home.as_ref())), + ("USERPROFILE", Some(isolated_home.as_ref())), + ], + ) + .await?; timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??; let thread_req = mcp