Files
codex/codex-rs/app-server/src/code_mode_host.rs
Channing Conger f61b51ddd9 Support remote code-mode hosts in app-server (#35098)
## What changed

- Add `--code-mode-host ws://...` and `wss://...` support to `codex app-server`, gated by the `code_mode_host` feature. When omitted, app-server continues to start a local host.
- Share one remote WebSocket connection across the process's threads, using the configured HTTP client's proxy and TLS policy and preserving the existing framed host protocol.
- Reject invalid host URLs, bound WebSocket frame sizes, close connections cleanly, and return an error when a connection exceeds 1,024 pending delegate calls without disconnecting it.

## Testing

- Cover CLI validation, WebSocket protocol execution and shutdown, connection sharing across app-server threads, and delegate-call capacity recovery.

GitOrigin-RevId: 715e82d4d9db1e7e2f91b754a777dcab504e2ae4
2026-07-24 04:37:01 +00:00

49 lines
1.5 KiB
Rust

use clap::Args;
use url::Url;
/// Selects the code-mode host for a single app-server process.
#[derive(Args, Debug, Clone, Default, PartialEq, Eq)]
pub struct AppServerCodeModeHostArgs {
/// Connect to a remote code-mode host instead of starting a local host.
#[arg(
long = "code-mode-host",
value_name = "WS_URL",
value_parser = parse_websocket_url
)]
pub code_mode_host: Option<Url>,
}
/// Process-scoped transport used to reach the code-mode host.
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub enum CodeModeHostTransport {
/// Start and own the default local code-mode host.
#[default]
Local,
/// Share a connection to the specified remote code-mode host.
WebSocket(Url),
}
impl From<AppServerCodeModeHostArgs> for CodeModeHostTransport {
fn from(args: AppServerCodeModeHostArgs) -> Self {
match args.code_mode_host {
Some(url) => Self::WebSocket(url),
None => Self::Local,
}
}
}
fn parse_websocket_url(value: &str) -> Result<Url, String> {
let url = Url::parse(value).map_err(|error| format!("invalid websocket URL: {error}"))?;
if !matches!(url.scheme(), "ws" | "wss") || url.host_str().is_none() {
return Err("code-mode host URL must use ws:// or wss:// with a host".to_string());
}
if url.fragment().is_some() {
return Err("code-mode host URL must not contain a fragment".to_string());
}
Ok(url)
}
#[cfg(test)]
#[path = "code_mode_host_tests.rs"]
mod tests;