diff --git a/codex-rs/core/src/codex_delegate.rs b/codex-rs/core/src/codex_delegate.rs index 8af52b87fb..aa8bd2074f 100644 --- a/codex-rs/core/src/codex_delegate.rs +++ b/codex-rs/core/src/codex_delegate.rs @@ -30,6 +30,7 @@ use tokio::time::timeout; use tokio_util::sync::CancellationToken; use crate::config::Config; +use crate::environment_selection::ResolvedEnvironmentSelections; use crate::guardian::GuardianApprovalRequest; use crate::guardian::new_guardian_review_id; use crate::guardian::routes_approval_to_guardian; @@ -47,7 +48,6 @@ use crate::session::SUBMISSION_CHANNEL_CAPACITY; use crate::session::emit_subagent_session_started; use crate::session::session::Session; use crate::session::turn_context::TurnContext; -use crate::session::turn_context::TurnEnvironment; use codex_login::AuthManager; use codex_models_manager::manager::SharedModelsManager; use codex_protocol::error::CodexErr; @@ -94,12 +94,9 @@ pub(crate) async fn run_codex_thread_interactive( inherited_exec_policy: Some(Arc::clone(&parent_session.services.exec_policy)), parent_rollout_thread_trace: codex_rollout_trace::ThreadTraceContext::disabled(), parent_trace: None, - environments: parent_ctx - .environments - .iter() - .map(TurnEnvironment::selection) - .collect(), - resolved_environments: None, + environment_selections: ResolvedEnvironmentSelections { + turn_environments: parent_ctx.environments.clone(), + }, analytics_events_client: Some(parent_session.services.analytics_events_client.clone()), thread_store: Arc::clone(&parent_session.services.thread_store), })) diff --git a/codex-rs/core/src/session/mod.rs b/codex-rs/core/src/session/mod.rs index 0e2f9f4f82..fb95c8d4ae 100644 --- a/codex-rs/core/src/session/mod.rs +++ b/codex-rs/core/src/session/mod.rs @@ -31,7 +31,6 @@ use crate::context::PermissionsInstructions; use crate::context::PersonalitySpecInstructions; use crate::default_skill_metadata_budget; use crate::environment_selection::ResolvedEnvironmentSelections; -use crate::environment_selection::resolve_environment_selections; use crate::exec_policy::ExecPolicyManager; use crate::installation_id::resolve_installation_id; use crate::parse_turn_item; @@ -113,7 +112,6 @@ use codex_protocol::protocol::SubAgentSource; use codex_protocol::protocol::TurnAbortReason; use codex_protocol::protocol::TurnContextItem; use codex_protocol::protocol::TurnContextNetworkItem; -use codex_protocol::protocol::TurnEnvironmentSelection; use codex_protocol::protocol::W3cTraceContext; use codex_protocol::request_permissions::PermissionGrantScope; use codex_protocol::request_permissions::RequestPermissionProfile; @@ -406,8 +404,7 @@ pub(crate) struct CodexSpawnArgs { pub(crate) parent_rollout_thread_trace: ThreadTraceContext, pub(crate) user_shell_override: Option, pub(crate) parent_trace: Option, - pub(crate) environments: Vec, - pub(crate) resolved_environments: Option, + pub(crate) environment_selections: ResolvedEnvironmentSelections, pub(crate) analytics_events_client: Option, pub(crate) thread_store: Arc, } @@ -464,20 +461,15 @@ impl Codex { inherited_exec_policy, parent_rollout_thread_trace, parent_trace: _, - environments, - resolved_environments, + environment_selections, analytics_events_client, thread_store, } = args; let (tx_sub, rx_sub) = async_channel::bounded(SUBMISSION_CHANNEL_CAPACITY); let (tx_event, rx_event) = async_channel::unbounded(); - let resolved_environments = match resolved_environments { - Some(resolved_environments) => resolved_environments, - None => resolve_environment_selections(environment_manager.as_ref(), &environments)?, - }; - config.cwd = resolved_environments.primary_cwd_or_fallback(&config.cwd); + config.cwd = environment_selections.primary_cwd_or_fallback(&config.cwd); let load_config = config.clone(); - let fs = resolved_environments.primary_filesystem(); + let fs = environment_selections.primary_filesystem(); let plugins_input = load_config.plugins_config_input(); let plugin_outcome = plugins_manager.plugins_for_config(&plugins_input).await; let effective_skill_roots = plugin_outcome.effective_skill_roots(); @@ -500,7 +492,7 @@ impl Codex { let _ = config.features.disable(Feature::Collab); } - let primary_environment = resolved_environments.primary_environment_backend(); + let primary_environment = environment_selections.primary_environment_backend(); let user_instructions = AgentsMdManager::new(&load_config) .user_instructions(primary_environment.as_deref()) .await; @@ -614,7 +606,11 @@ impl Codex { cwd: config.cwd.clone(), codex_home: config.codex_home.clone(), thread_name: None, - environments, + environments: environment_selections + .turn_environments + .iter() + .map(|environment| environment.selection()) + .collect(), original_config_do_not_use: Arc::clone(&config), metrics_service_name, app_server_client_name: None, diff --git a/codex-rs/core/src/session/tests/guardian_tests.rs b/codex-rs/core/src/session/tests/guardian_tests.rs index 0c229f246d..5e93775eae 100644 --- a/codex-rs/core/src/session/tests/guardian_tests.rs +++ b/codex-rs/core/src/session/tests/guardian_tests.rs @@ -1,5 +1,6 @@ use super::*; use crate::compact::InitialContextInjection; +use crate::environment_selection::ResolvedEnvironmentSelections; use crate::exec::ExecCapturePolicy; use crate::exec::ExecParams; use crate::exec_policy::ExecPolicyManager; @@ -754,8 +755,9 @@ async fn guardian_subagent_does_not_inherit_parent_exec_policy_rules() { parent_rollout_thread_trace: codex_rollout_trace::ThreadTraceContext::disabled(), user_shell_override: None, parent_trace: None, - environments: Vec::new(), - resolved_environments: None, + environment_selections: ResolvedEnvironmentSelections { + turn_environments: Vec::new(), + }, analytics_events_client: None, thread_store, }) diff --git a/codex-rs/core/src/thread_manager.rs b/codex-rs/core/src/thread_manager.rs index 2102a055a5..7df9a79c6d 100644 --- a/codex-rs/core/src/thread_manager.rs +++ b/codex-rs/core/src/thread_manager.rs @@ -1072,12 +1072,12 @@ impl ThreadManagerState { user_shell_override: Option, ) -> CodexResult { let is_resumed_thread = matches!(&initial_history, InitialHistory::Resumed(_)); - let resolved_environments = + let environment_selections = resolve_environment_selections(self.environment_manager.as_ref(), &environments)?; - let effective_cwd = resolved_environments.primary_cwd_or_fallback(&config.cwd); + let effective_cwd = environment_selections.primary_cwd_or_fallback(&config.cwd); let mut load_config = config.clone(); load_config.cwd = effective_cwd; - let watch_registration = match resolved_environments.primary_environment() { + let watch_registration = match environment_selections.primary_environment() { Some(turn_environment) if !turn_environment.environment.is_remote() => { self.skills_watcher .register_config( @@ -1116,8 +1116,7 @@ impl ThreadManagerState { parent_rollout_thread_trace, user_shell_override, parent_trace, - environments, - resolved_environments: Some(resolved_environments), + environment_selections, analytics_events_client: self.analytics_events_client.clone(), thread_store, })