Skip to content

Commit e1ec9e6

Browse files
starr-openaicodex
andauthored
Add environment provider snapshot (#20058)
## Summary - Change `EnvironmentProvider` to return concrete `Environment` instances instead of `EnvironmentConfigurations`. - Make `DefaultEnvironmentProvider` provide the provider-visible `local` environment plus optional `remote` environment from `CODEX_EXEC_SERVER_URL`. - Keep `EnvironmentManager` as the concrete cache while exposing its own explicit local environment for `local_environment()` fallback paths. ## Validation - `just fmt` - `git diff --check` --------- Co-authored-by: Codex <noreply@openai.com>
1 parent 6f328d5 commit e1ec9e6

14 files changed

Lines changed: 440 additions & 171 deletions

File tree

codex-rs/app-server-client/src/lib.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2029,14 +2029,17 @@ mod tests {
20292029
#[tokio::test]
20302030
async fn runtime_start_args_forward_environment_manager() {
20312031
let config = Arc::new(build_test_config().await);
2032-
let environment_manager = Arc::new(EnvironmentManager::new(EnvironmentManagerArgs {
2033-
exec_server_url: Some("ws://127.0.0.1:8765".to_string()),
2034-
local_runtime_paths: ExecServerRuntimePaths::new(
2035-
std::env::current_exe().expect("current exe"),
2036-
/*codex_linux_sandbox_exe*/ None,
2032+
let environment_manager = Arc::new(
2033+
EnvironmentManager::create_for_tests(
2034+
Some("ws://127.0.0.1:8765".to_string()),
2035+
ExecServerRuntimePaths::new(
2036+
std::env::current_exe().expect("current exe"),
2037+
/*codex_linux_sandbox_exe*/ None,
2038+
)
2039+
.expect("runtime paths"),
20372040
)
2038-
.expect("runtime paths"),
2039-
}));
2041+
.await,
2042+
);
20402043

20412044
let runtime_args = InProcessClientStartArgs {
20422045
arg0_paths: Arg0DispatchPaths::default(),

codex-rs/app-server/src/lib.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -418,12 +418,15 @@ pub async fn run_main_with_transport_options(
418418
auth: AppServerWebsocketAuthSettings,
419419
runtime_options: AppServerRuntimeOptions,
420420
) -> IoResult<()> {
421-
let environment_manager = Arc::new(EnvironmentManager::new(EnvironmentManagerArgs::from_env(
422-
ExecServerRuntimePaths::from_optional_paths(
423-
arg0_paths.codex_self_exe.clone(),
424-
arg0_paths.codex_linux_sandbox_exe.clone(),
425-
)?,
426-
)));
421+
let environment_manager = Arc::new(
422+
EnvironmentManager::new(EnvironmentManagerArgs::new(
423+
ExecServerRuntimePaths::from_optional_paths(
424+
arg0_paths.codex_self_exe.clone(),
425+
arg0_paths.codex_linux_sandbox_exe.clone(),
426+
)?,
427+
))
428+
.await,
429+
);
427430
let (transport_event_tx, mut transport_event_rx) =
428431
mpsc::channel::<TransportEvent>(CHANNEL_CAPACITY);
429432
let (outgoing_tx, mut outgoing_rx) = mpsc::channel::<OutgoingEnvelope>(CHANNEL_CAPACITY);

codex-rs/core/src/connectors.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ pub async fn list_accessible_connectors_from_mcp_tools_with_options_and_status(
201201
config.codex_linux_sandbox_exe.clone(),
202202
)?;
203203
let environment_manager =
204-
EnvironmentManager::new(EnvironmentManagerArgs::from_env(local_runtime_paths));
204+
EnvironmentManager::new(EnvironmentManagerArgs::new(local_runtime_paths)).await;
205205
list_accessible_connectors_from_mcp_tools_with_environment_manager(
206206
config,
207207
force_refetch,

codex-rs/core/src/environment_selection.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ pub(crate) fn selected_primary_environment(
6161

6262
#[cfg(test)]
6363
mod tests {
64-
use codex_exec_server::EnvironmentManagerArgs;
6564
use codex_exec_server::ExecServerRuntimePaths;
6665
use codex_exec_server::REMOTE_ENVIRONMENT_ID;
6766
use codex_protocol::protocol::TurnEnvironmentSelection;
@@ -81,10 +80,11 @@ mod tests {
8180
#[tokio::test]
8281
async fn default_thread_environment_selections_use_manager_default_id() {
8382
let cwd = AbsolutePathBuf::current_dir().expect("cwd");
84-
let manager = EnvironmentManager::new(EnvironmentManagerArgs {
85-
exec_server_url: Some("ws://127.0.0.1:8765".to_string()),
86-
local_runtime_paths: test_runtime_paths(),
87-
});
83+
let manager = EnvironmentManager::create_for_tests(
84+
Some("ws://127.0.0.1:8765".to_string()),
85+
test_runtime_paths(),
86+
)
87+
.await;
8888

8989
assert_eq!(
9090
default_thread_environment_selections(&manager, &cwd),
@@ -98,10 +98,7 @@ mod tests {
9898
#[tokio::test]
9999
async fn default_thread_environment_selections_empty_when_default_disabled() {
100100
let cwd = AbsolutePathBuf::current_dir().expect("cwd");
101-
let manager = EnvironmentManager::new(EnvironmentManagerArgs {
102-
exec_server_url: Some("none".to_string()),
103-
local_runtime_paths: test_runtime_paths(),
104-
});
101+
let manager = EnvironmentManager::disabled_for_tests(test_runtime_paths());
105102

106103
assert_eq!(
107104
default_thread_environment_selections(&manager, &cwd),

codex-rs/core/src/prompt_debug.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,7 @@ pub async fn build_prompt_input(
4545
.features
4646
.enabled(Feature::DefaultModeRequestUserInput),
4747
},
48-
Arc::new(EnvironmentManager::new(EnvironmentManagerArgs::from_env(
49-
local_runtime_paths,
50-
))),
48+
Arc::new(EnvironmentManager::new(EnvironmentManagerArgs::new(local_runtime_paths)).await),
5149
/*analytics_events_client*/ None,
5250
);
5351
let thread = thread_manager.start_thread(config).await?;

codex-rs/core/src/thread_manager_tests.rs

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -47,20 +47,6 @@ fn assistant_msg(text: &str) -> ResponseItem {
4747
}
4848
}
4949

50-
fn disabled_environment_manager_for_tests() -> Arc<codex_exec_server::EnvironmentManager> {
51-
let runtime_paths = codex_exec_server::ExecServerRuntimePaths::new(
52-
std::env::current_exe().expect("current exe path"),
53-
/*codex_linux_sandbox_exe*/ None,
54-
)
55-
.expect("runtime paths");
56-
Arc::new(codex_exec_server::EnvironmentManager::new(
57-
codex_exec_server::EnvironmentManagerArgs {
58-
exec_server_url: Some("none".to_string()),
59-
local_runtime_paths: runtime_paths,
60-
},
61-
))
62-
}
63-
6450
fn contextual_user_interrupted_marker() -> ResponseItem {
6551
interrupted_turn_history_marker(InterruptedTurnHistoryMarker::ContextualUser)
6652
.expect("contextual-user interrupted marker should be enabled")
@@ -307,11 +293,23 @@ async fn start_thread_accepts_explicit_environment_when_default_environment_is_d
307293
config.cwd = config.codex_home.abs();
308294
std::fs::create_dir_all(&config.codex_home).expect("create codex home");
309295

296+
let runtime_paths = codex_exec_server::ExecServerRuntimePaths::new(
297+
std::env::current_exe().expect("current exe path"),
298+
/*codex_linux_sandbox_exe*/ None,
299+
)
300+
.expect("runtime paths");
301+
let environment_manager = Arc::new(
302+
codex_exec_server::EnvironmentManager::create_for_tests(
303+
Some("none".to_string()),
304+
runtime_paths,
305+
)
306+
.await,
307+
);
310308
let manager = ThreadManager::with_models_provider_and_home_for_tests(
311309
CodexAuth::from_api_key("dummy"),
312310
config.model_provider.clone(),
313311
config.codex_home.to_path_buf(),
314-
disabled_environment_manager_for_tests(),
312+
environment_manager,
315313
);
316314

317315
let thread = manager

codex-rs/core/tests/common/test_codex.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -384,15 +384,17 @@ impl TestCodexBuilder {
384384
.exec_server_url
385385
.clone()
386386
.or_else(|| test_env.exec_server_url().map(str::to_owned));
387-
let environment_manager = Arc::new(codex_exec_server::EnvironmentManager::new(
388-
codex_exec_server::EnvironmentManagerArgs {
387+
let local_runtime_paths = codex_exec_server::ExecServerRuntimePaths::new(
388+
std::env::current_exe()?,
389+
/*codex_linux_sandbox_exe*/ None,
390+
)?;
391+
let environment_manager = Arc::new(
392+
codex_exec_server::EnvironmentManager::create_for_tests(
389393
exec_server_url,
390-
local_runtime_paths: codex_exec_server::ExecServerRuntimePaths::new(
391-
std::env::current_exe()?,
392-
/*codex_linux_sandbox_exe*/ None,
393-
)?,
394-
},
395-
));
394+
local_runtime_paths,
395+
)
396+
.await,
397+
);
396398
let file_system = test_env.environment().get_filesystem();
397399
let mut workspace_setups = vec![];
398400
swap(&mut self.workspace_setups, &mut workspace_setups);

codex-rs/core/tests/suite/skills.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -240,14 +240,11 @@ async fn list_skills_skips_cwd_roots_when_environment_disabled() -> Result<()> {
240240
codex_core::test_support::auth_manager_from_auth(CodexAuth::from_api_key("dummy")),
241241
SessionSource::Exec,
242242
CollaborationModesConfig::default(),
243-
Arc::new(EnvironmentManager::new(
244-
codex_exec_server::EnvironmentManagerArgs {
245-
exec_server_url: Some("none".to_string()),
246-
local_runtime_paths: ExecServerRuntimePaths::new(
247-
std::env::current_exe()?,
248-
/*codex_linux_sandbox_exe*/ None,
249-
)?,
250-
},
243+
Arc::new(EnvironmentManager::disabled_for_tests(
244+
ExecServerRuntimePaths::new(
245+
std::env::current_exe()?,
246+
/*codex_linux_sandbox_exe*/ None,
247+
)?,
251248
)),
252249
/*analytics_events_client*/ None,
253250
);

0 commit comments

Comments
 (0)