mirror of
https://github.com/openai/codex.git
synced 2026-11-13 14:46:14 +00:00
Support pending environment attachment configuration (#38684)
## Why An environment connection can be available before its owner has supplied the configuration for a particular thread attachment. Threads need to start without blocking while ensuring turns do not use that attachment prematurely. ## What changed - Accept `Pending` environment configuration and resolve each attachment only after both its shared executor connection and owner configuration are ready. - Add a `Failed` configuration state and `environment_failed` callback so an owner can fail one thread's attachment without affecting other threads. - Keep pending and failed attachments out of capability-root inspection and turn environments, and allow failed attachments to recover through a ready update. - Apply owner configuration before waking a waiting turn so its permission profile, login-shell policy, capability roots, and tools are immediately consistent. ## Testing Add an integration test covering non-blocking thread startup, independent ready and failed callbacks, waiting-turn resumption, installed capability and tool configuration, and recovery from failure. GitOrigin-RevId: d587e2025d584c867d782d470b18bf5a1a27b76c
This commit is contained in:
1 parent
eb147c0db3
commit
2ca575026c
7 files changed
+378
-85
No files matched your search
@@ -19,12 +19,9 @@ pub(super) fn validate_environment_selections(
|
||||
) -> CodexResult<()> {
|
||||
for selection in selections {
|
||||
match &selection.config {
|
||||
EnvironmentConfigState::FromThread => {}
|
||||
EnvironmentConfigState::Pending => {
|
||||
return Err(CodexErr::InvalidRequest(
|
||||
"pending environment configuration is not supported yet".to_string(),
|
||||
));
|
||||
}
|
||||
EnvironmentConfigState::FromThread
|
||||
| EnvironmentConfigState::Pending
|
||||
| EnvironmentConfigState::Failed(_) => {}
|
||||
EnvironmentConfigState::Ready(config) => {
|
||||
validate_environment_config(selection, config)?;
|
||||
}
|
||||
@@ -74,14 +71,46 @@ impl Session {
|
||||
config: EnvironmentConfig,
|
||||
) -> CodexResult<()> {
|
||||
validate_environment_config(selection, &config)?;
|
||||
self.update_environment_configuration(selection, EnvironmentConfigState::Ready(config))
|
||||
.await
|
||||
}
|
||||
|
||||
// grab session lock so installation can't race w/ thread settings updates
|
||||
let _state = self.state.lock().await;
|
||||
self.services
|
||||
.turn_environments
|
||||
.environment_ready(selection, config)?;
|
||||
// mark mcp runtime for refresh because available capabilities could've changed
|
||||
pub(crate) async fn environment_failed(
|
||||
&self,
|
||||
selection: &TurnEnvironmentSelection,
|
||||
error: String,
|
||||
) -> CodexResult<()> {
|
||||
self.update_environment_configuration(selection, EnvironmentConfigState::Failed(error))
|
||||
.await
|
||||
}
|
||||
|
||||
async fn update_environment_configuration(
|
||||
&self,
|
||||
selection: &TurnEnvironmentSelection,
|
||||
config: EnvironmentConfigState,
|
||||
) -> CodexResult<()> {
|
||||
// Serialize owner callbacks with ordinary thread settings updates.
|
||||
let state = self.state.lock().await;
|
||||
let mut environments = self.services.turn_environments.selections();
|
||||
let Some(environment) = environments.iter_mut().find(|environment| {
|
||||
environment.environment_id == selection.environment_id
|
||||
&& environment.cwd == selection.cwd
|
||||
&& environment.workspace_roots == selection.workspace_roots
|
||||
}) else {
|
||||
return Err(CodexErr::InvalidRequest(format!(
|
||||
"environment `{}` is not selected on this thread with the requested workspace",
|
||||
selection.environment_id
|
||||
)));
|
||||
};
|
||||
|
||||
environment.config = config;
|
||||
|
||||
// Invalidate MCP before installed configuration can wake a waiting turn.
|
||||
self.mark_mcp_runtime_dirty();
|
||||
self.services.turn_environments.update_selections(
|
||||
&environments,
|
||||
&state.session_configuration.turn_environment_config(),
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user