Add cloud executor registration to exec-server (#19575)

## Summary
This PR adds the first `codex-rs` milestone for remote-exec e2e: a local
`codex exec-server` can now register itself with
`codex-cloud-environments` and attach to the returned rendezvous
websocket.

At a high level, `codex exec-server --cloud ...` now:
- loads ChatGPT auth from normal Codex config
- registers an executor with `codex-cloud-environments`
- receives a signed rendezvous websocket URL
- serves the existing exec-server JSON-RPC protocol over that websocket

## What Changed
- Added `--cloud`, `--cloud-base-url`, `--cloud-environment-id`, and
`--cloud-name` to `codex exec-server`
- Added a new `exec-server/src/cloud.rs` module that handles:
  - registration requests
  - auth/header setup
  - bounded auth retry on `401/403`
  - reconnect/backoff after websocket disconnects
- Reused the existing `ConnectionProcessor` / `ExecServerHandler` path
so cloud mode serves the same exec/filesystem RPC surface as local
websocket mode
- Added cloud-specific error variants and minimal docs for the new mode

## Testing
Manual e2e test that fully goes through exec server flow with our codex
cloud agent as orchestrator
This commit is contained in:
Michael Zeng
2026-05-05 15:01:48 -07:00
committed by GitHub
Unverified
parent 7e310bc7f3
commit d0f9d5eba2
8 changed files with 452 additions and 8 deletions
+12
View File
@@ -254,6 +254,18 @@ pub enum ExecServerError {
Protocol(String),
#[error("exec-server rejected request ({code}): {message}")]
Server { code: i64, message: String },
#[error("executor registry request failed ({status}{code_suffix}): {message}", code_suffix = .code.as_ref().map(|code| format!(", {code}")).unwrap_or_default())]
ExecutorRegistryHttp {
status: reqwest::StatusCode,
code: Option<String>,
message: String,
},
#[error("executor registry configuration error: {0}")]
ExecutorRegistryConfig(String),
#[error("executor registry authentication error: {0}")]
ExecutorRegistryAuth(String),
#[error("executor registry request failed: {0}")]
ExecutorRegistryRequest(#[from] reqwest::Error),
}
impl ExecServerClient {