From 829f5b6b59d72a8f3e16036a5896ade90eb96a35 Mon Sep 17 00:00:00 2001 From: "Adam Perry @ OpenAI" Date: Tue, 23 Jun 2026 15:37:31 -0700 Subject: [PATCH] protocol: separate app and exec RPC ownership (#29714) ## Why The app-server and exec-server expose separate JSON-RPC APIs, but exec-server currently sources its serialized protocol and envelope types through app-server-oriented code. Giving each API an explicit owner makes the crate boundary legible without introducing shared generic envelopes. ## What changed - Added `codex-exec-server-protocol` to own exec DTOs, process IDs, and JSON-RPC envelopes. - Updated exec-server clients, transports, handlers, and tests to use the new crate. - Exposed app-server's existing JSON-RPC types through a public `rpc` module while retaining root re-exports. - Preserved existing wire shapes, including exec `PathUri` behavior. ## Stack This is PR 1 of 6. Next: [PR #29721](https://github.com/openai/codex/pull/29721), which moves auth mode below the app wire boundary. ## Validation - Exec-server protocol and server coverage passed in the focused protocol test runs. - App-server protocol schema fixtures passed. --- .github/CODEOWNERS | 1 + codex-rs/Cargo.lock | 18 ++++- codex-rs/Cargo.toml | 2 + .../schema/json/ClientRequest.json | 2 +- .../codex_app_server_protocol.schemas.json | 10 +-- .../codex_app_server_protocol.v2.schemas.json | 2 +- .../schema/json/v2/ThreadStartParams.json | 2 +- codex-rs/app-server-protocol/src/lib.rs | 4 +- .../src/{jsonrpc_lite.rs => rpc.rs} | 0 codex-rs/exec-server-protocol/BUILD.bazel | 6 ++ codex-rs/exec-server-protocol/Cargo.toml | 26 +++++++ codex-rs/exec-server-protocol/src/lib.rs | 7 ++ .../src/process_id.rs | 0 .../src/protocol.rs | 28 ++++++- codex-rs/exec-server-protocol/src/rpc.rs | 78 +++++++++++++++++++ codex-rs/exec-server/Cargo.toml | 3 +- codex-rs/exec-server/README.md | 4 +- codex-rs/exec-server/src/client.rs | 8 +- .../src/client/reqwest_http_client.rs | 2 +- codex-rs/exec-server/src/connection.rs | 8 +- codex-rs/exec-server/src/environment.rs | 23 ------ codex-rs/exec-server/src/fs_helper.rs | 2 +- codex-rs/exec-server/src/fs_sandbox.rs | 2 +- codex-rs/exec-server/src/lib.rs | 6 +- codex-rs/exec-server/src/local_process.rs | 2 +- .../src/noise_relay/executor_stream_tests.rs | 6 +- .../src/noise_relay/message_framing.rs | 2 +- .../src/noise_relay/message_framing_tests.rs | 4 +- codex-rs/exec-server/src/process_sandbox.rs | 2 +- codex-rs/exec-server/src/relay.rs | 7 +- .../src/remote_file_system_path_uri_tests.rs | 4 +- codex-rs/exec-server/src/rpc.rs | 19 +++-- .../exec-server/src/sandboxed_file_system.rs | 2 +- .../src/server/file_system_handler.rs | 2 +- codex-rs/exec-server/src/server/handler.rs | 4 +- .../exec-server/src/server/process_handler.rs | 2 +- codex-rs/exec-server/src/server/processor.rs | 21 +++-- .../src/server/session_registry.rs | 2 +- .../exec-server/src/server/transport_tests.rs | 11 ++- .../exec-server/tests/common/exec_server.rs | 9 +-- codex-rs/exec-server/tests/http_client.rs | 10 +-- codex-rs/exec-server/tests/http_request.rs | 12 +-- codex-rs/exec-server/tests/initialize.rs | 4 +- codex-rs/exec-server/tests/process.rs | 4 +- codex-rs/exec-server/tests/websocket.rs | 13 ++-- 45 files changed, 255 insertions(+), 131 deletions(-) rename codex-rs/app-server-protocol/src/{jsonrpc_lite.rs => rpc.rs} (100%) create mode 100644 codex-rs/exec-server-protocol/BUILD.bazel create mode 100644 codex-rs/exec-server-protocol/Cargo.toml create mode 100644 codex-rs/exec-server-protocol/src/lib.rs rename codex-rs/{exec-server => exec-server-protocol}/src/process_id.rs (100%) rename codex-rs/{exec-server => exec-server-protocol}/src/protocol.rs (96%) create mode 100644 codex-rs/exec-server-protocol/src/rpc.rs diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 48674d396..41a1e6922 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,5 +1,6 @@ # Core crate ownership. /codex-rs/core/ @openai/codex-core-agent-team +/codex-rs/exec-server-protocol/ @openai/codex-core-agent-team /codex-rs/ext/extension-api/ @openai/codex-core-agent-team /codex-rs/prompts/ @openai/codex-core-agent-team /codex-rs/utils/path-uri/ @openai/codex-core-agent-team diff --git a/codex-rs/Cargo.lock b/codex-rs/Cargo.lock index a2953be53..6b5b5afdf 100644 --- a/codex-rs/Cargo.lock +++ b/codex-rs/Cargo.lock @@ -2883,13 +2883,12 @@ dependencies = [ "bytes", "clatter", "codex-api", - "codex-app-server-protocol", "codex-client", + "codex-exec-server-protocol", "codex-file-system", "codex-network-proxy", "codex-protocol", "codex-sandboxing", - "codex-shell-command", "codex-test-binary-support", "codex-utils-absolute-path", "codex-utils-path-uri", @@ -2918,6 +2917,21 @@ dependencies = [ "wiremock", ] +[[package]] +name = "codex-exec-server-protocol" +version = "0.0.0" +dependencies = [ + "base64 0.22.1", + "codex-file-system", + "codex-network-proxy", + "codex-protocol", + "codex-shell-command", + "codex-utils-path-uri", + "pretty_assertions", + "serde", + "serde_json", +] + [[package]] name = "codex-execpolicy" version = "0.0.0" diff --git a/codex-rs/Cargo.toml b/codex-rs/Cargo.toml index 17c2d1561..2bc8ac340 100644 --- a/codex-rs/Cargo.toml +++ b/codex-rs/Cargo.toml @@ -44,6 +44,7 @@ members = [ "secrets", "exec", "file-system", + "exec-server-protocol", "exec-server", "execpolicy", "execpolicy-legacy", @@ -171,6 +172,7 @@ codex-core-plugins = { path = "core-plugins" } codex-core-skills = { path = "core-skills" } codex-exec = { path = "exec" } codex-file-system = { path = "file-system" } +codex-exec-server-protocol = { path = "exec-server-protocol" } codex-exec-server = { path = "exec-server" } codex-execpolicy = { path = "execpolicy" } codex-extension-api = { path = "ext/extension-api" } diff --git a/codex-rs/app-server-protocol/schema/json/ClientRequest.json b/codex-rs/app-server-protocol/schema/json/ClientRequest.json index dcdbfa53f..214f136d7 100644 --- a/codex-rs/app-server-protocol/schema/json/ClientRequest.json +++ b/codex-rs/app-server-protocol/schema/json/ClientRequest.json @@ -6834,4 +6834,4 @@ } ], "title": "ClientRequest" -} +} \ No newline at end of file diff --git a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json index cfefddcee..e61969c47 100644 --- a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json +++ b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json @@ -7042,10 +7042,10 @@ "environmentId": { "type": "string" }, - "path": { - "description": "Absolute path for the root in the selected environment.", - "type": "string" - }, + "path": { + "description": "Absolute path for the root in the selected environment.", + "type": "string" + }, "type": { "enum": [ "environment" @@ -20691,4 +20691,4 @@ }, "title": "CodexAppServerProtocol", "type": "object" -} +} \ No newline at end of file diff --git a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json index 507a53480..3809c0b44 100644 --- a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json +++ b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json @@ -18469,4 +18469,4 @@ }, "title": "CodexAppServerProtocolV2", "type": "object" -} +} \ No newline at end of file diff --git a/codex-rs/app-server-protocol/schema/json/v2/ThreadStartParams.json b/codex-rs/app-server-protocol/schema/json/v2/ThreadStartParams.json index e447c644d..50c0a9cf7 100644 --- a/codex-rs/app-server-protocol/schema/json/v2/ThreadStartParams.json +++ b/codex-rs/app-server-protocol/schema/json/v2/ThreadStartParams.json @@ -388,4 +388,4 @@ }, "title": "ThreadStartParams", "type": "object" -} +} \ No newline at end of file diff --git a/codex-rs/app-server-protocol/src/lib.rs b/codex-rs/app-server-protocol/src/lib.rs index f6d7670e1..0797fcdf7 100644 --- a/codex-rs/app-server-protocol/src/lib.rs +++ b/codex-rs/app-server-protocol/src/lib.rs @@ -1,7 +1,7 @@ mod experimental_api; mod export; -mod jsonrpc_lite; mod protocol; +pub mod rpc; mod schema_fixtures; pub use experimental_api::*; @@ -12,7 +12,6 @@ pub use export::generate_json_with_experimental; pub use export::generate_ts; pub use export::generate_ts_with_options; pub use export::generate_types; -pub use jsonrpc_lite::*; pub use protocol::common::*; pub use protocol::event_mapping::*; pub use protocol::item_builders::*; @@ -40,6 +39,7 @@ pub use protocol::v1::SandboxSettings; pub use protocol::v1::Tools; pub use protocol::v1::UserSavedConfig; pub use protocol::v2::*; +pub use rpc::*; pub use schema_fixtures::SchemaFixtureOptions; #[doc(hidden)] pub use schema_fixtures::generate_typescript_schema_fixture_subtree_for_tests; diff --git a/codex-rs/app-server-protocol/src/jsonrpc_lite.rs b/codex-rs/app-server-protocol/src/rpc.rs similarity index 100% rename from codex-rs/app-server-protocol/src/jsonrpc_lite.rs rename to codex-rs/app-server-protocol/src/rpc.rs diff --git a/codex-rs/exec-server-protocol/BUILD.bazel b/codex-rs/exec-server-protocol/BUILD.bazel new file mode 100644 index 000000000..6f7994756 --- /dev/null +++ b/codex-rs/exec-server-protocol/BUILD.bazel @@ -0,0 +1,6 @@ +load("//:defs.bzl", "codex_rust_crate") + +codex_rust_crate( + name = "exec-server-protocol", + crate_name = "codex_exec_server_protocol", +) diff --git a/codex-rs/exec-server-protocol/Cargo.toml b/codex-rs/exec-server-protocol/Cargo.toml new file mode 100644 index 000000000..5a8628705 --- /dev/null +++ b/codex-rs/exec-server-protocol/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "codex-exec-server-protocol" +version.workspace = true +edition.workspace = true +license.workspace = true + +[lib] +name = "codex_exec_server_protocol" +path = "src/lib.rs" +doctest = false + +[lints] +workspace = true + +[dependencies] +base64 = { workspace = true } +codex-file-system = { workspace = true } +codex-network-proxy = { workspace = true } +codex-protocol = { workspace = true } +codex-shell-command = { workspace = true } +codex-utils-path-uri = { workspace = true } +serde = { workspace = true, features = ["derive"] } +serde_json = { workspace = true } + +[dev-dependencies] +pretty_assertions = { workspace = true } diff --git a/codex-rs/exec-server-protocol/src/lib.rs b/codex-rs/exec-server-protocol/src/lib.rs new file mode 100644 index 000000000..b5a6ebc74 --- /dev/null +++ b/codex-rs/exec-server-protocol/src/lib.rs @@ -0,0 +1,7 @@ +mod process_id; +mod protocol; +pub mod rpc; + +pub use process_id::ProcessId; +pub use protocol::*; +pub use rpc::*; diff --git a/codex-rs/exec-server/src/process_id.rs b/codex-rs/exec-server-protocol/src/process_id.rs similarity index 100% rename from codex-rs/exec-server/src/process_id.rs rename to codex-rs/exec-server-protocol/src/process_id.rs diff --git a/codex-rs/exec-server/src/protocol.rs b/codex-rs/exec-server-protocol/src/protocol.rs similarity index 96% rename from codex-rs/exec-server/src/protocol.rs rename to codex-rs/exec-server-protocol/src/protocol.rs index d53dae471..5ae80c37e 100644 --- a/codex-rs/exec-server/src/protocol.rs +++ b/codex-rs/exec-server-protocol/src/protocol.rs @@ -4,6 +4,7 @@ use base64::engine::general_purpose::STANDARD as BASE64_STANDARD; use codex_file_system::FileSystemSandboxContext; use codex_network_proxy::ManagedNetworkSandboxContext; use codex_protocol::config_types::ShellEnvironmentPolicyInherit; +use codex_shell_command::shell_detect::DetectedShell; use codex_utils_path_uri::PathUri; use serde::Deserialize; use serde::Serialize; @@ -22,9 +23,9 @@ pub const EXEC_EXITED_METHOD: &str = "process/exited"; pub const EXEC_CLOSED_METHOD: &str = "process/closed"; pub const ENVIRONMENT_INFO_METHOD: &str = "environment/info"; pub const FS_READ_FILE_METHOD: &str = "fs/readFile"; -pub(crate) const FS_OPEN_METHOD: &str = "fs/open"; -pub(crate) const FS_READ_BLOCK_METHOD: &str = "fs/readBlock"; -pub(crate) const FS_CLOSE_METHOD: &str = "fs/close"; +pub const FS_OPEN_METHOD: &str = "fs/open"; +pub const FS_READ_BLOCK_METHOD: &str = "fs/readBlock"; +pub const FS_CLOSE_METHOD: &str = "fs/close"; pub const FS_WRITE_FILE_METHOD: &str = "fs/writeFile"; pub const FS_CREATE_DIRECTORY_METHOD: &str = "fs/createDirectory"; pub const FS_GET_METADATA_METHOD: &str = "fs/getMetadata"; @@ -77,6 +78,18 @@ pub struct EnvironmentInfo { pub cwd: Option, } +impl EnvironmentInfo { + /// Returns information about the current local exec-server process. + pub fn local() -> Self { + Self { + shell: codex_shell_command::shell_detect::default_user_shell().into(), + cwd: std::env::current_dir() + .ok() + .and_then(|cwd| PathUri::from_host_native_path(cwd).ok()), + } + } +} + /// Shell detected for an execution/filesystem environment. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -88,6 +101,15 @@ pub struct ShellInfo { pub path: String, } +impl From for ShellInfo { + fn from(shell: DetectedShell) -> Self { + Self { + name: shell.name().to_string(), + path: shell.shell_path.to_string_lossy().into_owned(), + } + } +} + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct ExecParams { diff --git a/codex-rs/exec-server-protocol/src/rpc.rs b/codex-rs/exec-server-protocol/src/rpc.rs new file mode 100644 index 000000000..09bedf0fe --- /dev/null +++ b/codex-rs/exec-server-protocol/src/rpc.rs @@ -0,0 +1,78 @@ +//! JSON-RPC wire envelopes used by exec-server. +//! +//! Exec-server uses the Codex JSON-RPC dialect, which omits the +//! `"jsonrpc": "2.0"` field on the wire. + +use std::fmt; + +use serde::Deserialize; +use serde::Serialize; + +pub const JSONRPC_VERSION: &str = "2.0"; + +#[derive(Debug, Clone, PartialEq, PartialOrd, Ord, Deserialize, Serialize, Hash, Eq)] +#[serde(untagged)] +pub enum RequestId { + String(String), + Integer(i64), +} + +impl fmt::Display for RequestId { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::String(value) => f.write_str(value), + Self::Integer(value) => write!(f, "{value}"), + } + } +} + +pub type Result = serde_json::Value; + +/// Any valid exec-server JSON-RPC object that can be decoded from or encoded onto the wire. +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] +#[serde(untagged)] +pub enum JSONRPCMessage { + Request(JSONRPCRequest), + Notification(JSONRPCNotification), + Response(JSONRPCResponse), + Error(JSONRPCError), +} + +/// A request that expects a response. +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] +pub struct JSONRPCRequest { + pub id: RequestId, + pub method: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub params: Option, +} + +/// A notification that does not expect a response. +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] +pub struct JSONRPCNotification { + pub method: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub params: Option, +} + +/// A successful response to a request. +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] +pub struct JSONRPCResponse { + pub id: RequestId, + pub result: Result, +} + +/// A response indicating that a request failed. +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] +pub struct JSONRPCError { + pub error: JSONRPCErrorError, + pub id: RequestId, +} + +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] +pub struct JSONRPCErrorError { + pub code: i64, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub data: Option, + pub message: String, +} diff --git a/codex-rs/exec-server/Cargo.toml b/codex-rs/exec-server/Cargo.toml index 02f23dfc4..9f5383aa0 100644 --- a/codex-rs/exec-server/Cargo.toml +++ b/codex-rs/exec-server/Cargo.toml @@ -16,14 +16,13 @@ axum = { workspace = true, features = ["http1", "tokio", "ws"] } base64 = { workspace = true } bytes = { workspace = true } clatter = { workspace = true } -codex-app-server-protocol = { workspace = true } codex-api = { workspace = true } codex-client = { workspace = true } +codex-exec-server-protocol = { workspace = true } codex-file-system = { workspace = true } codex-network-proxy = { workspace = true } codex-protocol = { workspace = true } codex-sandboxing = { workspace = true } -codex-shell-command = { workspace = true } codex-utils-absolute-path = { workspace = true } codex-utils-path-uri = { workspace = true } codex-utils-pty = { workspace = true } diff --git a/codex-rs/exec-server/README.md b/codex-rs/exec-server/README.md index 6d2e663e2..b1f927918 100644 --- a/codex-rs/exec-server/README.md +++ b/codex-rs/exec-server/README.md @@ -16,8 +16,8 @@ filesystem operations and `codex-linux-sandbox`. ## Transport -The server speaks the shared `codex-app-server-protocol` message envelope on -the wire. +The server speaks the exec-specific `codex-exec-server-protocol` message +envelope on the wire. The CLI entrypoint supports: diff --git a/codex-rs/exec-server/src/client.rs b/codex-rs/exec-server/src/client.rs index 25d1b54e8..f913892e1 100644 --- a/codex-rs/exec-server/src/client.rs +++ b/codex-rs/exec-server/src/client.rs @@ -9,7 +9,7 @@ use std::sync::atomic::Ordering; use std::time::Duration; use arc_swap::ArcSwap; -use codex_app_server_protocol::JSONRPCNotification; +use codex_exec_server_protocol::JSONRPCNotification; use futures::FutureExt; use futures::future::BoxFuture; use serde_json::Value; @@ -1187,9 +1187,9 @@ async fn handle_server_notification( #[cfg(test)] mod tests { - use codex_app_server_protocol::JSONRPCMessage; - use codex_app_server_protocol::JSONRPCNotification; - use codex_app_server_protocol::JSONRPCResponse; + use codex_exec_server_protocol::JSONRPCMessage; + use codex_exec_server_protocol::JSONRPCNotification; + use codex_exec_server_protocol::JSONRPCResponse; use futures::SinkExt; use futures::StreamExt; use pretty_assertions::assert_eq; diff --git a/codex-rs/exec-server/src/client/reqwest_http_client.rs b/codex-rs/exec-server/src/client/reqwest_http_client.rs index 9e22fc01d..9de35315e 100644 --- a/codex-rs/exec-server/src/client/reqwest_http_client.rs +++ b/codex-rs/exec-server/src/client/reqwest_http_client.rs @@ -8,8 +8,8 @@ use std::error::Error as StdError; use std::time::Duration; -use codex_app_server_protocol::JSONRPCErrorError; use codex_client::build_reqwest_client_with_custom_ca; +use codex_exec_server_protocol::JSONRPCErrorError; use futures::FutureExt; use futures::StreamExt; use futures::future::BoxFuture; diff --git a/codex-rs/exec-server/src/connection.rs b/codex-rs/exec-server/src/connection.rs index 2d2e5afe0..ebc12b2f3 100644 --- a/codex-rs/exec-server/src/connection.rs +++ b/codex-rs/exec-server/src/connection.rs @@ -7,7 +7,7 @@ use std::time::Duration; use axum::extract::ws::Message as AxumWebSocketMessage; use axum::extract::ws::WebSocket as AxumWebSocket; -use codex_app_server_protocol::JSONRPCMessage; +use codex_exec_server_protocol::JSONRPCMessage; use futures::Sink; use futures::SinkExt; use futures::Stream; @@ -597,8 +597,8 @@ mod tests { use std::task::Context; use std::task::Poll; - use codex_app_server_protocol::JSONRPCRequest; - use codex_app_server_protocol::RequestId; + use codex_exec_server_protocol::JSONRPCRequest; + use codex_exec_server_protocol::RequestId; use futures::channel::mpsc as futures_mpsc; use futures::task::AtomicWaker; use tokio::net::TcpListener; @@ -667,7 +667,6 @@ mod tests { id: RequestId::Integer(1), method: "test".to_string(), params: None, - trace: None, }); server_websocket @@ -732,7 +731,6 @@ mod tests { id: RequestId::Integer(1), method: "test".to_string(), params: None, - trace: None, }) } diff --git a/codex-rs/exec-server/src/environment.rs b/codex-rs/exec-server/src/environment.rs index b1e4ae5c5..664ef730d 100644 --- a/codex-rs/exec-server/src/environment.rs +++ b/codex-rs/exec-server/src/environment.rs @@ -23,12 +23,9 @@ use crate::local_file_system::LocalFileSystem; use crate::local_process::LocalProcess; use crate::process::ExecBackend; use crate::protocol::EnvironmentInfo; -use crate::protocol::ShellInfo; use crate::remote::NoiseRendezvousEnvironmentConfig; use crate::remote_file_system::RemoteFileSystem; use crate::remote_process::RemoteProcess; -use codex_shell_command::shell_detect::DetectedShell; -use codex_utils_path_uri::PathUri; use tokio_util::task::AbortOnDropHandle; pub const CODEX_EXEC_SERVER_URL_ENV_VAR: &str = "CODEX_EXEC_SERVER_URL"; @@ -605,26 +602,6 @@ impl Environment { } } -impl EnvironmentInfo { - pub(crate) fn local() -> Self { - Self { - shell: codex_shell_command::shell_detect::default_user_shell().into(), - cwd: std::env::current_dir() - .ok() - .and_then(|cwd| PathUri::from_host_native_path(cwd).ok()), - } - } -} - -impl From for ShellInfo { - fn from(shell: DetectedShell) -> Self { - Self { - name: shell.name().to_string(), - path: shell.shell_path.to_string_lossy().into_owned(), - } - } -} - #[cfg(test)] mod tests { use std::collections::HashMap; diff --git a/codex-rs/exec-server/src/fs_helper.rs b/codex-rs/exec-server/src/fs_helper.rs index 9fa74bf3d..1eba3d0be 100644 --- a/codex-rs/exec-server/src/fs_helper.rs +++ b/codex-rs/exec-server/src/fs_helper.rs @@ -1,6 +1,6 @@ use base64::Engine as _; use base64::engine::general_purpose::STANDARD; -use codex_app_server_protocol::JSONRPCErrorError; +use codex_exec_server_protocol::JSONRPCErrorError; use serde::Deserialize; use serde::Serialize; use tokio::io; diff --git a/codex-rs/exec-server/src/fs_sandbox.rs b/codex-rs/exec-server/src/fs_sandbox.rs index 41a3e1221..812d76751 100644 --- a/codex-rs/exec-server/src/fs_sandbox.rs +++ b/codex-rs/exec-server/src/fs_sandbox.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use codex_app_server_protocol::JSONRPCErrorError; +use codex_exec_server_protocol::JSONRPCErrorError; use codex_protocol::models::PermissionProfile; use codex_protocol::permissions::FileSystemAccessMode; use codex_protocol::permissions::FileSystemPath; diff --git a/codex-rs/exec-server/src/lib.rs b/codex-rs/exec-server/src/lib.rs index d5c71674a..c861e47ba 100644 --- a/codex-rs/exec-server/src/lib.rs +++ b/codex-rs/exec-server/src/lib.rs @@ -15,9 +15,7 @@ mod local_process; mod noise_channel; mod noise_relay; mod process; -mod process_id; mod process_sandbox; -mod protocol; mod regular_file; mod relay; mod relay_proto; @@ -29,6 +27,8 @@ mod runtime_paths; mod sandboxed_file_system; mod server; +use codex_exec_server_protocol as protocol; + pub use client::ExecServerClient; pub use client::ExecServerError; pub use client::http_client::HttpResponseBodyStream; @@ -39,6 +39,7 @@ pub use client_api::NoiseRendezvousConnectArgs; pub use client_api::NoiseRendezvousConnectBundle; pub use client_api::NoiseRendezvousConnectProvider; pub use client_api::RemoteExecServerConnectArgs; +pub use codex_exec_server_protocol::ProcessId; pub use codex_file_system::CopyOptions; pub use codex_file_system::CreateDirectoryOptions; pub use codex_file_system::ExecutorFileSystem; @@ -78,7 +79,6 @@ pub use process::ExecProcessEvent; pub use process::ExecProcessEventReceiver; pub use process::ExecProcessFuture; pub use process::StartedExecProcess; -pub use process_id::ProcessId; pub use protocol::ByteChunk; pub use protocol::EnvironmentInfo; pub use protocol::ExecClosedNotification; diff --git a/codex-rs/exec-server/src/local_process.rs b/codex-rs/exec-server/src/local_process.rs index d77209e7c..973019808 100644 --- a/codex-rs/exec-server/src/local_process.rs +++ b/codex-rs/exec-server/src/local_process.rs @@ -7,7 +7,7 @@ use std::sync::atomic::AtomicU64; use std::sync::atomic::Ordering; use std::time::Duration; -use codex_app_server_protocol::JSONRPCErrorError; +use codex_exec_server_protocol::JSONRPCErrorError; use codex_protocol::config_types::EnvironmentVariablePattern; use codex_protocol::config_types::ShellEnvironmentPolicy; use codex_protocol::exec_output::ExecToolCallOutput; diff --git a/codex-rs/exec-server/src/noise_relay/executor_stream_tests.rs b/codex-rs/exec-server/src/noise_relay/executor_stream_tests.rs index 9119236cf..232dfa479 100644 --- a/codex-rs/exec-server/src/noise_relay/executor_stream_tests.rs +++ b/codex-rs/exec-server/src/noise_relay/executor_stream_tests.rs @@ -1,9 +1,9 @@ use std::time::Duration; use anyhow::Result; -use codex_app_server_protocol::JSONRPCMessage; -use codex_app_server_protocol::JSONRPCResponse; -use codex_app_server_protocol::RequestId; +use codex_exec_server_protocol::JSONRPCMessage; +use codex_exec_server_protocol::JSONRPCResponse; +use codex_exec_server_protocol::RequestId; use tokio::sync::mpsc; use tokio::time::timeout; diff --git a/codex-rs/exec-server/src/noise_relay/message_framing.rs b/codex-rs/exec-server/src/noise_relay/message_framing.rs index 24ee48173..402b68691 100644 --- a/codex-rs/exec-server/src/noise_relay/message_framing.rs +++ b/codex-rs/exec-server/src/noise_relay/message_framing.rs @@ -1,4 +1,4 @@ -use codex_app_server_protocol::JSONRPCMessage; +use codex_exec_server_protocol::JSONRPCMessage; use crate::ExecServerError; diff --git a/codex-rs/exec-server/src/noise_relay/message_framing_tests.rs b/codex-rs/exec-server/src/noise_relay/message_framing_tests.rs index c3df14bf5..3b9ac7939 100644 --- a/codex-rs/exec-server/src/noise_relay/message_framing_tests.rs +++ b/codex-rs/exec-server/src/noise_relay/message_framing_tests.rs @@ -1,5 +1,5 @@ -use codex_app_server_protocol::JSONRPCMessage; -use codex_app_server_protocol::JSONRPCNotification; +use codex_exec_server_protocol::JSONRPCMessage; +use codex_exec_server_protocol::JSONRPCNotification; use pretty_assertions::assert_eq; use super::JsonRpcMessageDecoder; diff --git a/codex-rs/exec-server/src/process_sandbox.rs b/codex-rs/exec-server/src/process_sandbox.rs index ef97d0ce5..b5dd54e0b 100644 --- a/codex-rs/exec-server/src/process_sandbox.rs +++ b/codex-rs/exec-server/src/process_sandbox.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use codex_app_server_protocol::JSONRPCErrorError; +use codex_exec_server_protocol::JSONRPCErrorError; use codex_network_proxy::CUSTOM_CA_ENV_KEYS; use codex_network_proxy::is_managed_mitm_ca_trust_bundle_path; use codex_protocol::models::PermissionProfile; diff --git a/codex-rs/exec-server/src/relay.rs b/codex-rs/exec-server/src/relay.rs index 033da4b2a..950fd60e7 100644 --- a/codex-rs/exec-server/src/relay.rs +++ b/codex-rs/exec-server/src/relay.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use std::time::Duration; -use codex_app_server_protocol::JSONRPCMessage; +use codex_exec_server_protocol::JSONRPCMessage; use futures::Sink; use futures::SinkExt; use futures::Stream; @@ -847,8 +847,8 @@ mod tests { use std::task::Poll; use std::time::Duration; - use codex_app_server_protocol::JSONRPCRequest; - use codex_app_server_protocol::RequestId; + use codex_exec_server_protocol::JSONRPCRequest; + use codex_exec_server_protocol::RequestId; use futures::Sink; use futures::Stream; use futures::channel::mpsc as futures_mpsc; @@ -1101,7 +1101,6 @@ mod tests { id: RequestId::Integer(1), method: "test".to_string(), params: None, - trace: None, }) } diff --git a/codex-rs/exec-server/src/remote_file_system_path_uri_tests.rs b/codex-rs/exec-server/src/remote_file_system_path_uri_tests.rs index 1205c6d7e..562f5d564 100644 --- a/codex-rs/exec-server/src/remote_file_system_path_uri_tests.rs +++ b/codex-rs/exec-server/src/remote_file_system_path_uri_tests.rs @@ -1,7 +1,7 @@ #![allow(clippy::expect_used)] -use codex_app_server_protocol::JSONRPCMessage; -use codex_app_server_protocol::JSONRPCResponse; +use codex_exec_server_protocol::JSONRPCMessage; +use codex_exec_server_protocol::JSONRPCResponse; use codex_protocol::models::PermissionProfile; use codex_protocol::permissions::FileSystemAccessMode; use codex_protocol::permissions::FileSystemPath; diff --git a/codex-rs/exec-server/src/rpc.rs b/codex-rs/exec-server/src/rpc.rs index 82cf2b200..8279f795a 100644 --- a/codex-rs/exec-server/src/rpc.rs +++ b/codex-rs/exec-server/src/rpc.rs @@ -6,13 +6,13 @@ use std::sync::atomic::AtomicBool; use std::sync::atomic::AtomicI64; use std::sync::atomic::Ordering; -use codex_app_server_protocol::JSONRPCError; -use codex_app_server_protocol::JSONRPCErrorError; -use codex_app_server_protocol::JSONRPCMessage; -use codex_app_server_protocol::JSONRPCNotification; -use codex_app_server_protocol::JSONRPCRequest; -use codex_app_server_protocol::JSONRPCResponse; -use codex_app_server_protocol::RequestId; +use codex_exec_server_protocol::JSONRPCError; +use codex_exec_server_protocol::JSONRPCErrorError; +use codex_exec_server_protocol::JSONRPCMessage; +use codex_exec_server_protocol::JSONRPCNotification; +use codex_exec_server_protocol::JSONRPCRequest; +use codex_exec_server_protocol::JSONRPCResponse; +use codex_exec_server_protocol::RequestId; use serde::Serialize; use serde::de::DeserializeOwned; use serde_json::Value; @@ -362,7 +362,6 @@ impl RpcClient { id: request_id.clone(), method: method.to_string(), params: Some(params), - trace: None, })) .await .is_err() @@ -552,8 +551,8 @@ async fn drain_pending(pending: &Mutex>) { mod tests { use std::time::Duration; - use codex_app_server_protocol::JSONRPCMessage; - use codex_app_server_protocol::JSONRPCResponse; + use codex_exec_server_protocol::JSONRPCMessage; + use codex_exec_server_protocol::JSONRPCResponse; use pretty_assertions::assert_eq; use tokio::io::AsyncBufReadExt; use tokio::io::AsyncWriteExt; diff --git a/codex-rs/exec-server/src/sandboxed_file_system.rs b/codex-rs/exec-server/src/sandboxed_file_system.rs index d0beb57a4..81007e65e 100644 --- a/codex-rs/exec-server/src/sandboxed_file_system.rs +++ b/codex-rs/exec-server/src/sandboxed_file_system.rs @@ -1,6 +1,6 @@ use base64::Engine as _; use base64::engine::general_purpose::STANDARD; -use codex_app_server_protocol::JSONRPCErrorError; +use codex_exec_server_protocol::JSONRPCErrorError; use codex_utils_path_uri::PathUri; use tokio::io; diff --git a/codex-rs/exec-server/src/server/file_system_handler.rs b/codex-rs/exec-server/src/server/file_system_handler.rs index 1a6e07393..a77b7ac71 100644 --- a/codex-rs/exec-server/src/server/file_system_handler.rs +++ b/codex-rs/exec-server/src/server/file_system_handler.rs @@ -2,7 +2,7 @@ use std::io; use base64::Engine as _; use base64::engine::general_purpose::STANDARD; -use codex_app_server_protocol::JSONRPCErrorError; +use codex_exec_server_protocol::JSONRPCErrorError; use crate::CopyOptions; use crate::CreateDirectoryOptions; diff --git a/codex-rs/exec-server/src/server/handler.rs b/codex-rs/exec-server/src/server/handler.rs index 07575a1c4..28d78a900 100644 --- a/codex-rs/exec-server/src/server/handler.rs +++ b/codex-rs/exec-server/src/server/handler.rs @@ -3,8 +3,8 @@ use std::sync::Mutex as StdMutex; use std::sync::atomic::AtomicBool; use std::sync::atomic::Ordering; -use codex_app_server_protocol::JSONRPCErrorError; -use codex_app_server_protocol::RequestId; +use codex_exec_server_protocol::JSONRPCErrorError; +use codex_exec_server_protocol::RequestId; use serde_json::to_value; use std::collections::HashSet; use tokio::sync::Mutex; diff --git a/codex-rs/exec-server/src/server/process_handler.rs b/codex-rs/exec-server/src/server/process_handler.rs index f628b242b..9ff669041 100644 --- a/codex-rs/exec-server/src/server/process_handler.rs +++ b/codex-rs/exec-server/src/server/process_handler.rs @@ -1,4 +1,4 @@ -use codex_app_server_protocol::JSONRPCErrorError; +use codex_exec_server_protocol::JSONRPCErrorError; use crate::ExecServerRuntimePaths; use crate::local_process::LocalProcess; diff --git a/codex-rs/exec-server/src/server/processor.rs b/codex-rs/exec-server/src/server/processor.rs index d960e53ca..e16359213 100644 --- a/codex-rs/exec-server/src/server/processor.rs +++ b/codex-rs/exec-server/src/server/processor.rs @@ -89,7 +89,7 @@ async fn run_connection( warn!("ignoring malformed exec-server message: {reason}"); if outgoing_tx .send(RpcServerOutboundMessage::Error { - request_id: codex_app_server_protocol::RequestId::Integer(-1), + request_id: codex_exec_server_protocol::RequestId::Integer(-1), error: invalid_request(reason), }) .await @@ -99,7 +99,7 @@ async fn run_connection( } } JsonRpcConnectionEvent::Message(message) => match message { - codex_app_server_protocol::JSONRPCMessage::Request(request) => { + codex_exec_server_protocol::JSONRPCMessage::Request(request) => { if let Some(route) = router.request_route(request.method.as_str()) { let message = tokio::select! { message = route(Arc::clone(&handler), request) => message, @@ -127,7 +127,7 @@ async fn run_connection( break; } } - codex_app_server_protocol::JSONRPCMessage::Notification(notification) => { + codex_exec_server_protocol::JSONRPCMessage::Notification(notification) => { let Some(route) = router.notification_route(notification.method.as_str()) else { warn!( @@ -150,14 +150,14 @@ async fn run_connection( break; } } - codex_app_server_protocol::JSONRPCMessage::Response(response) => { + codex_exec_server_protocol::JSONRPCMessage::Response(response) => { warn!( "closing exec-server connection after unexpected client response: {:?}", response.id ); break; } - codex_app_server_protocol::JSONRPCMessage::Error(error) => { + codex_exec_server_protocol::JSONRPCMessage::Error(error) => { warn!( "closing exec-server connection after unexpected client error: {:?}", error.id @@ -190,11 +190,11 @@ mod tests { use std::sync::Arc; use std::time::Duration; - use codex_app_server_protocol::JSONRPCMessage; - use codex_app_server_protocol::JSONRPCNotification; - use codex_app_server_protocol::JSONRPCRequest; - use codex_app_server_protocol::JSONRPCResponse; - use codex_app_server_protocol::RequestId; + use codex_exec_server_protocol::JSONRPCMessage; + use codex_exec_server_protocol::JSONRPCNotification; + use codex_exec_server_protocol::JSONRPCRequest; + use codex_exec_server_protocol::JSONRPCResponse; + use codex_exec_server_protocol::RequestId; use codex_utils_path_uri::PathUri; use pretty_assertions::assert_eq; use serde::Serialize; @@ -382,7 +382,6 @@ mod tests { id: RequestId::Integer(id), method: method.to_string(), params: Some(serde_json::to_value(params).expect("serialize params")), - trace: None, }), ) .await; diff --git a/codex-rs/exec-server/src/server/session_registry.rs b/codex-rs/exec-server/src/server/session_registry.rs index 73b14ff7c..4d2ef7f89 100644 --- a/codex-rs/exec-server/src/server/session_registry.rs +++ b/codex-rs/exec-server/src/server/session_registry.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use std::sync::Mutex as StdMutex; use std::time::Duration; -use codex_app_server_protocol::JSONRPCErrorError; +use codex_exec_server_protocol::JSONRPCErrorError; use tokio::sync::Mutex; use uuid::Uuid; diff --git a/codex-rs/exec-server/src/server/transport_tests.rs b/codex-rs/exec-server/src/server/transport_tests.rs index b9787d8a3..49d769e41 100644 --- a/codex-rs/exec-server/src/server/transport_tests.rs +++ b/codex-rs/exec-server/src/server/transport_tests.rs @@ -1,11 +1,11 @@ use std::net::SocketAddr; use std::time::Duration; -use codex_app_server_protocol::JSONRPCMessage; -use codex_app_server_protocol::JSONRPCNotification; -use codex_app_server_protocol::JSONRPCRequest; -use codex_app_server_protocol::JSONRPCResponse; -use codex_app_server_protocol::RequestId; +use codex_exec_server_protocol::JSONRPCMessage; +use codex_exec_server_protocol::JSONRPCNotification; +use codex_exec_server_protocol::JSONRPCRequest; +use codex_exec_server_protocol::JSONRPCResponse; +use codex_exec_server_protocol::RequestId; use pretty_assertions::assert_eq; use tokio::io::AsyncBufReadExt; use tokio::io::AsyncWriteExt; @@ -74,7 +74,6 @@ async fn stdio_listen_transport_serves_initialize() { }) .expect("initialize params should serialize"), ), - trace: None, }); write_jsonrpc_line(&mut client_writer, &initialize).await; diff --git a/codex-rs/exec-server/tests/common/exec_server.rs b/codex-rs/exec-server/tests/common/exec_server.rs index ad089d5cd..bbd2d8116 100644 --- a/codex-rs/exec-server/tests/common/exec_server.rs +++ b/codex-rs/exec-server/tests/common/exec_server.rs @@ -5,10 +5,10 @@ use std::process::Stdio; use std::time::Duration; use anyhow::anyhow; -use codex_app_server_protocol::JSONRPCMessage; -use codex_app_server_protocol::JSONRPCNotification; -use codex_app_server_protocol::JSONRPCRequest; -use codex_app_server_protocol::RequestId; +use codex_exec_server_protocol::JSONRPCMessage; +use codex_exec_server_protocol::JSONRPCNotification; +use codex_exec_server_protocol::JSONRPCRequest; +use codex_exec_server_protocol::RequestId; use futures::SinkExt; use futures::StreamExt; use tempfile::TempDir; @@ -165,7 +165,6 @@ impl ExecServerHarness { id: id.clone(), method: method.to_string(), params: Some(params), - trace: None, })) .await?; Ok(id) diff --git a/codex-rs/exec-server/tests/http_client.rs b/codex-rs/exec-server/tests/http_client.rs index 6a087dd11..248564b49 100644 --- a/codex-rs/exec-server/tests/http_client.rs +++ b/codex-rs/exec-server/tests/http_client.rs @@ -4,11 +4,6 @@ use std::time::Duration; use anyhow::Context; use anyhow::Result; use anyhow::bail; -use codex_app_server_protocol::JSONRPCMessage; -use codex_app_server_protocol::JSONRPCNotification; -use codex_app_server_protocol::JSONRPCRequest; -use codex_app_server_protocol::JSONRPCResponse; -use codex_app_server_protocol::RequestId; use codex_exec_server::ExecServerClient; use codex_exec_server::HttpHeader; use codex_exec_server::HttpRequestBodyDeltaNotification; @@ -17,6 +12,11 @@ use codex_exec_server::HttpRequestResponse; use codex_exec_server::InitializeParams; use codex_exec_server::InitializeResponse; use codex_exec_server::RemoteExecServerConnectArgs; +use codex_exec_server_protocol::JSONRPCMessage; +use codex_exec_server_protocol::JSONRPCNotification; +use codex_exec_server_protocol::JSONRPCRequest; +use codex_exec_server_protocol::JSONRPCResponse; +use codex_exec_server_protocol::RequestId; use futures::SinkExt; use futures::StreamExt; use pretty_assertions::assert_eq; diff --git a/codex-rs/exec-server/tests/http_request.rs b/codex-rs/exec-server/tests/http_request.rs index f45261dad..a4734bf92 100644 --- a/codex-rs/exec-server/tests/http_request.rs +++ b/codex-rs/exec-server/tests/http_request.rs @@ -6,16 +6,16 @@ use std::collections::BTreeMap; use std::io::ErrorKind; use std::time::Duration; -use codex_app_server_protocol::JSONRPCError; -use codex_app_server_protocol::JSONRPCMessage; -use codex_app_server_protocol::JSONRPCNotification; -use codex_app_server_protocol::JSONRPCResponse; -use codex_app_server_protocol::RequestId; use codex_exec_server::HttpHeader; use codex_exec_server::HttpRequestBodyDeltaNotification; use codex_exec_server::HttpRequestParams; use codex_exec_server::HttpRequestResponse; use codex_exec_server::InitializeParams; +use codex_exec_server_protocol::JSONRPCError; +use codex_exec_server_protocol::JSONRPCMessage; +use codex_exec_server_protocol::JSONRPCNotification; +use codex_exec_server_protocol::JSONRPCResponse; +use codex_exec_server_protocol::RequestId; use common::exec_server::ExecServerHarness; use common::exec_server::exec_server; use pretty_assertions::assert_eq; @@ -392,7 +392,7 @@ where async fn wait_for_error_response( server: &mut ExecServerHarness, request_id: RequestId, -) -> anyhow::Result { +) -> anyhow::Result { let response = server .wait_for_event(|event| { matches!( diff --git a/codex-rs/exec-server/tests/initialize.rs b/codex-rs/exec-server/tests/initialize.rs index 9c6739566..daf4306db 100644 --- a/codex-rs/exec-server/tests/initialize.rs +++ b/codex-rs/exec-server/tests/initialize.rs @@ -2,10 +2,10 @@ mod common; -use codex_app_server_protocol::JSONRPCMessage; -use codex_app_server_protocol::JSONRPCResponse; use codex_exec_server::InitializeParams; use codex_exec_server::InitializeResponse; +use codex_exec_server_protocol::JSONRPCMessage; +use codex_exec_server_protocol::JSONRPCResponse; use common::exec_server::exec_server; use pretty_assertions::assert_eq; use uuid::Uuid; diff --git a/codex-rs/exec-server/tests/process.rs b/codex-rs/exec-server/tests/process.rs index 7a1da19ac..2255d4f8c 100644 --- a/codex-rs/exec-server/tests/process.rs +++ b/codex-rs/exec-server/tests/process.rs @@ -2,8 +2,6 @@ mod common; -use codex_app_server_protocol::JSONRPCMessage; -use codex_app_server_protocol::JSONRPCResponse; use codex_exec_server::ExecResponse; use codex_exec_server::InitializeParams; use codex_exec_server::InitializeResponse; @@ -12,6 +10,8 @@ use codex_exec_server::ReadResponse; use codex_exec_server::TerminateResponse; use codex_exec_server::WriteResponse; use codex_exec_server::WriteStatus; +use codex_exec_server_protocol::JSONRPCMessage; +use codex_exec_server_protocol::JSONRPCResponse; use codex_utils_path_uri::PathUri; use common::exec_server::exec_server; use pretty_assertions::assert_eq; diff --git a/codex-rs/exec-server/tests/websocket.rs b/codex-rs/exec-server/tests/websocket.rs index 3d0bebf10..4df163913 100644 --- a/codex-rs/exec-server/tests/websocket.rs +++ b/codex-rs/exec-server/tests/websocket.rs @@ -2,11 +2,11 @@ mod common; -use codex_app_server_protocol::JSONRPCError; -use codex_app_server_protocol::JSONRPCMessage; -use codex_app_server_protocol::JSONRPCResponse; use codex_exec_server::InitializeParams; use codex_exec_server::InitializeResponse; +use codex_exec_server_protocol::JSONRPCError; +use codex_exec_server_protocol::JSONRPCMessage; +use codex_exec_server_protocol::JSONRPCResponse; use common::exec_server::exec_server; use pretty_assertions::assert_eq; use tokio_tungstenite::connect_async; @@ -28,7 +28,7 @@ async fn exec_server_reports_malformed_websocket_json_and_keeps_running() -> any let JSONRPCMessage::Error(JSONRPCError { id, error }) = response else { panic!("expected malformed-message error response"); }; - assert_eq!(id, codex_app_server_protocol::RequestId::Integer(-1)); + assert_eq!(id, codex_exec_server_protocol::RequestId::Integer(-1)); assert_eq!(error.code, -32600); assert!( error @@ -70,15 +70,14 @@ async fn exec_server_reports_malformed_websocket_json_and_keeps_running() -> any #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn exec_server_accepts_binary_websocket_json() -> anyhow::Result<()> { let mut server = exec_server().await?; - let initialize_id = codex_app_server_protocol::RequestId::Integer(1); - let initialize = JSONRPCMessage::Request(codex_app_server_protocol::JSONRPCRequest { + let initialize_id = codex_exec_server_protocol::RequestId::Integer(1); + let initialize = JSONRPCMessage::Request(codex_exec_server_protocol::JSONRPCRequest { id: initialize_id.clone(), method: "initialize".to_string(), params: Some(serde_json::to_value(InitializeParams { client_name: "exec-server-binary-test".to_string(), resume_session_id: None, })?), - trace: None, }); server .send_raw_binary(serde_json::to_vec(&initialize)?)