Surface multi-environment choices in environment context (#20646)

## Why
The model needs a way to see which environments are available during a
multi-environment turn without changing the legacy single-environment
prompt surface or pulling replay/persistence changes into the same
review.

## Stack
1. https://github.com/openai/codex/pull/20646 - `EnvironmentContext`
rendering for selected environments (this PR)
2. https://github.com/openai/codex/pull/20669 - selected-environment
ownership and tool config prep
3. https://github.com/openai/codex/pull/20647 - process-tool
`environment_id` routing

## What Changed
- extend `environment_context` so multi-environment turns render an
`<environments>` block with the selected environment ids and cwd values
- keep zero- and single-environment turns on the existing cwd-only
render path
- keep replay and persistence paths on the legacy surface for now so
this PR stays scoped to live prompt rendering
- add focused coverage in
`codex-rs/core/src/context/environment_context_tests.rs`

## Testing
- CI

---------

Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
starr-openai
2026-05-01 22:11:06 +00:00
committed by GitHub
co-authored by Codex
parent d55479488e
commit 2952beb009
9 changed files with 248 additions and 76 deletions
+1 -2
View File
@@ -2534,7 +2534,6 @@ impl Session {
) -> Vec<ResponseItem> {
let mut developer_sections = Vec::<String>::with_capacity(8);
let mut contextual_user_sections = Vec::<String>::with_capacity(2);
let shell = self.user_shell();
let (
reference_context_item,
previous_turn_settings,
@@ -2695,7 +2694,7 @@ impl Session {
.format_environment_context_subagents(self.conversation_id)
.await;
contextual_user_sections.push(
crate::context::EnvironmentContext::from_turn_context(turn_context, shell.as_ref())
crate::context::EnvironmentContext::from_turn_context(turn_context)
.with_subagents(subagents)
.render(),
);
+2
View File
@@ -2949,6 +2949,7 @@ fn turn_environments_for_tests(
environment_id: codex_exec_server::LOCAL_ENVIRONMENT_ID.to_string(),
environment: Arc::clone(environment),
cwd: cwd.clone(),
shell: "bash".to_string(),
}]
}
@@ -4488,6 +4489,7 @@ async fn primary_environment_uses_first_turn_environment() {
environment_id: "second".to_string(),
environment: Arc::clone(&first_environment.environment),
cwd: second_cwd.clone(),
shell: first_environment.shell.clone(),
});
assert_eq!(
@@ -34,6 +34,7 @@ pub(crate) struct TurnEnvironment {
pub(crate) environment_id: String,
pub(crate) environment: Arc<Environment>,
pub(crate) cwd: AbsolutePathBuf,
pub(crate) shell: String,
}
impl TurnEnvironment {