From 712bfa04acb57206aa5df554a6855a0cd14dc9a6 Mon Sep 17 00:00:00 2001 From: Michael Bolin Date: Mon, 18 Aug 2025 09:36:57 -0700 Subject: [PATCH] chore: move mcp-server/src/wire_format.rs to protocol/src/mcp_protocol.rs (#2423) The existing `wire_format.rs` should share more types with the `codex-protocol` crate (like `AskForApproval` instead of maintaining a parallel `CodexToolCallApprovalPolicy` enum), so this PR moves `wire_format.rs` into `codex-protocol`, renaming it as `mcp-protocol.rs`. We also de-dupe types, where appropriate. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/2423). * #2424 * __->__ #2423 --- codex-rs/Cargo.lock | 6 ++ codex-rs/cli/Cargo.toml | 1 + codex-rs/cli/src/debug_sandbox.rs | 2 +- codex-rs/common/Cargo.toml | 1 + codex-rs/common/src/sandbox_mode_cli_arg.rs | 2 +- codex-rs/core/src/config.rs | 2 +- codex-rs/core/src/config_types.rs | 15 ----- codex-rs/core/src/environment_context.rs | 2 +- codex-rs/exec/Cargo.toml | 3 +- codex-rs/exec/src/lib.rs | 2 +- codex-rs/mcp-server/Cargo.toml | 1 + .../mcp-server/src/codex_message_processor.rs | 56 +++++++++---------- codex-rs/mcp-server/src/codex_tool_config.rs | 2 +- codex-rs/mcp-server/src/lib.rs | 1 - codex-rs/mcp-server/src/message_processor.rs | 2 +- .../tests/codex_message_processor_flow.rs | 28 +++++----- codex-rs/mcp-server/tests/common/Cargo.toml | 1 + .../mcp-server/tests/common/mcp_process.rs | 12 ++-- .../mcp-server/tests/create_conversation.rs | 14 ++--- codex-rs/mcp-server/tests/interrupt.rs | 16 +++--- codex-rs/mcp-server/tests/send_message.rs | 16 +++--- codex-rs/protocol/Cargo.toml | 3 + codex-rs/protocol/src/config_types.rs | 15 +++++ codex-rs/protocol/src/lib.rs | 1 + .../src/mcp_protocol.rs} | 24 ++++---- codex-rs/tui/src/lib.rs | 2 +- 26 files changed, 121 insertions(+), 109 deletions(-) rename codex-rs/{mcp-server/src/wire_format.rs => protocol/src/mcp_protocol.rs} (94%) diff --git a/codex-rs/Cargo.lock b/codex-rs/Cargo.lock index 9da3595e..10b5bf94 100644 --- a/codex-rs/Cargo.lock +++ b/codex-rs/Cargo.lock @@ -665,6 +665,7 @@ dependencies = [ "codex-exec", "codex-login", "codex-mcp-server", + "codex-protocol", "codex-tui", "serde_json", "tokio", @@ -678,6 +679,7 @@ version = "0.0.0" dependencies = [ "clap", "codex-core", + "codex-protocol", "serde", "toml 0.9.5", ] @@ -752,6 +754,7 @@ dependencies = [ "codex-common", "codex-core", "codex-ollama", + "codex-protocol", "core_test_support", "libc", "owo-colors", @@ -856,6 +859,7 @@ dependencies = [ "codex-arg0", "codex-core", "codex-login", + "codex-protocol", "mcp-types", "mcp_test_support", "pretty_assertions", @@ -896,6 +900,7 @@ name = "codex-protocol" version = "0.0.0" dependencies = [ "mcp-types", + "pretty_assertions", "serde", "serde_bytes", "serde_json", @@ -2781,6 +2786,7 @@ dependencies = [ "assert_cmd", "codex-core", "codex-mcp-server", + "codex-protocol", "mcp-types", "pretty_assertions", "serde", diff --git a/codex-rs/cli/Cargo.toml b/codex-rs/cli/Cargo.toml index 0f370691..0183ae28 100644 --- a/codex-rs/cli/Cargo.toml +++ b/codex-rs/cli/Cargo.toml @@ -25,6 +25,7 @@ codex-core = { path = "../core" } codex-exec = { path = "../exec" } codex-login = { path = "../login" } codex-mcp-server = { path = "../mcp-server" } +codex-protocol = { path = "../protocol" } codex-tui = { path = "../tui" } serde_json = "1" tokio = { version = "1", features = [ diff --git a/codex-rs/cli/src/debug_sandbox.rs b/codex-rs/cli/src/debug_sandbox.rs index 30e144ed..6fe7f003 100644 --- a/codex-rs/cli/src/debug_sandbox.rs +++ b/codex-rs/cli/src/debug_sandbox.rs @@ -3,11 +3,11 @@ use std::path::PathBuf; use codex_common::CliConfigOverrides; use codex_core::config::Config; use codex_core::config::ConfigOverrides; -use codex_core::config_types::SandboxMode; use codex_core::exec_env::create_env; use codex_core::landlock::spawn_command_under_linux_sandbox; use codex_core::seatbelt::spawn_command_under_seatbelt; use codex_core::spawn::StdioPolicy; +use codex_protocol::config_types::SandboxMode; use crate::LandlockCommand; use crate::SeatbeltCommand; diff --git a/codex-rs/common/Cargo.toml b/codex-rs/common/Cargo.toml index 1723098b..b1060057 100644 --- a/codex-rs/common/Cargo.toml +++ b/codex-rs/common/Cargo.toml @@ -9,6 +9,7 @@ workspace = true [dependencies] clap = { version = "4", features = ["derive", "wrap_help"], optional = true } codex-core = { path = "../core" } +codex-protocol = { path = "../protocol" } serde = { version = "1", optional = true } toml = { version = "0.9", optional = true } diff --git a/codex-rs/common/src/sandbox_mode_cli_arg.rs b/codex-rs/common/src/sandbox_mode_cli_arg.rs index 588637ae..fa5662ce 100644 --- a/codex-rs/common/src/sandbox_mode_cli_arg.rs +++ b/codex-rs/common/src/sandbox_mode_cli_arg.rs @@ -7,7 +7,7 @@ //! `config.toml`. use clap::ValueEnum; -use codex_core::config_types::SandboxMode; +use codex_protocol::config_types::SandboxMode; #[derive(Clone, Copy, Debug, ValueEnum)] #[value(rename_all = "kebab-case")] diff --git a/codex-rs/core/src/config.rs b/codex-rs/core/src/config.rs index e2a68d07..16a48dbc 100644 --- a/codex-rs/core/src/config.rs +++ b/codex-rs/core/src/config.rs @@ -3,7 +3,6 @@ use crate::config_types::History; use crate::config_types::McpServerConfig; use crate::config_types::ReasoningEffort; use crate::config_types::ReasoningSummary; -use crate::config_types::SandboxMode; use crate::config_types::SandboxWorkspaceWrite; use crate::config_types::ShellEnvironmentPolicy; use crate::config_types::ShellEnvironmentPolicyToml; @@ -16,6 +15,7 @@ use crate::model_provider_info::built_in_model_providers; use crate::openai_model_info::get_model_info; use crate::protocol::AskForApproval; use crate::protocol::SandboxPolicy; +use codex_protocol::config_types::SandboxMode; use dirs::home_dir; use serde::Deserialize; use std::collections::HashMap; diff --git a/codex-rs/core/src/config_types.rs b/codex-rs/core/src/config_types.rs index 17fd6104..927bb21e 100644 --- a/codex-rs/core/src/config_types.rs +++ b/codex-rs/core/src/config_types.rs @@ -78,21 +78,6 @@ pub enum HistoryPersistence { #[derive(Deserialize, Debug, Clone, PartialEq, Default)] pub struct Tui {} -#[derive(Deserialize, Debug, Clone, Copy, PartialEq, Default, Serialize, Display)] -#[serde(rename_all = "kebab-case")] -#[strum(serialize_all = "kebab-case")] -pub enum SandboxMode { - #[serde(rename = "read-only")] - #[default] - ReadOnly, - - #[serde(rename = "workspace-write")] - WorkspaceWrite, - - #[serde(rename = "danger-full-access")] - DangerFullAccess, -} - #[derive(Deserialize, Debug, Clone, PartialEq, Default)] pub struct SandboxWorkspaceWrite { #[serde(default)] diff --git a/codex-rs/core/src/environment_context.rs b/codex-rs/core/src/environment_context.rs index d31ddbc1..b37645a3 100644 --- a/codex-rs/core/src/environment_context.rs +++ b/codex-rs/core/src/environment_context.rs @@ -2,11 +2,11 @@ use serde::Deserialize; use serde::Serialize; use strum_macros::Display as DeriveDisplay; -use crate::config_types::SandboxMode; use crate::models::ContentItem; use crate::models::ResponseItem; use crate::protocol::AskForApproval; use crate::protocol::SandboxPolicy; +use codex_protocol::config_types::SandboxMode; use std::fmt::Display; use std::path::PathBuf; diff --git a/codex-rs/exec/Cargo.toml b/codex-rs/exec/Cargo.toml index 9847788d..89dc3951 100644 --- a/codex-rs/exec/Cargo.toml +++ b/codex-rs/exec/Cargo.toml @@ -26,6 +26,7 @@ codex-common = { path = "../common", features = [ ] } codex-core = { path = "../core" } codex-ollama = { path = "../ollama" } +codex-protocol = { path = "../protocol" } owo-colors = "4.2.0" serde_json = "1" shlex = "1.3.0" @@ -41,8 +42,8 @@ tracing-subscriber = { version = "0.3.19", features = ["env-filter"] } [dev-dependencies] assert_cmd = "2" +core_test_support = { path = "../core/tests/common" } libc = "0.2" predicates = "3" tempfile = "3.13.0" wiremock = "0.6" -core_test_support = { path = "../core/tests/common" } diff --git a/codex-rs/exec/src/lib.rs b/codex-rs/exec/src/lib.rs index e6b4d7fb..e18314fb 100644 --- a/codex-rs/exec/src/lib.rs +++ b/codex-rs/exec/src/lib.rs @@ -13,7 +13,6 @@ use codex_core::ConversationManager; use codex_core::NewConversation; use codex_core::config::Config; use codex_core::config::ConfigOverrides; -use codex_core::config_types::SandboxMode; use codex_core::protocol::AskForApproval; use codex_core::protocol::Event; use codex_core::protocol::EventMsg; @@ -22,6 +21,7 @@ use codex_core::protocol::Op; use codex_core::protocol::TaskCompleteEvent; use codex_core::util::is_inside_git_repo; use codex_ollama::DEFAULT_OSS_MODEL; +use codex_protocol::config_types::SandboxMode; use event_processor_with_human_output::EventProcessorWithHumanOutput; use event_processor_with_json_output::EventProcessorWithJsonOutput; use tracing::debug; diff --git a/codex-rs/mcp-server/Cargo.toml b/codex-rs/mcp-server/Cargo.toml index 6274ba8e..3f5c2a0f 100644 --- a/codex-rs/mcp-server/Cargo.toml +++ b/codex-rs/mcp-server/Cargo.toml @@ -19,6 +19,7 @@ anyhow = "1" codex-arg0 = { path = "../arg0" } codex-core = { path = "../core" } codex-login = { path = "../login" } +codex-protocol = { path = "../protocol" } mcp-types = { path = "../mcp-types" } schemars = "0.8.22" serde = { version = "1", features = ["derive"] } diff --git a/codex-rs/mcp-server/src/codex_message_processor.rs b/codex-rs/mcp-server/src/codex_message_processor.rs index c90fab86..d13bdbf3 100644 --- a/codex-rs/mcp-server/src/codex_message_processor.rs +++ b/codex-rs/mcp-server/src/codex_message_processor.rs @@ -25,36 +25,36 @@ use crate::error_code::INVALID_REQUEST_ERROR_CODE; use crate::json_to_toml::json_to_toml; use crate::outgoing_message::OutgoingMessageSender; use crate::outgoing_message::OutgoingNotification; -use crate::wire_format::APPLY_PATCH_APPROVAL_METHOD; -use crate::wire_format::AddConversationListenerParams; -use crate::wire_format::AddConversationSubscriptionResponse; -use crate::wire_format::ApplyPatchApprovalParams; -use crate::wire_format::ApplyPatchApprovalResponse; -use crate::wire_format::ClientRequest; -use crate::wire_format::ConversationId; -use crate::wire_format::EXEC_COMMAND_APPROVAL_METHOD; -use crate::wire_format::ExecCommandApprovalParams; -use crate::wire_format::ExecCommandApprovalResponse; -use crate::wire_format::InputItem as WireInputItem; -use crate::wire_format::InterruptConversationParams; -use crate::wire_format::InterruptConversationResponse; -use crate::wire_format::LOGIN_CHATGPT_COMPLETE_EVENT; -use crate::wire_format::LoginChatGptCompleteNotification; -use crate::wire_format::LoginChatGptResponse; -use crate::wire_format::NewConversationParams; -use crate::wire_format::NewConversationResponse; -use crate::wire_format::RemoveConversationListenerParams; -use crate::wire_format::RemoveConversationSubscriptionResponse; -use crate::wire_format::SendUserMessageParams; -use crate::wire_format::SendUserMessageResponse; -use crate::wire_format::SendUserTurnParams; -use crate::wire_format::SendUserTurnResponse; use codex_core::protocol::InputItem as CoreInputItem; use codex_core::protocol::Op; use codex_login::CLIENT_ID; use codex_login::ServerOptions as LoginServerOptions; use codex_login::ShutdownHandle; use codex_login::run_login_server; +use codex_protocol::mcp_protocol::APPLY_PATCH_APPROVAL_METHOD; +use codex_protocol::mcp_protocol::AddConversationListenerParams; +use codex_protocol::mcp_protocol::AddConversationSubscriptionResponse; +use codex_protocol::mcp_protocol::ApplyPatchApprovalParams; +use codex_protocol::mcp_protocol::ApplyPatchApprovalResponse; +use codex_protocol::mcp_protocol::ClientRequest; +use codex_protocol::mcp_protocol::ConversationId; +use codex_protocol::mcp_protocol::EXEC_COMMAND_APPROVAL_METHOD; +use codex_protocol::mcp_protocol::ExecCommandApprovalParams; +use codex_protocol::mcp_protocol::ExecCommandApprovalResponse; +use codex_protocol::mcp_protocol::InputItem as WireInputItem; +use codex_protocol::mcp_protocol::InterruptConversationParams; +use codex_protocol::mcp_protocol::InterruptConversationResponse; +use codex_protocol::mcp_protocol::LOGIN_CHATGPT_COMPLETE_EVENT; +use codex_protocol::mcp_protocol::LoginChatGptCompleteNotification; +use codex_protocol::mcp_protocol::LoginChatGptResponse; +use codex_protocol::mcp_protocol::NewConversationParams; +use codex_protocol::mcp_protocol::NewConversationResponse; +use codex_protocol::mcp_protocol::RemoveConversationListenerParams; +use codex_protocol::mcp_protocol::RemoveConversationSubscriptionResponse; +use codex_protocol::mcp_protocol::SendUserMessageParams; +use codex_protocol::mcp_protocol::SendUserMessageResponse; +use codex_protocol::mcp_protocol::SendUserTurnParams; +use codex_protocol::mcp_protocol::SendUserTurnResponse; // Duration before a ChatGPT login attempt is abandoned. const LOGIN_CHATGPT_TIMEOUT: Duration = Duration::from_secs(10 * 60); @@ -237,7 +237,7 @@ impl CodexMessageProcessor { self.outgoing .send_response( request_id, - crate::wire_format::CancelLoginChatGptResponse {}, + codex_protocol::mcp_protocol::CancelLoginChatGptResponse {}, ) .await; } else { @@ -595,7 +595,7 @@ fn derive_config_from_params( profile, cwd, approval_policy, - sandbox, + sandbox: sandbox_mode, config: cli_overrides, base_instructions, include_plan_tool, @@ -605,8 +605,8 @@ fn derive_config_from_params( model, config_profile: profile, cwd: cwd.map(PathBuf::from), - approval_policy: approval_policy.map(Into::into), - sandbox_mode: sandbox.map(Into::into), + approval_policy, + sandbox_mode, model_provider: None, codex_linux_sandbox_exe, base_instructions, diff --git a/codex-rs/mcp-server/src/codex_tool_config.rs b/codex-rs/mcp-server/src/codex_tool_config.rs index 906921a0..5993c10f 100644 --- a/codex-rs/mcp-server/src/codex_tool_config.rs +++ b/codex-rs/mcp-server/src/codex_tool_config.rs @@ -1,7 +1,7 @@ //! Configuration object accepted by the `codex` MCP tool-call. -use codex_core::config_types::SandboxMode; use codex_core::protocol::AskForApproval; +use codex_protocol::config_types::SandboxMode; use mcp_types::Tool; use mcp_types::ToolInputSchema; use schemars::JsonSchema; diff --git a/codex-rs/mcp-server/src/lib.rs b/codex-rs/mcp-server/src/lib.rs index f30daa92..e22df1f9 100644 --- a/codex-rs/mcp-server/src/lib.rs +++ b/codex-rs/mcp-server/src/lib.rs @@ -24,7 +24,6 @@ mod json_to_toml; pub(crate) mod message_processor; mod outgoing_message; mod patch_approval; -pub mod wire_format; use crate::message_processor::MessageProcessor; use crate::outgoing_message::OutgoingMessage; diff --git a/codex-rs/mcp-server/src/message_processor.rs b/codex-rs/mcp-server/src/message_processor.rs index 2143cecc..1ddcc6bc 100644 --- a/codex-rs/mcp-server/src/message_processor.rs +++ b/codex-rs/mcp-server/src/message_processor.rs @@ -9,7 +9,7 @@ use crate::codex_tool_config::create_tool_for_codex_tool_call_param; use crate::codex_tool_config::create_tool_for_codex_tool_call_reply_param; use crate::error_code::INVALID_REQUEST_ERROR_CODE; use crate::outgoing_message::OutgoingMessageSender; -use crate::wire_format::ClientRequest; +use codex_protocol::mcp_protocol::ClientRequest; use codex_core::ConversationManager; use codex_core::config::Config as CodexConfig; diff --git a/codex-rs/mcp-server/tests/codex_message_processor_flow.rs b/codex-rs/mcp-server/tests/codex_message_processor_flow.rs index 03706af1..092b1352 100644 --- a/codex-rs/mcp-server/tests/codex_message_processor_flow.rs +++ b/codex-rs/mcp-server/tests/codex_message_processor_flow.rs @@ -5,17 +5,17 @@ use codex_core::protocol::SandboxPolicy; use codex_core::protocol_config_types::ReasoningEffort; use codex_core::protocol_config_types::ReasoningSummary; use codex_core::spawn::CODEX_SANDBOX_NETWORK_DISABLED_ENV_VAR; -use codex_mcp_server::wire_format::AddConversationListenerParams; -use codex_mcp_server::wire_format::AddConversationSubscriptionResponse; -use codex_mcp_server::wire_format::EXEC_COMMAND_APPROVAL_METHOD; -use codex_mcp_server::wire_format::NewConversationParams; -use codex_mcp_server::wire_format::NewConversationResponse; -use codex_mcp_server::wire_format::RemoveConversationListenerParams; -use codex_mcp_server::wire_format::RemoveConversationSubscriptionResponse; -use codex_mcp_server::wire_format::SendUserMessageParams; -use codex_mcp_server::wire_format::SendUserMessageResponse; -use codex_mcp_server::wire_format::SendUserTurnParams; -use codex_mcp_server::wire_format::SendUserTurnResponse; +use codex_protocol::mcp_protocol::AddConversationListenerParams; +use codex_protocol::mcp_protocol::AddConversationSubscriptionResponse; +use codex_protocol::mcp_protocol::EXEC_COMMAND_APPROVAL_METHOD; +use codex_protocol::mcp_protocol::NewConversationParams; +use codex_protocol::mcp_protocol::NewConversationResponse; +use codex_protocol::mcp_protocol::RemoveConversationListenerParams; +use codex_protocol::mcp_protocol::RemoveConversationSubscriptionResponse; +use codex_protocol::mcp_protocol::SendUserMessageParams; +use codex_protocol::mcp_protocol::SendUserMessageResponse; +use codex_protocol::mcp_protocol::SendUserTurnParams; +use codex_protocol::mcp_protocol::SendUserTurnResponse; use mcp_test_support::McpProcess; use mcp_test_support::create_final_assistant_message_sse_response; use mcp_test_support::create_mock_chat_completions_server; @@ -113,7 +113,7 @@ async fn test_codex_jsonrpc_conversation_flow() { let send_user_id = mcp .send_send_user_message_request(SendUserMessageParams { conversation_id, - items: vec![codex_mcp_server::wire_format::InputItem::Text { + items: vec![codex_protocol::mcp_protocol::InputItem::Text { text: "text".to_string(), }], }) @@ -263,7 +263,7 @@ async fn test_send_user_turn_changes_approval_policy_behavior() { let send_user_id = mcp .send_send_user_message_request(SendUserMessageParams { conversation_id, - items: vec![codex_mcp_server::wire_format::InputItem::Text { + items: vec![codex_protocol::mcp_protocol::InputItem::Text { text: "run python".to_string(), }], }) @@ -311,7 +311,7 @@ async fn test_send_user_turn_changes_approval_policy_behavior() { let send_turn_id = mcp .send_send_user_turn_request(SendUserTurnParams { conversation_id, - items: vec![codex_mcp_server::wire_format::InputItem::Text { + items: vec![codex_protocol::mcp_protocol::InputItem::Text { text: "run python again".to_string(), }], cwd: working_directory.clone(), diff --git a/codex-rs/mcp-server/tests/common/Cargo.toml b/codex-rs/mcp-server/tests/common/Cargo.toml index 3528ad6e..a9b4ddfb 100644 --- a/codex-rs/mcp-server/tests/common/Cargo.toml +++ b/codex-rs/mcp-server/tests/common/Cargo.toml @@ -11,6 +11,7 @@ anyhow = "1" assert_cmd = "2" codex-core = { path = "../../../core" } codex-mcp-server = { path = "../.." } +codex-protocol = { path = "../../../protocol" } mcp-types = { path = "../../../mcp-types" } pretty_assertions = "1.4.1" serde = { version = "1" } diff --git a/codex-rs/mcp-server/tests/common/mcp_process.rs b/codex-rs/mcp-server/tests/common/mcp_process.rs index 5d2dbac0..6793dcaf 100644 --- a/codex-rs/mcp-server/tests/common/mcp_process.rs +++ b/codex-rs/mcp-server/tests/common/mcp_process.rs @@ -12,12 +12,12 @@ use tokio::process::ChildStdout; use anyhow::Context; use assert_cmd::prelude::*; use codex_mcp_server::CodexToolCallParam; -use codex_mcp_server::wire_format::AddConversationListenerParams; -use codex_mcp_server::wire_format::InterruptConversationParams; -use codex_mcp_server::wire_format::NewConversationParams; -use codex_mcp_server::wire_format::RemoveConversationListenerParams; -use codex_mcp_server::wire_format::SendUserMessageParams; -use codex_mcp_server::wire_format::SendUserTurnParams; +use codex_protocol::mcp_protocol::AddConversationListenerParams; +use codex_protocol::mcp_protocol::InterruptConversationParams; +use codex_protocol::mcp_protocol::NewConversationParams; +use codex_protocol::mcp_protocol::RemoveConversationListenerParams; +use codex_protocol::mcp_protocol::SendUserMessageParams; +use codex_protocol::mcp_protocol::SendUserTurnParams; use mcp_types::CallToolRequestParams; use mcp_types::ClientCapabilities; diff --git a/codex-rs/mcp-server/tests/create_conversation.rs b/codex-rs/mcp-server/tests/create_conversation.rs index 86f6963b..81cc1f3e 100644 --- a/codex-rs/mcp-server/tests/create_conversation.rs +++ b/codex-rs/mcp-server/tests/create_conversation.rs @@ -1,12 +1,12 @@ use std::path::Path; -use codex_mcp_server::wire_format::AddConversationListenerParams; -use codex_mcp_server::wire_format::AddConversationSubscriptionResponse; -use codex_mcp_server::wire_format::InputItem; -use codex_mcp_server::wire_format::NewConversationParams; -use codex_mcp_server::wire_format::NewConversationResponse; -use codex_mcp_server::wire_format::SendUserMessageParams; -use codex_mcp_server::wire_format::SendUserMessageResponse; +use codex_protocol::mcp_protocol::AddConversationListenerParams; +use codex_protocol::mcp_protocol::AddConversationSubscriptionResponse; +use codex_protocol::mcp_protocol::InputItem; +use codex_protocol::mcp_protocol::NewConversationParams; +use codex_protocol::mcp_protocol::NewConversationResponse; +use codex_protocol::mcp_protocol::SendUserMessageParams; +use codex_protocol::mcp_protocol::SendUserMessageResponse; use mcp_test_support::McpProcess; use mcp_test_support::create_final_assistant_message_sse_response; use mcp_test_support::create_mock_chat_completions_server; diff --git a/codex-rs/mcp-server/tests/interrupt.rs b/codex-rs/mcp-server/tests/interrupt.rs index 08406d37..113a8dd2 100644 --- a/codex-rs/mcp-server/tests/interrupt.rs +++ b/codex-rs/mcp-server/tests/interrupt.rs @@ -5,13 +5,13 @@ use std::path::Path; use codex_core::protocol::TurnAbortReason; use codex_core::spawn::CODEX_SANDBOX_NETWORK_DISABLED_ENV_VAR; -use codex_mcp_server::wire_format::AddConversationListenerParams; -use codex_mcp_server::wire_format::InterruptConversationParams; -use codex_mcp_server::wire_format::InterruptConversationResponse; -use codex_mcp_server::wire_format::NewConversationParams; -use codex_mcp_server::wire_format::NewConversationResponse; -use codex_mcp_server::wire_format::SendUserMessageParams; -use codex_mcp_server::wire_format::SendUserMessageResponse; +use codex_protocol::mcp_protocol::AddConversationListenerParams; +use codex_protocol::mcp_protocol::InterruptConversationParams; +use codex_protocol::mcp_protocol::InterruptConversationResponse; +use codex_protocol::mcp_protocol::NewConversationParams; +use codex_protocol::mcp_protocol::NewConversationResponse; +use codex_protocol::mcp_protocol::SendUserMessageParams; +use codex_protocol::mcp_protocol::SendUserMessageResponse; use mcp_types::JSONRPCResponse; use mcp_types::RequestId; use tempfile::TempDir; @@ -105,7 +105,7 @@ async fn shell_command_interruption() -> anyhow::Result<()> { let send_user_id = mcp .send_send_user_message_request(SendUserMessageParams { conversation_id, - items: vec![codex_mcp_server::wire_format::InputItem::Text { + items: vec![codex_protocol::mcp_protocol::InputItem::Text { text: "run first sleep command".to_string(), }], }) diff --git a/codex-rs/mcp-server/tests/send_message.rs b/codex-rs/mcp-server/tests/send_message.rs index d96d1e09..8f607776 100644 --- a/codex-rs/mcp-server/tests/send_message.rs +++ b/codex-rs/mcp-server/tests/send_message.rs @@ -1,13 +1,13 @@ use std::path::Path; -use codex_mcp_server::wire_format::AddConversationListenerParams; -use codex_mcp_server::wire_format::AddConversationSubscriptionResponse; -use codex_mcp_server::wire_format::ConversationId; -use codex_mcp_server::wire_format::InputItem; -use codex_mcp_server::wire_format::NewConversationParams; -use codex_mcp_server::wire_format::NewConversationResponse; -use codex_mcp_server::wire_format::SendUserMessageParams; -use codex_mcp_server::wire_format::SendUserMessageResponse; +use codex_protocol::mcp_protocol::AddConversationListenerParams; +use codex_protocol::mcp_protocol::AddConversationSubscriptionResponse; +use codex_protocol::mcp_protocol::ConversationId; +use codex_protocol::mcp_protocol::InputItem; +use codex_protocol::mcp_protocol::NewConversationParams; +use codex_protocol::mcp_protocol::NewConversationResponse; +use codex_protocol::mcp_protocol::SendUserMessageParams; +use codex_protocol::mcp_protocol::SendUserMessageResponse; use mcp_test_support::McpProcess; use mcp_test_support::create_final_assistant_message_sse_response; use mcp_test_support::create_mock_chat_completions_server; diff --git a/codex-rs/protocol/Cargo.toml b/codex-rs/protocol/Cargo.toml index 43c5eac8..9525d043 100644 --- a/codex-rs/protocol/Cargo.toml +++ b/codex-rs/protocol/Cargo.toml @@ -18,3 +18,6 @@ serde_json = "1" strum = "0.27.2" strum_macros = "0.27.2" uuid = { version = "1", features = ["serde", "v4"] } + +[dev-dependencies] +pretty_assertions = "1.4.1" diff --git a/codex-rs/protocol/src/config_types.rs b/codex-rs/protocol/src/config_types.rs index b4525d79..3641a81d 100644 --- a/codex-rs/protocol/src/config_types.rs +++ b/codex-rs/protocol/src/config_types.rs @@ -29,3 +29,18 @@ pub enum ReasoningSummary { /// Option to disable reasoning summaries. None, } + +#[derive(Deserialize, Debug, Clone, Copy, PartialEq, Default, Serialize, Display)] +#[serde(rename_all = "kebab-case")] +#[strum(serialize_all = "kebab-case")] +pub enum SandboxMode { + #[serde(rename = "read-only")] + #[default] + ReadOnly, + + #[serde(rename = "workspace-write")] + WorkspaceWrite, + + #[serde(rename = "danger-full-access")] + DangerFullAccess, +} diff --git a/codex-rs/protocol/src/lib.rs b/codex-rs/protocol/src/lib.rs index ec6a4195..458ae659 100644 --- a/codex-rs/protocol/src/lib.rs +++ b/codex-rs/protocol/src/lib.rs @@ -1,4 +1,5 @@ pub mod config_types; +pub mod mcp_protocol; pub mod message_history; pub mod parse_command; pub mod plan_tool; diff --git a/codex-rs/mcp-server/src/wire_format.rs b/codex-rs/protocol/src/mcp_protocol.rs similarity index 94% rename from codex-rs/mcp-server/src/wire_format.rs rename to codex-rs/protocol/src/mcp_protocol.rs index 786a512e..5110f469 100644 --- a/codex-rs/mcp-server/src/wire_format.rs +++ b/codex-rs/protocol/src/mcp_protocol.rs @@ -2,19 +2,17 @@ use std::collections::HashMap; use std::fmt::Display; use std::path::PathBuf; -use codex_core::protocol::AskForApproval; -use codex_core::protocol::FileChange; -use codex_core::protocol::ReviewDecision; -use codex_core::protocol::SandboxPolicy; -use codex_core::protocol::TurnAbortReason; -use codex_core::protocol_config_types::ReasoningEffort; -use codex_core::protocol_config_types::ReasoningSummary; +use crate::config_types::ReasoningEffort; +use crate::config_types::ReasoningSummary; +use crate::config_types::SandboxMode; +use crate::protocol::AskForApproval; +use crate::protocol::FileChange; +use crate::protocol::ReviewDecision; +use crate::protocol::SandboxPolicy; +use crate::protocol::TurnAbortReason; use mcp_types::RequestId; use serde::Deserialize; use serde::Serialize; - -use crate::codex_tool_config::CodexToolCallApprovalPolicy; -use crate::codex_tool_config::CodexToolCallSandboxMode; use uuid::Uuid; #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] @@ -91,11 +89,11 @@ pub struct NewConversationParams { /// Approval policy for shell commands generated by the model: /// `untrusted`, `on-failure`, `on-request`, `never`. #[serde(skip_serializing_if = "Option::is_none")] - pub approval_policy: Option, + pub approval_policy: Option, /// Sandbox mode: `read-only`, `workspace-write`, or `danger-full-access`. #[serde(skip_serializing_if = "Option::is_none")] - pub sandbox: Option, + pub sandbox: Option, /// Individual config settings that will override what is in /// CODEX_HOME/config.toml. @@ -308,7 +306,7 @@ mod tests { model: Some("gpt-5".to_string()), profile: None, cwd: None, - approval_policy: Some(CodexToolCallApprovalPolicy::OnRequest), + approval_policy: Some(AskForApproval::OnRequest), sandbox: None, config: None, base_instructions: None, diff --git a/codex-rs/tui/src/lib.rs b/codex-rs/tui/src/lib.rs index 2d9210ca..e43367a0 100644 --- a/codex-rs/tui/src/lib.rs +++ b/codex-rs/tui/src/lib.rs @@ -10,11 +10,11 @@ use codex_core::config::ConfigOverrides; use codex_core::config::ConfigToml; use codex_core::config::find_codex_home; use codex_core::config::load_config_as_toml_with_cli_overrides; -use codex_core::config_types::SandboxMode; use codex_core::protocol::AskForApproval; use codex_core::protocol::SandboxPolicy; use codex_login::CodexAuth; use codex_ollama::DEFAULT_OSS_MODEL; +use codex_protocol::config_types::SandboxMode; use std::fs::OpenOptions; use std::path::PathBuf; use tracing::error;