Expose environment status through app-server (#32920)

## What changed

- Add the experimental `environment/status` request for inspecting a configured environment without starting or reconnecting it.
- Report `ready`, `pending`, `disconnected`, or `unknown`, including error details for disconnected and unknown environments.
- Probe ready remote environments over their existing exec-server connection.

## Testing

- Add an app-server integration test covering local and remote ready, pending, disconnected, and unknown environments.

GitOrigin-RevId: 397bba603aa9e0b59008ee6cb7cbde46e357652c
This commit is contained in:
Adam Perry @ OpenAI
2026-07-14 01:49:16 +00:00
committed by copyberry
parent 80c6cd3014
commit f96cf4d1c3
10 changed files with 301 additions and 13 deletions
@@ -966,6 +966,9 @@ impl MessageProcessor {
ClientRequest::EnvironmentInfo { params, .. } => {
self.environment_processor.environment_info(params).await
}
ClientRequest::EnvironmentStatus { params, .. } => {
self.environment_processor.environment_status(params).await
}
ClientRequest::FsReadFile { params, .. } => self
.fs_processor
.read_file(params)
@@ -64,6 +64,9 @@ use codex_app_server_protocol::EnvironmentAddResponse;
use codex_app_server_protocol::EnvironmentInfoParams;
use codex_app_server_protocol::EnvironmentInfoResponse;
use codex_app_server_protocol::EnvironmentShellInfo;
use codex_app_server_protocol::EnvironmentStatusKind;
use codex_app_server_protocol::EnvironmentStatusParams;
use codex_app_server_protocol::EnvironmentStatusResponse;
use codex_app_server_protocol::ExperimentalFeature as ApiExperimentalFeature;
use codex_app_server_protocol::ExperimentalFeatureListParams;
use codex_app_server_protocol::ExperimentalFeatureListResponse;
@@ -368,6 +371,7 @@ use codex_core_plugins::remote::RemotePluginShareContext as RemoteCatalogPluginS
use codex_core_plugins::remote::RemotePluginShareSummary as RemoteCatalogPluginShareSummary;
use codex_core_plugins::remote::RemotePluginSummary as RemoteCatalogPluginSummary;
use codex_exec_server::EnvironmentManager;
use codex_exec_server::EnvironmentObservedStatus;
use codex_exec_server::LOCAL_ENVIRONMENT_ID;
use codex_exec_server::LOCAL_FS;
use codex_features::FEATURES;
@@ -52,4 +52,27 @@ impl EnvironmentRequestProcessor {
.into(),
))
}
pub(crate) async fn environment_status(
&self,
params: EnvironmentStatusParams,
) -> Result<Option<ClientResponsePayload>, JSONRPCErrorError> {
let environment_id = params.environment_id;
let (status, error) = match self
.environment_manager
.get_environment_status(&environment_id)
.await
{
Some(EnvironmentObservedStatus::Ready) => (EnvironmentStatusKind::Ready, None),
Some(EnvironmentObservedStatus::Pending) => (EnvironmentStatusKind::Pending, None),
Some(EnvironmentObservedStatus::Disconnected { error }) => {
(EnvironmentStatusKind::Disconnected, Some(error))
}
None => (
EnvironmentStatusKind::Unknown,
Some(format!("unknown environment id `{environment_id}`")),
),
};
Ok(Some(EnvironmentStatusResponse { status, error }.into()))
}
}