Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions codex-rs/core/src/agents_md_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ fn resolved_local_environments<const N: usize>(
permission_profile: PermissionProfileSnapshot::legacy(
PermissionProfile::read_only(),
),
shell_environment_policy: Default::default(),
selected_capability_roots: Vec::new(),
}),
},
Expand Down
5 changes: 5 additions & 0 deletions codex-rs/core/src/environment_selection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,7 @@ mod tests {
EnvironmentConfig {
allow_login_shell: true,
permission_profile: PermissionProfileSnapshot::legacy(PermissionProfile::read_only()),
shell_environment_policy: Default::default(),
selected_capability_roots: Vec::new(),
}
}
Expand Down Expand Up @@ -957,6 +958,7 @@ url = "ws://127.0.0.1:8765"
ActivePermissionProfile::read_only(),
vec![cwd.join("profile-root")],
),
shell_environment_policy: Default::default(),
selected_capability_roots: Vec::new(),
};
let turn_environments = ThreadEnvironments::new(
Expand Down Expand Up @@ -1158,6 +1160,7 @@ url = "ws://127.0.0.1:8765"
ActivePermissionProfile::read_only(),
vec![cwd.join("profile-root")],
),
shell_environment_policy: Default::default(),
selected_capability_roots: Vec::new(),
};
let cwd = PathUri::from_abs_path(&cwd);
Expand Down Expand Up @@ -1491,6 +1494,7 @@ url = "ws://127.0.0.1:8765"
ActivePermissionProfile::read_only(),
vec![cwd.join("child-profile-root")],
),
shell_environment_policy: Default::default(),
selected_capability_roots: Vec::new(),
};
let environments = ThreadEnvironments::new(
Expand Down Expand Up @@ -1534,6 +1538,7 @@ url = "ws://127.0.0.1:8765"
let parent_owner_config = EnvironmentConfig {
allow_login_shell: false,
permission_profile: PermissionProfileSnapshot::legacy(PermissionProfile::read_only()),
shell_environment_policy: Default::default(),
selected_capability_roots: vec![root("parent-root")],
};
let mut owner_selection = selection.clone();
Expand Down
1 change: 1 addition & 0 deletions codex-rs/core/src/mcp_tool_call_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1120,6 +1120,7 @@ async fn mcp_sandbox_cwd_uses_matching_server_environment_uri() -> anyhow::Resul
.permissions
.permission_profile_state()
.snapshot(),
shell_environment_policy: Default::default(),
selected_capability_roots: Vec::new(),
}),
},
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/core/src/session/environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ impl Session {
self.mark_mcp_runtime_dirty();
self.services.turn_environments.update_selections(
&environments,
&state.session_configuration.turn_environment_config(),
&state.session_configuration.inferred_environment_config(),
);
Ok(())
}
Expand Down
8 changes: 6 additions & 2 deletions codex-rs/core/src/session/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,8 @@ impl Session {
approval_policy: config.permissions.approval_policy.clone(),
approvals_reviewer: config.approvals_reviewer,
permission_profile_state: session_permission_profile_state_from_config(&config)?,
allow_login_shell: config.permissions.allow_login_shell,
shell_environment_policy: config.permissions.shell_environment_policy.clone(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&config),
legacy_fallback_cwd: config.cwd.clone(),
codex_home: config.codex_home.clone(),
Expand Down Expand Up @@ -1596,12 +1598,14 @@ impl Session {
if mcp_inputs_changed {
self.mark_mcp_runtime_dirty();
}
let environment_config = updated.turn_environment_config();
let environment_config = updated.inferred_environment_config();
if let Some(environments) = &updates.environments {
self.services
.turn_environments
.update_selections(&environments.environments, &environment_config);
} else if state.session_configuration.turn_environment_config() != environment_config {
} else if state.session_configuration.inferred_environment_config()
!= environment_config
{
self.services
.turn_environments
.update_thread_config(&environment_config);
Expand Down
15 changes: 8 additions & 7 deletions codex-rs/core/src/session/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use codex_protocol::SessionId;
use codex_protocol::capabilities::SelectedCapabilityRoot;
use codex_protocol::config_types::SERVICE_TIER_DEFAULT_REQUEST_VALUE;
use codex_protocol::config_types::ServiceTier;
use codex_protocol::config_types::ShellEnvironmentPolicy;
use codex_protocol::mcp::ClientMcpExtensions;
use codex_protocol::permissions::FileSystemPath;
use codex_protocol::permissions::FileSystemSpecialPath;
Expand Down Expand Up @@ -90,6 +91,8 @@ pub(crate) struct SessionConfiguration {
/// active profile id, and profile-defined workspace roots in sync by using
/// the methods below instead of mutating the fields independently.
pub(super) permission_profile_state: PermissionProfileState,
pub(super) allow_login_shell: bool,
pub(super) shell_environment_policy: ShellEnvironmentPolicy,
pub(super) windows_sandbox_level: WindowsSandboxLevel,

/// Legacy thread cwd used when a turn does not select an environment.
Expand Down Expand Up @@ -136,13 +139,11 @@ impl SessionConfiguration {
&self.permission_profile_state
}

pub(super) fn turn_environment_config(&self) -> EnvironmentConfig {
pub(super) fn inferred_environment_config(&self) -> EnvironmentConfig {
EnvironmentConfig {
allow_login_shell: self
.original_config_do_not_use
.permissions
.allow_login_shell,
allow_login_shell: self.allow_login_shell,
permission_profile: self.permission_profile_state.snapshot(),
shell_environment_policy: self.shell_environment_policy.clone(),
selected_capability_roots: Vec::new(),
}
}
Expand Down Expand Up @@ -1080,14 +1081,14 @@ impl Session {
let turn_environments = Arc::new(ThreadEnvironments::new(
environment_manager,
default_shell.clone(),
session_configuration.turn_environment_config(),
session_configuration.inferred_environment_config(),
shell_snapshot,
inherited_environments.unwrap_or_default(),
config.features.enabled(Feature::DeferredExecutor),
));
turn_environments.update_selections(
environment_selections,
&session_configuration.turn_environment_config(),
&session_configuration.inferred_environment_config(),
);
let resolved_environments = turn_environments.snapshot().await;
let agents_md_manager = Arc::new(AgentsMdManager::new(user_instructions));
Expand Down
24 changes: 20 additions & 4 deletions codex-rs/core/src/session/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4189,6 +4189,8 @@ async fn set_rate_limits_retains_previous_credits() {
approval_policy: config.permissions.approval_policy.clone(),
approvals_reviewer: config.approvals_reviewer,
permission_profile_state: config.permissions.permission_profile_state().clone(),
allow_login_shell: config.permissions.allow_login_shell,
shell_environment_policy: config.permissions.shell_environment_policy.clone(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&config),
legacy_fallback_cwd: config.cwd.clone(),
codex_home: config.codex_home.clone(),
Expand Down Expand Up @@ -4298,6 +4300,8 @@ async fn set_rate_limits_updates_plan_type_when_present() {
approval_policy: config.permissions.approval_policy.clone(),
approvals_reviewer: config.approvals_reviewer,
permission_profile_state: config.permissions.permission_profile_state().clone(),
allow_login_shell: config.permissions.allow_login_shell,
shell_environment_policy: config.permissions.shell_environment_policy.clone(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&config),
legacy_fallback_cwd: config.cwd.clone(),
codex_home: config.codex_home.clone(),
Expand Down Expand Up @@ -4852,6 +4856,8 @@ pub(crate) async fn make_session_configuration_for_tests() -> SessionConfigurati
approval_policy: config.permissions.approval_policy.clone(),
approvals_reviewer: config.approvals_reviewer,
permission_profile_state: config.permissions.permission_profile_state().clone(),
allow_login_shell: config.permissions.allow_login_shell,
shell_environment_policy: config.permissions.shell_environment_policy.clone(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&config),
legacy_fallback_cwd: config.cwd.clone(),
codex_home: config.codex_home.clone(),
Expand Down Expand Up @@ -4963,14 +4969,14 @@ async fn resolved_environments_for_configuration(
let turn_environments = ThreadEnvironments::new(
Arc::clone(&environment_manager),
default_user_shell(),
session_configuration.turn_environment_config(),
session_configuration.inferred_environment_config(),
ShellSnapshot::disabled(),
TurnEnvironmentSnapshot::default(),
/*non_blocking_snapshots*/ false,
);
turn_environments.update_selections(
environment_selections,
&session_configuration.turn_environment_config(),
&session_configuration.inferred_environment_config(),
);
(environment_manager, turn_environments.snapshot().await)
}
Expand Down Expand Up @@ -5641,6 +5647,8 @@ async fn session_new_fails_when_zsh_fork_enabled_without_packaged_zsh() {
approval_policy: config.permissions.approval_policy.clone(),
approvals_reviewer: config.approvals_reviewer,
permission_profile_state: config.permissions.permission_profile_state().clone(),
allow_login_shell: config.permissions.allow_login_shell,
shell_environment_policy: config.permissions.shell_environment_policy.clone(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&config),
legacy_fallback_cwd: config.cwd.clone(),
codex_home: config.codex_home.clone(),
Expand Down Expand Up @@ -5787,6 +5795,8 @@ pub(crate) async fn make_session_and_context() -> (Session, TurnContext) {
approval_policy: config.permissions.approval_policy.clone(),
approvals_reviewer: config.approvals_reviewer,
permission_profile_state: config.permissions.permission_profile_state().clone(),
allow_login_shell: config.permissions.allow_login_shell,
shell_environment_policy: config.permissions.shell_environment_policy.clone(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&config),
legacy_fallback_cwd: config.cwd.clone(),
codex_home: config.codex_home.clone(),
Expand Down Expand Up @@ -5820,7 +5830,7 @@ pub(crate) async fn make_session_and_context() -> (Session, TurnContext) {
let turn_environments = Arc::new(ThreadEnvironments::new(
environment_manager,
default_user_shell(),
session_configuration.turn_environment_config(),
session_configuration.inferred_environment_config(),
ShellSnapshot::disabled(),
resolved_environments,
/*non_blocking_snapshots*/ false,
Expand Down Expand Up @@ -6068,6 +6078,8 @@ async fn make_session_with_config_and_rx(
approval_policy: config.permissions.approval_policy.clone(),
approvals_reviewer: config.approvals_reviewer,
permission_profile_state: config.permissions.permission_profile_state().clone(),
allow_login_shell: config.permissions.allow_login_shell,
shell_environment_policy: config.permissions.shell_environment_policy.clone(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&config),
legacy_fallback_cwd: config.cwd.clone(),
codex_home: config.codex_home.clone(),
Expand Down Expand Up @@ -6187,6 +6199,8 @@ async fn make_session_with_history_source_and_agent_control_and_rx(
approval_policy: config.permissions.approval_policy.clone(),
approvals_reviewer: config.approvals_reviewer,
permission_profile_state: config.permissions.permission_profile_state().clone(),
allow_login_shell: config.permissions.allow_login_shell,
shell_environment_policy: config.permissions.shell_environment_policy.clone(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&config),
legacy_fallback_cwd: config.cwd.clone(),
codex_home: config.codex_home.clone(),
Expand Down Expand Up @@ -7987,6 +8001,8 @@ where
approval_policy: config.permissions.approval_policy.clone(),
approvals_reviewer: config.approvals_reviewer,
permission_profile_state: config.permissions.permission_profile_state().clone(),
allow_login_shell: config.permissions.allow_login_shell,
shell_environment_policy: config.permissions.shell_environment_policy.clone(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&config),
legacy_fallback_cwd: config.cwd.clone(),
codex_home: config.codex_home.clone(),
Expand Down Expand Up @@ -8019,7 +8035,7 @@ where
let turn_environments = Arc::new(ThreadEnvironments::new(
environment_manager,
default_user_shell(),
session_configuration.turn_environment_config(),
session_configuration.inferred_environment_config(),
ShellSnapshot::disabled(),
resolved_turn_environments.clone(),
/*non_blocking_snapshots*/ false,
Expand Down
9 changes: 7 additions & 2 deletions codex-rs/core/src/session/turn_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use codex_file_system::FileSystemSandboxContext;
use codex_model_provider::SharedModelProvider;
use codex_protocol::SessionId;
use codex_protocol::ThreadId;
use codex_protocol::config_types::ShellEnvironmentPolicy;
use codex_protocol::models::AdditionalPermissionProfile;
use codex_protocol::openai_models::MODEL_SPECIALTY_CYBER;
use codex_protocol::openai_models::ModelInfo;
Expand Down Expand Up @@ -66,6 +67,10 @@ impl TurnEnvironment {
config
}

pub(crate) fn shell_environment_policy(&self) -> &ShellEnvironmentPolicy {
&self.config().shell_environment_policy
}

#[cfg(test)]
pub(crate) fn config_mut(&mut self) -> &mut EnvironmentConfig {
let EnvironmentConfigState::Ready(config) = &mut self.selection.config else {
Expand Down Expand Up @@ -712,12 +717,12 @@ impl Session {
previous_permission_profile != next_permission_profile;
let previous_config = notify_config_contributors
.then(|| self.build_effective_session_config(&state.session_configuration));
let environment_config = next.turn_environment_config();
let environment_config = next.inferred_environment_config();
if let Some(environments) = &updates.environments {
self.services
.turn_environments
.update_selections(&environments.environments, &environment_config);
} else if state.session_configuration.turn_environment_config()
} else if state.session_configuration.inferred_environment_config()
!= environment_config
{
self.services
Expand Down
12 changes: 3 additions & 9 deletions codex-rs/core/src/tasks/user_shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,8 @@ pub(crate) async fn execute_user_shell_command(
return;
};
let shell_snapshot_location = turn_environment.shell_snapshot(&cwd);
let mut exec_env_map = create_env(
&turn_context.config.permissions.shell_environment_policy,
Some(session.thread_id),
);
let shell_environment_policy = turn_environment.shell_environment_policy();
let mut exec_env_map = create_env(shell_environment_policy, Some(session.thread_id));
inject_session_id_env(&mut exec_env_map, session.session_id());
inject_apply_patch_env(&mut exec_env_map, &turn_context.config.features);
if exec_env_map.contains_key(PROXY_ACTIVE_ENV_KEY) {
Expand All @@ -171,11 +169,7 @@ pub(crate) async fn execute_user_shell_command(
&display_command,
environment_shell,
shell_snapshot_location.as_ref(),
&turn_context
.config
.permissions
.shell_environment_policy
.r#set,
&shell_environment_policy.r#set,
&mut exec_env_map,
);

Expand Down
7 changes: 1 addition & 6 deletions codex-rs/core/src/tools/handlers/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,7 @@ async fn run_exec_like(args: RunExecLikeArgs) -> Result<FunctionToolOutput, Func

let fs = turn_environment.environment.get_filesystem();

let mut explicit_env_overrides = turn
.config
.permissions
.shell_environment_policy
.r#set
.clone();
let mut explicit_env_overrides = turn_environment.shell_environment_policy().r#set.clone();
let mut env = exec_params.env.clone();
strip_output_env(&mut env);
strip_output_env(&mut explicit_env_overrides);
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/core/src/tools/handlers/shell/shell_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ impl ShellCommandHandler {
let command = Self::base_command(shell, &params.command, use_login_shell);

let mut env = create_env(
&turn_context.config.permissions.shell_environment_policy,
turn_environment.shell_environment_policy(),
Some(session.thread_id),
);
inject_session_id_env(&mut env, session.session_id());
Expand Down
Loading
Loading