mirror of
https://github.com/openai/codex.git
synced 2026-11-13 06:45:07 +00:00
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
This commit is contained in:
1 parent
0dfa778dae
commit
f61b51ddd9
28 files changed
+977
-65
No files matched your search
@@ -516,6 +516,9 @@ struct AppServerCommand {
|
||||
#[command(subcommand)]
|
||||
subcommand: Option<AppServerSubcommand>,
|
||||
|
||||
#[command(flatten)]
|
||||
code_mode_host: codex_app_server::AppServerCodeModeHostArgs,
|
||||
|
||||
/// Error out when config.toml contains fields that are not recognized by this version of Codex.
|
||||
#[arg(long = "strict-config", default_value_t = false)]
|
||||
strict_config: bool,
|
||||
@@ -1099,6 +1102,7 @@ async fn cli_main(
|
||||
Some(Subcommand::AppServer(app_server_cli)) => {
|
||||
let AppServerCommand {
|
||||
subcommand,
|
||||
code_mode_host,
|
||||
strict_config: app_server_strict_config,
|
||||
listen,
|
||||
stdio,
|
||||
@@ -1122,6 +1126,7 @@ async fn cli_main(
|
||||
};
|
||||
let auth = auth.try_into_settings()?;
|
||||
let runtime_options = codex_app_server::AppServerRuntimeOptions {
|
||||
code_mode_host_transport: code_mode_host.into(),
|
||||
remote_control_startup_mode: match (remote_control, remote_control_disabled)
|
||||
{
|
||||
(true, _) => {
|
||||
@@ -3817,6 +3822,50 @@ mod tests {
|
||||
assert!(err.to_string().contains("is empty"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn app_server_code_mode_host_url_parses_independently_of_listen_transport() {
|
||||
let app_server = app_server_from_args(
|
||||
[
|
||||
"codex",
|
||||
"app-server",
|
||||
"--code-mode-host",
|
||||
"wss://example.test/code-mode",
|
||||
"--listen",
|
||||
"ws://127.0.0.1:4500",
|
||||
]
|
||||
.as_ref(),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
app_server.code_mode_host.code_mode_host,
|
||||
Some(
|
||||
url::Url::parse("wss://example.test/code-mode")
|
||||
.expect("test endpoint should parse")
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
app_server.listen,
|
||||
codex_app_server::AppServerTransport::WebSocket {
|
||||
bind_address: "127.0.0.1:4500".parse().expect("valid socket address"),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn app_server_rejects_invalid_code_mode_host_urls() {
|
||||
for endpoint in [
|
||||
"http://127.0.0.1:8765",
|
||||
"ws://",
|
||||
"wss://example.test/code-mode#fragment",
|
||||
] {
|
||||
let error =
|
||||
MultitoolCli::try_parse_from(["codex", "app-server", "--code-mode-host", endpoint])
|
||||
.expect_err("invalid code-mode host endpoint should fail argument parsing");
|
||||
|
||||
assert_eq!(error.kind(), clap::error::ErrorKind::ValueValidation);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn app_server_listen_websocket_url_parses() {
|
||||
let app_server = app_server_from_args(
|
||||
|
||||
Reference in new issue
Block a user