mirror of
https://github.com/openai/codex.git
synced 2026-10-15 16:48:52 +00:00
Expose current environment selections for a running turn (#47970)
## Why `active_turn_environment_selections()` returns the selections captured at turn start, so it does not reflect later environment settings updates. ## What changed Add `CodexThread::current_turn_environment_selections(expected_turn_id)` to read the running turn's current selections, including environments that are still starting or have failed. Return `None` when the requested turn is no longer active or has been cancelled. ## Testing Add a regression test covering selection updates, mismatched turn IDs, and completed turns, while verifying that the initial selection snapshot remains unchanged. GitOrigin-RevId: bb526a686d549209142150ffde99ad1444add205
This commit is contained in:
@@ -546,6 +546,20 @@ impl CodexThread {
|
||||
Some(task.turn_context.initial_environments.all_selections())
|
||||
}
|
||||
|
||||
/// Returns the named running turn's current selections, including environments that are
|
||||
/// still starting or have failed. Returns `None` if that turn is no longer running.
|
||||
pub async fn current_turn_environment_selections(
|
||||
&self,
|
||||
expected_turn_id: &str,
|
||||
) -> Option<Vec<TurnEnvironmentSelection>> {
|
||||
let active = self.session.active_turn.lock().await;
|
||||
let task = active.as_ref()?.task.as_ref()?;
|
||||
if task.turn_context.sub_id != expected_turn_id || task.cancellation_token.is_cancelled() {
|
||||
return None;
|
||||
}
|
||||
Some(self.session.services.turn_environments.selections())
|
||||
}
|
||||
|
||||
/// Captures a regular turn only after its input is recorded. The caller must flush the rollout.
|
||||
pub async fn interrupted_turn(
|
||||
&self,
|
||||
|
||||
@@ -10,6 +10,64 @@ use core_test_support::submit_thread_settings;
|
||||
use core_test_support::test_codex::environment_config_for_selection;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn current_turn_environment_selections_follow_active_updates() -> Result<()> {
|
||||
skip_if_no_network!(Ok(()));
|
||||
|
||||
let server = start_mock_server().await;
|
||||
mount_sse_sequence(
|
||||
&server,
|
||||
vec![paused_response("first", "pause"), sse_completed("second")],
|
||||
)
|
||||
.await;
|
||||
let test = step_settings_test().build_with_auto_env(&server).await?;
|
||||
let thread = &test.codex;
|
||||
let turn_id = start_paused_turn(thread).await?.turn_id;
|
||||
let initial = thread
|
||||
.active_turn_environment_selections()
|
||||
.await
|
||||
.expect("running turn");
|
||||
assert_eq!(initial.len(), 1);
|
||||
assert_eq!(
|
||||
thread.current_turn_environment_selections(&turn_id).await,
|
||||
Some(initial.clone())
|
||||
);
|
||||
assert_eq!(
|
||||
thread
|
||||
.current_turn_environment_selections("other-turn")
|
||||
.await,
|
||||
None
|
||||
);
|
||||
|
||||
for environments in [vec![], initial.clone()] {
|
||||
apply_turn_settings(
|
||||
thread,
|
||||
&turn_id,
|
||||
TurnSettingsUpdate {
|
||||
environments: Some(environments.clone()),
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
assert_eq!(
|
||||
thread.current_turn_environment_selections(&turn_id).await,
|
||||
Some(environments)
|
||||
);
|
||||
assert_eq!(
|
||||
thread.active_turn_environment_selections().await,
|
||||
Some(initial.clone())
|
||||
);
|
||||
}
|
||||
|
||||
answer_paused_turn(thread, &turn_id).await?;
|
||||
wait_for_event(thread, |event| matches!(event, EventMsg::TurnComplete(_))).await;
|
||||
assert_eq!(
|
||||
thread.current_turn_environment_selections(&turn_id).await,
|
||||
None
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn model_update_preserves_active_environment_and_next_turn_uses_new_selection() -> Result<()>
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user