From 97729885d4707a123db31ae80f5fb0eeda6b7706 Mon Sep 17 00:00:00 2001 From: jif Date: Mon, 10 Aug 2026 16:55:47 +0000 Subject: [PATCH] Expose the session ID to shell commands (#37848) ## What changed - Set `CODEX_SESSION_ID` to the shared root-session ID for shell tool calls, unified exec processes, and user shell commands. - Preserve `CODEX_SESSION_ID` when restoring a shell snapshot, alongside the existing runtime-owned environment variables. GitOrigin-RevId: 5228867d25507105c7edf11607a8298958c3b917 --- codex-rs/core/src/exec_env.rs | 7 +++++++ codex-rs/core/src/tasks/user_shell.rs | 2 ++ codex-rs/core/src/tools/handlers/shell/shell_command.rs | 2 ++ codex-rs/core/src/tools/handlers/shell_tests.rs | 2 ++ codex-rs/core/src/tools/runtimes/mod.rs | 2 ++ codex-rs/core/src/unified_exec/process_manager.rs | 2 ++ codex-rs/protocol/src/shell_environment.rs | 1 + 7 files changed, 18 insertions(+) diff --git a/codex-rs/core/src/exec_env.rs b/codex-rs/core/src/exec_env.rs index f4be869d42..4daa29eb0c 100644 --- a/codex-rs/core/src/exec_env.rs +++ b/codex-rs/core/src/exec_env.rs @@ -1,6 +1,7 @@ pub use codex_apply_patch::CODEX_APPLY_PATCH_PRESERVE_LINE_ENDINGS_ENV_VAR; use codex_features::Feature; use codex_features::Features; +use codex_protocol::SessionId; use codex_protocol::ThreadId; #[cfg(test)] use codex_protocol::config_types::EnvironmentVariablePattern; @@ -9,6 +10,7 @@ use codex_protocol::models::ActivePermissionProfile; use codex_protocol::shell_environment; use std::collections::HashMap; +pub use codex_protocol::shell_environment::CODEX_SESSION_ID_ENV_VAR; pub use codex_protocol::shell_environment::CODEX_THREAD_ID_ENV_VAR; /// Informational name of the active permission profile. Child processes can @@ -33,6 +35,11 @@ pub fn create_env( shell_environment::create_env(policy, thread_id.as_deref()) } +/// Exposes the shared root-session identity to model-reachable shell commands. +pub(crate) fn inject_session_id_env(env: &mut HashMap, session_id: SessionId) { + env.insert(CODEX_SESSION_ID_ENV_VAR.to_string(), session_id.to_string()); +} + /// Injects the selected named permission profile into a shell tool's environment. /// /// This is applied after the shell environment policy so the runtime-selected diff --git a/codex-rs/core/src/tasks/user_shell.rs b/codex-rs/core/src/tasks/user_shell.rs index 293320fd7a..d3312c8b46 100644 --- a/codex-rs/core/src/tasks/user_shell.rs +++ b/codex-rs/core/src/tasks/user_shell.rs @@ -15,6 +15,7 @@ use crate::exec::StdoutStream; use crate::exec::execute_exec_request; use crate::exec_env::create_env; use crate::exec_env::inject_apply_patch_env; +use crate::exec_env::inject_session_id_env; use crate::sandboxing::ExecRequest; use crate::session::TurnInput; use crate::session::turn_context::TurnContext; @@ -160,6 +161,7 @@ pub(crate) async fn execute_user_shell_command( &turn_context.config.permissions.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) { strip_managed_proxy_env(&mut exec_env_map); diff --git a/codex-rs/core/src/tools/handlers/shell/shell_command.rs b/codex-rs/core/src/tools/handlers/shell/shell_command.rs index 0346455e5b..18605c1545 100644 --- a/codex-rs/core/src/tools/handlers/shell/shell_command.rs +++ b/codex-rs/core/src/tools/handlers/shell/shell_command.rs @@ -8,6 +8,7 @@ use crate::exec::ExecParams; use crate::exec_env::create_env; use crate::exec_env::inject_apply_patch_env; use crate::exec_env::inject_permission_profile_env; +use crate::exec_env::inject_session_id_env; use crate::function_tool::FunctionCallError; use crate::maybe_emit_implicit_skill_invocation; use crate::session::turn_context::TurnContext; @@ -106,6 +107,7 @@ impl ShellCommandHandler { &turn_context.config.permissions.shell_environment_policy, Some(session.thread_id), ); + inject_session_id_env(&mut env, session.session_id()); inject_apply_patch_env(&mut env, &turn_context.config.features); let active_permission_profile = turn_environment.active_permission_profile(); inject_permission_profile_env(&mut env, active_permission_profile.as_ref()); diff --git a/codex-rs/core/src/tools/handlers/shell_tests.rs b/codex-rs/core/src/tools/handlers/shell_tests.rs index b9e68880f3..cda3f0d3f1 100644 --- a/codex-rs/core/src/tools/handlers/shell_tests.rs +++ b/codex-rs/core/src/tools/handlers/shell_tests.rs @@ -9,6 +9,7 @@ use crate::config::PermissionProfileSnapshot; use crate::exec_env::CODEX_PERMISSION_PROFILE_ENV_VAR; use crate::exec_env::create_env; use crate::exec_env::inject_permission_profile_env; +use crate::exec_env::inject_session_id_env; use crate::sandboxing::SandboxPermissions; use crate::session::step_context::StepContext; use crate::session::tests::make_session_and_context; @@ -125,6 +126,7 @@ async fn shell_command_handler_to_exec_params_uses_selected_environment() { &turn_context.config.permissions.shell_environment_policy, Some(session.thread_id), ); + inject_session_id_env(&mut expected_env, session.session_id()); inject_permission_profile_env(&mut expected_env, Some(&active_permission_profile)); let params = ShellCommandToolCallParams { diff --git a/codex-rs/core/src/tools/runtimes/mod.rs b/codex-rs/core/src/tools/runtimes/mod.rs index e7c109a5b7..045116d7a1 100644 --- a/codex-rs/core/src/tools/runtimes/mod.rs +++ b/codex-rs/core/src/tools/runtimes/mod.rs @@ -5,6 +5,7 @@ Concrete ToolRuntime implementations for specific tools. Each runtime stays small and focused and reuses the orchestrator for approvals + sandbox + retry. */ use crate::exec_env::CODEX_PERMISSION_PROFILE_ENV_VAR; +use crate::exec_env::CODEX_SESSION_ID_ENV_VAR; use crate::exec_env::CODEX_THREAD_ID_ENV_VAR; use crate::sandboxing::SandboxPermissions; use crate::shell::Shell; @@ -269,6 +270,7 @@ pub(crate) fn maybe_wrap_shell_lc_with_snapshot( .collect::(); let mut override_env = explicit_env_overrides.clone(); for key in [ + CODEX_SESSION_ID_ENV_VAR, CODEX_THREAD_ID_ENV_VAR, CODEX_PERMISSION_PROFILE_ENV_VAR, CODEX_APPLY_PATCH_PRESERVE_LINE_ENDINGS_ENV_VAR, diff --git a/codex-rs/core/src/unified_exec/process_manager.rs b/codex-rs/core/src/unified_exec/process_manager.rs index 6a9afc78c1..5fb57600e0 100644 --- a/codex-rs/core/src/unified_exec/process_manager.rs +++ b/codex-rs/core/src/unified_exec/process_manager.rs @@ -18,6 +18,7 @@ use crate::exec_env::CODEX_THREAD_ID_ENV_VAR; use crate::exec_env::create_env; use crate::exec_env::inject_apply_patch_env; use crate::exec_env::inject_permission_profile_env; +use crate::exec_env::inject_session_id_env; use crate::exec_policy::ExecApprovalRequest; use crate::sandboxing::ExecOptions; use crate::sandboxing::ExecRequest; @@ -1160,6 +1161,7 @@ impl UnifiedExecProcessManager { CODEX_THREAD_ID_ENV_VAR.to_string(), context.session.thread_id.to_string(), ); + inject_session_id_env(&mut env, context.session.session_id()); inject_apply_patch_env(&mut env, &turn.config.features); let active_permission_profile = request.turn_environment.active_permission_profile(); inject_permission_profile_env(&mut env, active_permission_profile.as_ref()); diff --git a/codex-rs/protocol/src/shell_environment.rs b/codex-rs/protocol/src/shell_environment.rs index c7ee880d5b..c19a21989e 100644 --- a/codex-rs/protocol/src/shell_environment.rs +++ b/codex-rs/protocol/src/shell_environment.rs @@ -3,6 +3,7 @@ use crate::config_types::ShellEnvironmentPolicy; use crate::config_types::ShellEnvironmentPolicyInherit; use std::collections::HashMap; +pub const CODEX_SESSION_ID_ENV_VAR: &str = "CODEX_SESSION_ID"; pub const CODEX_THREAD_ID_ENV_VAR: &str = "CODEX_THREAD_ID"; pub const OPENAI_FEDERATION_RULE_ID_ENV_VAR: &str = "OPENAI_FEDERATION_RULE_ID"; pub const OPENAI_IDENTITY_TOKEN_FILE_ENV_VAR: &str = "OPENAI_IDENTITY_TOKEN_FILE";