diff --git a/codex-rs/app-server-client/src/lib.rs b/codex-rs/app-server-client/src/lib.rs index 3a5be188df..3b386ff3ce 100644 --- a/codex-rs/app-server-client/src/lib.rs +++ b/codex-rs/app-server-client/src/lib.rs @@ -2094,7 +2094,7 @@ mod tests { let config = Arc::new(build_test_config().await); let environment_manager = Arc::new( EnvironmentManager::create_for_tests( - Some("ws://127.0.0.1:8765/ws".to_string()), + Some("ws://127.0.0.1:8765".to_string()), ExecServerRuntimePaths::new( std::env::current_exe().expect("current exe"), /*codex_linux_sandbox_exe*/ None, diff --git a/codex-rs/app-server-protocol/src/protocol/common.rs b/codex-rs/app-server-protocol/src/protocol/common.rs index 5caa066f08..ae00b08b73 100644 --- a/codex-rs/app-server-protocol/src/protocol/common.rs +++ b/codex-rs/app-server-protocol/src/protocol/common.rs @@ -1808,7 +1808,7 @@ mod tests { request_id: request_id(), params: v2::EnvironmentAddParams { environment_id: "remote-a".to_string(), - exec_server_url: "ws://127.0.0.1:8765/ws".to_string(), + exec_server_url: "ws://127.0.0.1:8765".to_string(), }, }; assert_eq!( @@ -2603,7 +2603,7 @@ mod tests { request_id: RequestId::Integer(9), params: v2::EnvironmentAddParams { environment_id: "remote-a".to_string(), - exec_server_url: "ws://127.0.0.1:8765/ws".to_string(), + exec_server_url: "ws://127.0.0.1:8765".to_string(), }, }; assert_eq!( @@ -2612,7 +2612,7 @@ mod tests { "id": 9, "params": { "environmentId": "remote-a", - "execServerUrl": "ws://127.0.0.1:8765/ws" + "execServerUrl": "ws://127.0.0.1:8765" } }), serde_json::to_value(&request)?, @@ -2898,7 +2898,7 @@ mod tests { request_id: RequestId::Integer(1), params: v2::EnvironmentAddParams { environment_id: "remote-a".to_string(), - exec_server_url: "ws://127.0.0.1:8765/ws".to_string(), + exec_server_url: "ws://127.0.0.1:8765".to_string(), }, }; let reason = crate::experimental_api::ExperimentalApi::experimental_reason(&request); diff --git a/codex-rs/app-server/tests/suite/v2/turn_start.rs b/codex-rs/app-server/tests/suite/v2/turn_start.rs index e152babd10..524b795b81 100644 --- a/codex-rs/app-server/tests/suite/v2/turn_start.rs +++ b/codex-rs/app-server/tests/suite/v2/turn_start.rs @@ -2005,7 +2005,7 @@ async fn turn_start_resolves_sticky_thread_local_environment_and_turn_overrides( r#" [[environments]] id = "remote" -url = "ws://127.0.0.1:1/ws" +url = "ws://127.0.0.1:1" "#, )?; diff --git a/codex-rs/core/src/environment_selection.rs b/codex-rs/core/src/environment_selection.rs index 247e8f507c..89808c27ee 100644 --- a/codex-rs/core/src/environment_selection.rs +++ b/codex-rs/core/src/environment_selection.rs @@ -105,7 +105,7 @@ mod tests { async fn default_thread_environment_selections_use_manager_default_id() { let cwd = AbsolutePathBuf::current_dir().expect("cwd"); let manager = EnvironmentManager::create_for_tests( - Some("ws://127.0.0.1:8765/ws".to_string()), + Some("ws://127.0.0.1:8765".to_string()), test_runtime_paths(), ) .await; @@ -127,7 +127,7 @@ mod tests { r#" [[environments]] id = "remote" -url = "ws://127.0.0.1:8765/ws" +url = "ws://127.0.0.1:8765" "#, ) .expect("write environments.toml"); diff --git a/codex-rs/exec-server/README.md b/codex-rs/exec-server/README.md index e4d8f58932..81664eaca0 100644 --- a/codex-rs/exec-server/README.md +++ b/codex-rs/exec-server/README.md @@ -21,7 +21,7 @@ the wire. The CLI entrypoint supports: -- `ws://IP:PORT` (default bind address; the listener advertises `ws://IP:PORT/ws`) +- `ws://IP:PORT` (default) - `--remote URL --executor-id ID [--name NAME]` Remote mode registers the local exec-server with the executor registry, diff --git a/codex-rs/exec-server/src/environment.rs b/codex-rs/exec-server/src/environment.rs index dd207fc6ea..7e4a3fb056 100644 --- a/codex-rs/exec-server/src/environment.rs +++ b/codex-rs/exec-server/src/environment.rs @@ -506,7 +506,7 @@ mod tests { #[tokio::test] async fn environment_manager_reports_remote_url() { let manager = EnvironmentManager::create_for_tests( - Some("ws://127.0.0.1:8765/ws".to_string()), + Some("ws://127.0.0.1:8765".to_string()), test_runtime_paths(), ) .await; @@ -517,10 +517,7 @@ mod tests { Some(REMOTE_ENVIRONMENT_ID) ); assert!(environment.is_remote()); - assert_eq!( - environment.exec_server_url(), - Some("ws://127.0.0.1:8765/ws") - ); + assert_eq!(environment.exec_server_url(), Some("ws://127.0.0.1:8765")); assert!(Arc::ptr_eq( &environment, &manager @@ -551,7 +548,7 @@ mod tests { snapshot: EnvironmentProviderSnapshot { environments: vec![( REMOTE_ENVIRONMENT_ID.to_string(), - Environment::create_for_tests(Some("ws://127.0.0.1:8765/ws".to_string())) + Environment::create_for_tests(Some("ws://127.0.0.1:8765".to_string())) .expect("remote environment"), )], default: EnvironmentDefault::EnvironmentId(REMOTE_ENVIRONMENT_ID.to_string()), @@ -623,7 +620,7 @@ mod tests { snapshot: EnvironmentProviderSnapshot { environments: vec![( "devbox".to_string(), - Environment::create_for_tests(Some("ws://127.0.0.1:8765/ws".to_string())) + Environment::create_for_tests(Some("ws://127.0.0.1:8765".to_string())) .expect("remote environment"), )], default: EnvironmentDefault::EnvironmentId("devbox".to_string()), @@ -648,7 +645,7 @@ mod tests { snapshot: EnvironmentProviderSnapshot { environments: vec![( "devbox".to_string(), - Environment::create_for_tests(Some("ws://127.0.0.1:8765/ws".to_string())) + Environment::create_for_tests(Some("ws://127.0.0.1:8765".to_string())) .expect("remote environment"), )], default: EnvironmentDefault::Disabled, @@ -675,7 +672,7 @@ mod tests { snapshot: EnvironmentProviderSnapshot { environments: vec![( "devbox".to_string(), - Environment::create_for_tests(Some("ws://127.0.0.1:8765/ws".to_string())) + Environment::create_for_tests(Some("ws://127.0.0.1:8765".to_string())) .expect("remote environment"), )], default: EnvironmentDefault::EnvironmentId("missing".to_string()), @@ -769,29 +766,23 @@ mod tests { let manager = EnvironmentManager::disabled_for_tests(test_runtime_paths()); manager - .upsert_environment( - "executor-a".to_string(), - "ws://127.0.0.1:8765/ws".to_string(), - ) + .upsert_environment("executor-a".to_string(), "ws://127.0.0.1:8765".to_string()) .expect("remote environment"); let first = manager .get_environment("executor-a") .expect("first remote environment"); assert!(first.is_remote()); - assert_eq!(first.exec_server_url(), Some("ws://127.0.0.1:8765/ws")); + assert_eq!(first.exec_server_url(), Some("ws://127.0.0.1:8765")); assert_eq!(manager.default_environment_id(), None); manager - .upsert_environment( - "executor-a".to_string(), - "ws://127.0.0.1:9876/ws".to_string(), - ) + .upsert_environment("executor-a".to_string(), "ws://127.0.0.1:9876".to_string()) .expect("updated remote environment"); let second = manager .get_environment("executor-a") .expect("second remote environment"); assert!(second.is_remote()); - assert_eq!(second.exec_server_url(), Some("ws://127.0.0.1:9876/ws")); + assert_eq!(second.exec_server_url(), Some("ws://127.0.0.1:9876")); assert!(!Arc::ptr_eq(&first, &second)); } diff --git a/codex-rs/exec-server/src/environment_provider.rs b/codex-rs/exec-server/src/environment_provider.rs index 47f0e82b94..7e132ee2b4 100644 --- a/codex-rs/exec-server/src/environment_provider.rs +++ b/codex-rs/exec-server/src/environment_provider.rs @@ -162,7 +162,7 @@ mod tests { #[tokio::test] async fn default_provider_adds_remote_environment_for_websocket_url() { - let provider = DefaultEnvironmentProvider::new(Some("ws://127.0.0.1:8765/ws".to_string())); + let provider = DefaultEnvironmentProvider::new(Some("ws://127.0.0.1:8765".to_string())); let snapshot = provider.snapshot().await.expect("environments"); let EnvironmentProviderSnapshot { environments, @@ -177,7 +177,7 @@ mod tests { assert!(remote_environment.is_remote()); assert_eq!( remote_environment.exec_server_url(), - Some("ws://127.0.0.1:8765/ws") + Some("ws://127.0.0.1:8765") ); assert_eq!( default, @@ -187,14 +187,13 @@ mod tests { #[tokio::test] async fn default_provider_normalizes_exec_server_url() { - let provider = - DefaultEnvironmentProvider::new(Some(" ws://127.0.0.1:8765/ws ".to_string())); + let provider = DefaultEnvironmentProvider::new(Some(" ws://127.0.0.1:8765 ".to_string())); let snapshot = provider.snapshot().await.expect("environments"); let environments: HashMap<_, _> = snapshot.environments.into_iter().collect(); assert_eq!( environments[REMOTE_ENVIRONMENT_ID].exec_server_url(), - Some("ws://127.0.0.1:8765/ws") + Some("ws://127.0.0.1:8765") ); } } diff --git a/codex-rs/exec-server/src/environment_toml.rs b/codex-rs/exec-server/src/environment_toml.rs index 5615960eda..90f4c78262 100644 --- a/codex-rs/exec-server/src/environment_toml.rs +++ b/codex-rs/exec-server/src/environment_toml.rs @@ -333,7 +333,7 @@ mod tests { environments: vec![ EnvironmentToml { id: "devbox".to_string(), - url: Some(" ws://127.0.0.1:8765/ws ".to_string()), + url: Some(" ws://127.0.0.1:8765 ".to_string()), ..Default::default() }, EnvironmentToml { @@ -370,7 +370,7 @@ mod tests { assert!(!environments.contains_key(LOCAL_ENVIRONMENT_ID)); assert_eq!( environments["devbox"].exec_server_url(), - Some("ws://127.0.0.1:8765/ws") + Some("ws://127.0.0.1:8765") ); assert!(environments["ssh-dev"].is_remote()); assert_eq!(environments["ssh-dev"].exec_server_url(), None); @@ -411,7 +411,7 @@ mod tests { ( EnvironmentToml { id: "local".to_string(), - url: Some("ws://127.0.0.1:8765/ws".to_string()), + url: Some("ws://127.0.0.1:8765".to_string()), ..Default::default() }, "environment id `local` is reserved", @@ -419,7 +419,7 @@ mod tests { ( EnvironmentToml { id: " devbox ".to_string(), - url: Some("ws://127.0.0.1:8765/ws".to_string()), + url: Some("ws://127.0.0.1:8765".to_string()), ..Default::default() }, "environment id ` devbox ` must not contain surrounding whitespace", @@ -427,7 +427,7 @@ mod tests { ( EnvironmentToml { id: "dev box".to_string(), - url: Some("ws://127.0.0.1:8765/ws".to_string()), + url: Some("ws://127.0.0.1:8765".to_string()), ..Default::default() }, "environment id `dev box` must contain only ASCII letters, numbers, '-' or '_'", @@ -443,7 +443,7 @@ mod tests { ( EnvironmentToml { id: "devbox".to_string(), - url: Some("ws://127.0.0.1:8765/ws".to_string()), + url: Some("ws://127.0.0.1:8765".to_string()), program: Some("codex".to_string()), ..Default::default() }, @@ -528,7 +528,7 @@ mod tests { environments: vec![ EnvironmentToml { id: "devbox".to_string(), - url: Some("ws://127.0.0.1:8765/ws".to_string()), + url: Some("ws://127.0.0.1:8765".to_string()), connect_timeout_sec: Some(Duration::from_secs(12)), initialize_timeout_sec: Some(Duration::from_secs(34)), ..Default::default() @@ -546,7 +546,7 @@ mod tests { assert_eq!( provider.environments[0].1, ExecServerTransportParams::WebSocketUrl { - websocket_url: "ws://127.0.0.1:8765/ws".to_string(), + websocket_url: "ws://127.0.0.1:8765".to_string(), connect_timeout: Duration::from_secs(12), initialize_timeout: Duration::from_secs(34), } @@ -591,7 +591,7 @@ mod tests { environments: vec![ EnvironmentToml { id: "devbox".to_string(), - url: Some("ws://127.0.0.1:8765/ws".to_string()), + url: Some("ws://127.0.0.1:8765".to_string()), ..Default::default() }, EnvironmentToml { @@ -616,7 +616,7 @@ mod tests { default: None, environments: vec![EnvironmentToml { id: id.clone(), - url: Some("ws://127.0.0.1:8765/ws".to_string()), + url: Some("ws://127.0.0.1:8765".to_string()), ..Default::default() }], }) @@ -655,7 +655,7 @@ default = "ssh-dev" [[environments]] id = "devbox" -url = "ws://127.0.0.1:4512/ws" +url = "ws://127.0.0.1:4512" connect_timeout_sec = 12.0 initialize_timeout_sec = 34.0 @@ -678,7 +678,7 @@ CODEX_LOG = "debug" environments.environments[0], EnvironmentToml { id: "devbox".to_string(), - url: Some("ws://127.0.0.1:4512/ws".to_string()), + url: Some("ws://127.0.0.1:4512".to_string()), connect_timeout_sec: Some(Duration::from_secs(12)), initialize_timeout_sec: Some(Duration::from_secs(34)), ..Default::default() @@ -712,7 +712,7 @@ CODEX_LOG = "debug" r#" [[environments]] id = "devbox" -url = "ws://127.0.0.1:4512/ws" +url = "ws://127.0.0.1:4512" unknown = true "#, "unknown field `unknown`", diff --git a/codex-rs/exec-server/src/server/transport.rs b/codex-rs/exec-server/src/server/transport.rs index a82962c0d6..142fd6266d 100644 --- a/codex-rs/exec-server/src/server/transport.rs +++ b/codex-rs/exec-server/src/server/transport.rs @@ -2,10 +2,8 @@ use axum::Router; use axum::extract::ConnectInfo; use axum::extract::State; use axum::extract::ws::WebSocketUpgrade; -use axum::http::StatusCode; use axum::response::IntoResponse; use axum::routing::any; -use axum::routing::get; use std::io::Write as _; use std::net::SocketAddr; use tokio::io; @@ -116,15 +114,12 @@ async fn run_websocket_listener( let listener = TcpListener::bind(bind_address).await?; let local_addr = listener.local_addr()?; let processor = ConnectionProcessor::new(runtime_paths); - info!("codex-exec-server listening on ws://{local_addr}/ws"); - println!("ws://{local_addr}/ws"); + info!("codex-exec-server listening on ws://{local_addr}"); + println!("ws://{local_addr}"); std::io::stdout().flush()?; let router = Router::new() - .route("/", get(health_check_handler)) - .route("/readyz", get(health_check_handler)) - .route("/healthz", get(health_check_handler)) - .route("/ws", any(websocket_upgrade_handler)) + .route("/", any(websocket_upgrade_handler)) .with_state(ExecServerWebSocketState { processor }); axum::serve( listener, @@ -139,10 +134,6 @@ struct ExecServerWebSocketState { processor: ConnectionProcessor, } -async fn health_check_handler() -> StatusCode { - StatusCode::OK -} - async fn websocket_upgrade_handler( websocket: WebSocketUpgrade, ConnectInfo(peer_addr): ConnectInfo, diff --git a/codex-rs/exec-server/tests/health.rs b/codex-rs/exec-server/tests/health.rs deleted file mode 100644 index b4c2aa59f2..0000000000 --- a/codex-rs/exec-server/tests/health.rs +++ /dev/null @@ -1,24 +0,0 @@ -#![cfg(unix)] - -mod common; - -use common::exec_server::exec_server; -use pretty_assertions::assert_eq; - -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn exec_server_serves_health_checks_alongside_websocket_endpoint() -> anyhow::Result<()> { - let mut server = exec_server().await?; - let http_base_url = server - .websocket_url() - .strip_prefix("ws://") - .and_then(|url| url.strip_suffix("/ws")) - .expect("websocket URL should use ws://.../ws"); - - for path in ["/", "/readyz", "/healthz"] { - let response = reqwest::get(format!("http://{http_base_url}{path}")).await?; - assert_eq!(response.status(), reqwest::StatusCode::OK); - } - - server.shutdown().await?; - Ok(()) -} diff --git a/codex-rs/tui/src/lib.rs b/codex-rs/tui/src/lib.rs index 86ffc1a073..ac5b489af1 100644 --- a/codex-rs/tui/src/lib.rs +++ b/codex-rs/tui/src/lib.rs @@ -2145,7 +2145,7 @@ mod tests { }; let target = AppServerTarget::Embedded; let environment_manager = EnvironmentManager::create_for_tests( - Some("ws://127.0.0.1:8765/ws".to_string()), + Some("ws://127.0.0.1:8765".to_string()), ExecServerRuntimePaths::new( std::env::current_exe().expect("current exe"), /*codex_linux_sandbox_exe*/ None, diff --git a/scripts/start-codex-exec.sh b/scripts/start-codex-exec.sh index 41b76b0317..8835d4c095 100755 --- a/scripts/start-codex-exec.sh +++ b/scripts/start-codex-exec.sh @@ -161,7 +161,6 @@ if [[ -z "${remote_exec_server_pid}" || -z "${listen_url}" || -z "${remote_repo_ fi remote_exec_server_port="${listen_url##*:}" -remote_exec_server_port="${remote_exec_server_port%%/*}" if [[ -z "${remote_exec_server_port}" || "${remote_exec_server_port}" == "${listen_url}" ]]; then echo "failed to parse remote exec server port from ${listen_url}" >&2 exit 1 @@ -171,7 +170,7 @@ echo "Remote exec server: ${listen_url}" echo "Remote exec server log: ${remote_exec_server_log_path}" echo "Press Ctrl-C to stop the SSH tunnel and remote exec server." echo "Start codex via: " -printf ' CODEX_EXEC_SERVER_URL=ws://127.0.0.1:%s/ws codex -C %q\n' \ +printf ' CODEX_EXEC_SERVER_URL=ws://127.0.0.1:%s codex -C %q\n' \ "${local_exec_server_port}" \ "${remote_repo_root}" diff --git a/scripts/test-remote-env.sh b/scripts/test-remote-env.sh index c7c7b51e9a..96743616a2 100755 --- a/scripts/test-remote-env.sh +++ b/scripts/test-remote-env.sh @@ -85,7 +85,7 @@ setup_remote_env() { return 1 fi export CODEX_TEST_REMOTE_EXEC_SERVER_PID="${remote_exec_server_pid}" -export CODEX_TEST_REMOTE_EXEC_SERVER_URL="ws://${container_ip}:${remote_exec_server_port}/ws" + export CODEX_TEST_REMOTE_EXEC_SERVER_URL="ws://${container_ip}:${remote_exec_server_port}" fi export CODEX_TEST_REMOTE_ENV="${container_name}"