diff --git a/Cargo.lock b/Cargo.lock index 140b585c..6706ce2a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -136,9 +136,9 @@ dependencies = [ [[package]] name = "agent-client-protocol-schema" -version = "0.13.8" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fec685c82933a27b9d0c34594749b8b47d26ab4c2fb0e7bee268798cebe1c8b" +checksum = "b4e7eb6f1e554741f621ae4abb046d4fbb3cb88541bc599693ae7f9aa30b72eb" dependencies = [ "anyhow", "derive_more", diff --git a/Cargo.toml b/Cargo.toml index d6b9e9fe..cd75b697 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,7 @@ agent-client-protocol-trace-viewer = { path = "src/agent-client-protocol-trace-v yopo = { package = "agent-client-protocol-yopo", path = "src/yopo" } # Protocol -agent-client-protocol-schema = { version = "=0.13.8", features = ["tracing"] } +agent-client-protocol-schema = { version = "=0.14.0", features = ["tracing"] } # Core async runtime tokio = { version = "1.52", default-features = false } diff --git a/src/agent-client-protocol-conductor/src/conductor.rs b/src/agent-client-protocol-conductor/src/conductor.rs index eb7c0cf2..d2158991 100644 --- a/src/agent-client-protocol-conductor/src/conductor.rs +++ b/src/agent-client-protocol-conductor/src/conductor.rs @@ -121,7 +121,7 @@ use agent_client_protocol::{ }; use agent_client_protocol::{ HandleDispatchFrom, - schema::{InitializeProxyRequest, InitializeRequest}, + schema::{InitializeProxyRequest, v1::InitializeRequest}, util::MatchDispatchFrom, }; use agent_client_protocol::{Handled, schema::SuccessorMessage}; diff --git a/src/agent-client-protocol-conductor/src/lib.rs b/src/agent-client-protocol-conductor/src/lib.rs index b886f40b..4136195f 100644 --- a/src/agent-client-protocol-conductor/src/lib.rs +++ b/src/agent-client-protocol-conductor/src/lib.rs @@ -79,7 +79,7 @@ pub use self::conductor::*; use clap::{Parser, Subcommand}; use agent_client_protocol::{AcpAgent, Stdio}; -use agent_client_protocol::{Client, Conductor, DynConnectTo, schema::InitializeRequest}; +use agent_client_protocol::{Client, Conductor, DynConnectTo, schema::v1::InitializeRequest}; use tracing::Instrument; use tracing_subscriber::{EnvFilter, layer::SubscriberExt, util::SubscriberInitExt}; diff --git a/src/agent-client-protocol-conductor/src/trace.rs b/src/agent-client-protocol-conductor/src/trace.rs index 59647d18..dc6a03fd 100644 --- a/src/agent-client-protocol-conductor/src/trace.rs +++ b/src/agent-client-protocol-conductor/src/trace.rs @@ -9,9 +9,10 @@ use std::io::{BufWriter, Write}; use std::path::Path; use std::time::Instant; -use agent_client_protocol::schema::{ - McpOverAcpMessage, RequestId, Response as RpcResponse, SuccessorMessage, +use agent_client_protocol::schema::v1::{ + Notification as RpcNotification, Request as RpcRequest, RequestId, Response as RpcResponse, }; +use agent_client_protocol::schema::{McpOverAcpMessage, SuccessorMessage}; use agent_client_protocol::{ DynConnectTo, JsonRpcMessage, RawJsonRpcMessage, RawJsonRpcParams, Role, UntypedMessage, }; @@ -559,16 +560,14 @@ impl MessageInfo { /// - `_mcp/message` messages are detected and marked as MCP protocol /// /// Returns (protocol, method, params). - fn from_request(req: agent_client_protocol::schema::Request) -> Self { + fn from_request(req: RpcRequest) -> Self { let untyped = UntypedMessage::parse_message(&req.method, ¶ms_from_transport(req.params)) .expect("untyped message is infallible"); Self::from_untyped(Successor(false), Some(req.id), Protocol::Acp, untyped) } - fn from_notification( - notification: agent_client_protocol::schema::Notification, - ) -> Self { + fn from_notification(notification: RpcNotification) -> Self { let untyped = UntypedMessage::parse_message( ¬ification.method, ¶ms_from_transport(notification.params), diff --git a/src/agent-client-protocol-conductor/tests/initialization_sequence.rs b/src/agent-client-protocol-conductor/tests/initialization_sequence.rs index 03e9b347..de79ddaf 100644 --- a/src/agent-client-protocol-conductor/tests/initialization_sequence.rs +++ b/src/agent-client-protocol-conductor/tests/initialization_sequence.rs @@ -5,10 +5,8 @@ //! 2. Multi-component chains: proxies receive `InitializeProxyRequest` //! 3. Last component (agent) receives `InitializeRequest` -use agent_client_protocol::schema::{ - AgentCapabilities, InitializeProxyRequest, InitializeRequest, InitializeResponse, - ProtocolVersion, -}; +use agent_client_protocol::schema::v1::{AgentCapabilities, InitializeRequest, InitializeResponse}; +use agent_client_protocol::schema::{InitializeProxyRequest, ProtocolVersion}; use agent_client_protocol::{Agent, Client, Conductor, ConnectTo, DynConnectTo, Proxy}; use agent_client_protocol_conductor::{ConductorImpl, ProxiesAndAgent}; use agent_client_protocol_test::testy::Testy; diff --git a/src/agent-client-protocol-conductor/tests/mcp-integration.rs b/src/agent-client-protocol-conductor/tests/mcp-integration.rs index 1464c229..d67628ea 100644 --- a/src/agent-client-protocol-conductor/tests/mcp-integration.rs +++ b/src/agent-client-protocol-conductor/tests/mcp-integration.rs @@ -8,9 +8,10 @@ mod mcp_integration; use agent_client_protocol::Agent; -use agent_client_protocol::schema::{ - ContentBlock, InitializeRequest, NewSessionRequest, PromptRequest, ProtocolVersion, - SessionNotification, TextContent, +use agent_client_protocol::schema::ProtocolVersion; +use agent_client_protocol::schema::v1::{ + ContentBlock, InitializeRequest, NewSessionRequest, PromptRequest, SessionNotification, + TextContent, }; use agent_client_protocol_conductor::{ConductorImpl, ProxiesAndAgent}; use agent_client_protocol_polyfill::mcp_over_acp::McpOverAcpPolyfill; diff --git a/src/agent-client-protocol-conductor/tests/mcp_server_handler_chain.rs b/src/agent-client-protocol-conductor/tests/mcp_server_handler_chain.rs index d91b4993..fa2926fe 100644 --- a/src/agent-client-protocol-conductor/tests/mcp_server_handler_chain.rs +++ b/src/agent-client-protocol-conductor/tests/mcp_server_handler_chain.rs @@ -6,9 +6,10 @@ //! from being invoked. use agent_client_protocol::mcp_server::McpServer; -use agent_client_protocol::schema::{ +use agent_client_protocol::schema::ProtocolVersion; +use agent_client_protocol::schema::v1::{ AgentCapabilities, InitializeRequest, InitializeResponse, NewSessionRequest, - NewSessionResponse, ProtocolVersion, SessionId, + NewSessionResponse, SessionId, }; use agent_client_protocol::{Agent, Client, Conductor, ConnectTo, DynConnectTo, Proxy}; use agent_client_protocol_conductor::{ConductorImpl, ProxiesAndAgent}; diff --git a/src/agent-client-protocol-conductor/tests/meta_propagation.rs b/src/agent-client-protocol-conductor/tests/meta_propagation.rs index ae9710e7..b2476bc8 100644 --- a/src/agent-client-protocol-conductor/tests/meta_propagation.rs +++ b/src/agent-client-protocol-conductor/tests/meta_propagation.rs @@ -1,10 +1,11 @@ use std::sync::{Arc, Mutex}; -use agent_client_protocol::schema::{ - AgentCapabilities, ContentBlock, InitializeProxyRequest, InitializeRequest, InitializeResponse, - Meta, NewSessionRequest, NewSessionResponse, PromptRequest, PromptResponse, ProtocolVersion, - SessionId, StopReason, TextContent, +use agent_client_protocol::schema::v1::{ + AgentCapabilities, ContentBlock, InitializeRequest, InitializeResponse, Meta, + NewSessionRequest, NewSessionResponse, PromptRequest, PromptResponse, SessionId, StopReason, + TextContent, }; +use agent_client_protocol::schema::{InitializeProxyRequest, ProtocolVersion}; use agent_client_protocol::util::MatchDispatchFrom; use agent_client_protocol::{ Agent, Client, Conductor, ConnectTo, ConnectionTo, Dispatch, HandleDispatchFrom, Handled, diff --git a/src/agent-client-protocol-conductor/tests/request_cancellation.rs b/src/agent-client-protocol-conductor/tests/request_cancellation.rs index 6ff64ff5..c805cc79 100644 --- a/src/agent-client-protocol-conductor/tests/request_cancellation.rs +++ b/src/agent-client-protocol-conductor/tests/request_cancellation.rs @@ -21,14 +21,14 @@ use std::sync::{Arc, Mutex}; use std::time::Duration; use agent_client_protocol::DynConnectTo; -use agent_client_protocol::schema::{ +use agent_client_protocol::schema::v1::{ CancelRequestNotification, ContentBlock, ContentChunk, InitializeRequest, InitializeResponse, - McpConnectRequest, McpServer as SchemaMcpServer, NewSessionRequest, NewSessionResponse, - PermissionOption, PermissionOptionKind, PromptRequest, PromptResponse, ProtocolVersion, - RequestPermissionOutcome, RequestPermissionRequest, RequestPermissionResponse, - SelectedPermissionOutcome, SessionId, SessionNotification, SessionUpdate, StopReason, - ToolCallUpdate, ToolCallUpdateFields, + McpServer as SchemaMcpServer, NewSessionRequest, NewSessionResponse, PermissionOption, + PermissionOptionKind, PromptRequest, PromptResponse, RequestPermissionOutcome, + RequestPermissionRequest, RequestPermissionResponse, SelectedPermissionOutcome, SessionId, + SessionNotification, SessionUpdate, StopReason, ToolCallUpdate, ToolCallUpdateFields, }; +use agent_client_protocol::schema::{McpConnectRequest, ProtocolVersion}; use agent_client_protocol::{ Agent, ByteStreams, Client, Conductor, ConnectTo, ConnectionTo, Error, JsonRpcRequest, JsonRpcResponse, NullRun, Proxy, Responder, Role, SentRequest, diff --git a/src/agent-client-protocol-conductor/tests/scoped_mcp_server.rs b/src/agent-client-protocol-conductor/tests/scoped_mcp_server.rs index c052078f..41991e49 100644 --- a/src/agent-client-protocol-conductor/tests/scoped_mcp_server.rs +++ b/src/agent-client-protocol-conductor/tests/scoped_mcp_server.rs @@ -61,7 +61,7 @@ async fn test_scoped_mcp_server_through_session() -> Result<(), agent_client_pro ), async |cx| { // Initialize first - cx.send_request(agent_client_protocol::schema::InitializeRequest::new( + cx.send_request(agent_client_protocol::schema::v1::InitializeRequest::new( agent_client_protocol::schema::ProtocolVersion::LATEST, )) .block_task() diff --git a/src/agent-client-protocol-conductor/tests/trace_client_mcp_server.rs b/src/agent-client-protocol-conductor/tests/trace_client_mcp_server.rs index 8eb29117..45c204cb 100644 --- a/src/agent-client-protocol-conductor/tests/trace_client_mcp_server.rs +++ b/src/agent-client-protocol-conductor/tests/trace_client_mcp_server.rs @@ -10,7 +10,7 @@ //! verifies that MCP requests travel all the way back to the client. use agent_client_protocol::mcp_server::McpServer; -use agent_client_protocol::schema::{InitializeRequest, ProtocolVersion}; +use agent_client_protocol::schema::{ProtocolVersion, v1::InitializeRequest}; use agent_client_protocol::{Client, Role, RunWithConnectionTo}; use agent_client_protocol_conductor::trace::TraceEvent; use agent_client_protocol_conductor::{ConductorImpl, ProxiesAndAgent}; diff --git a/src/agent-client-protocol-conductor/tests/trace_mcp_tool_call.rs b/src/agent-client-protocol-conductor/tests/trace_mcp_tool_call.rs index d67492b5..decd8e0a 100644 --- a/src/agent-client-protocol-conductor/tests/trace_mcp_tool_call.rs +++ b/src/agent-client-protocol-conductor/tests/trace_mcp_tool_call.rs @@ -10,9 +10,10 @@ mod mcp_integration; -use agent_client_protocol::schema::{ - ContentBlock, InitializeRequest, NewSessionRequest, PromptRequest, ProtocolVersion, - SessionNotification, TextContent, +use agent_client_protocol::schema::ProtocolVersion; +use agent_client_protocol::schema::v1::{ + ContentBlock, InitializeRequest, NewSessionRequest, PromptRequest, SessionNotification, + TextContent, }; use agent_client_protocol_conductor::trace::TraceEvent; use agent_client_protocol_conductor::{ConductorImpl, ProxiesAndAgent}; diff --git a/src/agent-client-protocol-cookbook/src/lib.rs b/src/agent-client-protocol-cookbook/src/lib.rs index 11655abe..d42d8f66 100644 --- a/src/agent-client-protocol-cookbook/src/lib.rs +++ b/src/agent-client-protocol-cookbook/src/lib.rs @@ -61,7 +61,7 @@ pub mod one_shot_prompt { //! //! ``` //! use agent_client_protocol::{Client, Agent, ConnectTo}; - //! use agent_client_protocol::schema::{InitializeRequest, ProtocolVersion}; + //! use agent_client_protocol::schema::{ProtocolVersion, v1::InitializeRequest}; //! //! async fn ask_agent( //! transport: impl ConnectTo + 'static, @@ -114,7 +114,7 @@ pub mod one_shot_prompt { //! [`send_prompt`]: agent_client_protocol::ActiveSession::send_prompt //! [`read_to_string`]: agent_client_protocol::ActiveSession::read_to_string //! [`connecting_as_client`]: super::connecting_as_client - //! [`RequestPermissionRequest`]: agent_client_protocol::schema::RequestPermissionRequest + //! [`RequestPermissionRequest`]: agent_client_protocol::schema::v1::RequestPermissionRequest } pub mod connecting_as_client { @@ -128,7 +128,7 @@ pub mod connecting_as_client { //! //! ``` //! use agent_client_protocol::{Client, Agent, ConnectTo}; - //! use agent_client_protocol::schema::{InitializeRequest, ProtocolVersion}; + //! use agent_client_protocol::schema::{ProtocolVersion, v1::InitializeRequest}; //! //! async fn connect_to_agent(transport: impl ConnectTo) -> Result<(), agent_client_protocol::Error> { //! Client.builder() @@ -201,7 +201,7 @@ pub mod connecting_as_client { //! [`read_update`]: agent_client_protocol::ActiveSession::read_update //! [`read_to_string`]: agent_client_protocol::ActiveSession::read_to_string //! [`with_mcp_server`]: agent_client_protocol::SessionBuilder::with_mcp_server - //! [`RequestPermissionRequest`]: agent_client_protocol::schema::RequestPermissionRequest + //! [`RequestPermissionRequest`]: agent_client_protocol::schema::v1::RequestPermissionRequest //! [`on_receive_request`]: agent_client_protocol::Builder::on_receive_request } @@ -220,7 +220,7 @@ pub mod building_an_agent { //! //! ``` //! use agent_client_protocol::{Agent, Client, ConnectTo, Dispatch, ConnectionTo}; - //! use agent_client_protocol::schema::{ + //! use agent_client_protocol::schema::v1::{ //! InitializeRequest, InitializeResponse, AgentCapabilities, //! NewSessionRequest, NewSessionResponse, SessionId, //! PromptRequest, PromptResponse, StopReason, @@ -321,11 +321,11 @@ pub mod building_an_agent { //! For agents that will be composed with proxies, implement [`ConnectTo`]. //! See [`reusable_components`] for the pattern. //! - //! [`InitializeRequest`]: agent_client_protocol::schema::InitializeRequest - //! [`NewSessionRequest`]: agent_client_protocol::schema::NewSessionRequest - //! [`PromptRequest`]: agent_client_protocol::schema::PromptRequest - //! [`SessionNotification`]: agent_client_protocol::schema::SessionNotification - //! [`RequestPermissionRequest`]: agent_client_protocol::schema::RequestPermissionRequest + //! [`InitializeRequest`]: agent_client_protocol::schema::v1::InitializeRequest + //! [`NewSessionRequest`]: agent_client_protocol::schema::v1::NewSessionRequest + //! [`PromptRequest`]: agent_client_protocol::schema::v1::PromptRequest + //! [`SessionNotification`]: agent_client_protocol::schema::v1::SessionNotification + //! [`RequestPermissionRequest`]: agent_client_protocol::schema::v1::RequestPermissionRequest //! [`Agent`]: agent_client_protocol::Agent //! [`ConnectTo`]: agent_client_protocol::ConnectTo //! [`reusable_components`]: super::reusable_components @@ -342,7 +342,7 @@ pub mod reusable_components { //! //! ``` //! use agent_client_protocol::{ConnectTo, Agent, Client}; - //! use agent_client_protocol::schema::{ + //! use agent_client_protocol::schema::v1::{ //! InitializeRequest, InitializeResponse, AgentCapabilities, //! }; //! @@ -397,7 +397,7 @@ pub mod custom_message_handlers { //! //! ``` //! use agent_client_protocol::{HandleDispatchFrom, Dispatch, Handled, ConnectionTo, UntypedRole}; - //! use agent_client_protocol::schema::{InitializeRequest, InitializeResponse, AgentCapabilities}; + //! use agent_client_protocol::schema::v1::{AgentCapabilities, InitializeRequest, InitializeResponse}; //! use agent_client_protocol::util::MatchDispatch; //! //! struct MyHandler; @@ -583,7 +583,7 @@ pub mod per_session_mcp_server { //! ``` //! use agent_client_protocol::mcp_server::McpServer; //! use agent_client_protocol_rmcp::McpServerExt; - //! use agent_client_protocol::schema::NewSessionRequest; + //! use agent_client_protocol::schema::v1::NewSessionRequest; //! use agent_client_protocol::{Client, Proxy, Conductor, ConnectTo}; //! //! async fn run_proxy(transport: impl ConnectTo) -> Result<(), agent_client_protocol::Error> { @@ -642,7 +642,7 @@ pub mod per_session_mcp_server { //! ``` //! # use agent_client_protocol::mcp_server::McpServer; //! # use agent_client_protocol_rmcp::McpServerExt; - //! # use agent_client_protocol::schema::NewSessionRequest; + //! # use agent_client_protocol::schema::v1::NewSessionRequest; //! # use agent_client_protocol::{Client, Proxy, Conductor, ConnectTo}; //! # async fn run_proxy(transport: impl ConnectTo) -> Result<(), agent_client_protocol::Error> { //! Proxy.builder() @@ -674,7 +674,7 @@ pub mod per_session_mcp_server { //! [`start_session`]: agent_client_protocol::SessionBuilder::start_session //! [`proxy_remaining_messages`]: agent_client_protocol::ActiveSession::proxy_remaining_messages //! - //! [`NewSessionRequest`]: agent_client_protocol::schema::NewSessionRequest + //! [`NewSessionRequest`]: agent_client_protocol::schema::v1::NewSessionRequest //! [`on_proxy_session_start`]: agent_client_protocol::SessionBuilder::on_proxy_session_start //! [`block_task`]: agent_client_protocol::SessionBuilder::block_task //! [`start_session_proxy`]: agent_client_protocol::SessionBuilder::start_session_proxy diff --git a/src/agent-client-protocol-http/src/client.rs b/src/agent-client-protocol-http/src/client.rs index 8bb92340..c531bb58 100644 --- a/src/agent-client-protocol-http/src/client.rs +++ b/src/agent-client-protocol-http/src/client.rs @@ -5,7 +5,7 @@ use std::{ use agent_client_protocol::{ Agent, Channel, Client, ConnectTo, Error as AcpError, RawJsonRpcMessage, - schema::{RequestId, Response as RpcResponse}, + schema::v1::{RequestId, Response as RpcResponse}, }; use async_tungstenite::tungstenite::Message as WsMessage; use futures::{ @@ -793,7 +793,7 @@ mod tests { time::Duration, }; - use agent_client_protocol::schema::RequestId; + use agent_client_protocol::schema::v1::RequestId; use axum::{ Json, Router, extract::{WebSocketUpgrade, ws::Message as AxumWsMessage}, diff --git a/src/agent-client-protocol-http/src/connection.rs b/src/agent-client-protocol-http/src/connection.rs index 2c2b91e2..40233641 100644 --- a/src/agent-client-protocol-http/src/connection.rs +++ b/src/agent-client-protocol-http/src/connection.rs @@ -3,7 +3,7 @@ use std::{ sync::{Arc, Weak}, }; -use agent_client_protocol::{Channel, RawJsonRpcMessage, schema::RequestId}; +use agent_client_protocol::{Channel, RawJsonRpcMessage, schema::v1::RequestId}; use futures::{SinkExt, StreamExt}; use tokio::sync::{Mutex, RwLock, mpsc, watch}; use tracing::{debug, error, trace}; @@ -681,7 +681,7 @@ mod tests { assert!(matches!( message, - RawJsonRpcMessage::Response(agent_client_protocol::schema::Response::Result { + RawJsonRpcMessage::Response(agent_client_protocol::schema::v1::Response::Result { id: RequestId::Number(1), .. }) diff --git a/src/agent-client-protocol-http/src/http_server.rs b/src/agent-client-protocol-http/src/http_server.rs index d22c890a..bb30ac19 100644 --- a/src/agent-client-protocol-http/src/http_server.rs +++ b/src/agent-client-protocol-http/src/http_server.rs @@ -1,6 +1,6 @@ use std::{convert::Infallible, error::Error as _, sync::Arc, time::Duration}; -use agent_client_protocol::{RawJsonRpcMessage, schema::Response as RpcResponse}; +use agent_client_protocol::{RawJsonRpcMessage, schema::v1::Response as RpcResponse}; use axum::{ body::Body, extract::State, @@ -336,7 +336,7 @@ fn post_body_too_large_response() -> Response { mod tests { use std::sync::Arc; - use agent_client_protocol::{Channel, RawJsonRpcMessage, schema::RequestId}; + use agent_client_protocol::{Channel, RawJsonRpcMessage, schema::v1::RequestId}; use futures::{StreamExt, future::BoxFuture}; use serde_json::json; use tokio::{ diff --git a/src/agent-client-protocol-http/src/protocol.rs b/src/agent-client-protocol-http/src/protocol.rs index 1c746cf9..d9d23a51 100644 --- a/src/agent-client-protocol-http/src/protocol.rs +++ b/src/agent-client-protocol-http/src/protocol.rs @@ -145,7 +145,7 @@ fn apply_session_header_to_params( #[cfg(test)] mod tests { #[cfg(feature = "server")] - use agent_client_protocol::schema::RequestId; + use agent_client_protocol::schema::v1::RequestId; use axum::http::{HeaderMap, HeaderValue}; #[cfg(feature = "server")] use serde_json::json; diff --git a/src/agent-client-protocol-http/src/websocket_server.rs b/src/agent-client-protocol-http/src/websocket_server.rs index 279d6ee3..65a7fa20 100644 --- a/src/agent-client-protocol-http/src/websocket_server.rs +++ b/src/agent-client-protocol-http/src/websocket_server.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use agent_client_protocol::{Error as AcpError, RawJsonRpcMessage, schema::RequestId}; +use agent_client_protocol::{Error as AcpError, RawJsonRpcMessage, schema::v1::RequestId}; use axum::{ extract::ws::{Message as WsMessage, WebSocket, WebSocketUpgrade}, http::HeaderValue, @@ -154,7 +154,7 @@ async fn run_ws( mod tests { use agent_client_protocol::{ Channel, - schema::{RequestId, Response as RpcResponse}, + schema::v1::{RequestId, Response as RpcResponse}, }; use async_tungstenite::{tokio::connect_async, tungstenite::Message as ClientWsMessage}; use axum::{Router, extract::WebSocketUpgrade, routing::get}; diff --git a/src/agent-client-protocol-polyfill/src/mcp_over_acp/http.rs b/src/agent-client-protocol-polyfill/src/mcp_over_acp/http.rs index b8f05f21..88a8feac 100644 --- a/src/agent-client-protocol-polyfill/src/mcp_over_acp/http.rs +++ b/src/agent-client-protocol-polyfill/src/mcp_over_acp/http.rs @@ -3,7 +3,7 @@ use agent_client_protocol::{ BoxFuture, Channel, ConnectTo, RawJsonRpcMessage, RawJsonRpcParams, role::mcp, - schema::{ + schema::v1::{ Notification as RpcNotification, Request as RpcRequest, RequestId, Response as RpcResponse, }, }; diff --git a/src/agent-client-protocol-polyfill/src/mcp_over_acp/mod.rs b/src/agent-client-protocol-polyfill/src/mcp_over_acp/mod.rs index cce2d476..bbaf9d75 100644 --- a/src/agent-client-protocol-polyfill/src/mcp_over_acp/mod.rs +++ b/src/agent-client-protocol-polyfill/src/mcp_over_acp/mod.rs @@ -27,9 +27,12 @@ pub(crate) mod stdio; use std::collections::HashMap; use std::path::PathBuf; +use agent_client_protocol::schema::v1::{ + McpServer, McpServerHttp, McpServerStdio, NewSessionRequest, +}; use agent_client_protocol::schema::{ InitializeProxyRequest, McpConnectRequest, McpConnectResponse, McpDisconnectNotification, - McpOverAcpMessage, McpServer, McpServerHttp, McpServerStdio, NewSessionRequest, + McpOverAcpMessage, }; use agent_client_protocol::{ Agent, Client, Conductor, ConnectTo, ConnectionTo, Dispatch, Proxy, Role, diff --git a/src/agent-client-protocol-test/src/arrow_proxy.rs b/src/agent-client-protocol-test/src/arrow_proxy.rs index 6a006b99..9210cf05 100644 --- a/src/agent-client-protocol-test/src/arrow_proxy.rs +++ b/src/agent-client-protocol-test/src/arrow_proxy.rs @@ -3,7 +3,7 @@ //! This proxy demonstrates basic proxy functionality by intercepting //! `session/update` notifications and prepending `>` to the content. -use agent_client_protocol::schema::{ +use agent_client_protocol::schema::v1::{ ContentBlock, ContentChunk, SessionNotification, SessionUpdate, }; use agent_client_protocol::{Agent, Client, ConnectTo, Proxy}; diff --git a/src/agent-client-protocol-test/src/testy.rs b/src/agent-client-protocol-test/src/testy.rs index d882fdf7..2a3ef57c 100644 --- a/src/agent-client-protocol-test/src/testy.rs +++ b/src/agent-client-protocol-test/src/testy.rs @@ -2,7 +2,7 @@ //! //! The agent accepts JSON-serialized [`TestyCommand`] values as prompt text. -use agent_client_protocol::schema::{ +use agent_client_protocol::schema::v1::{ AgentCapabilities, ContentBlock, ContentChunk, InitializeRequest, InitializeResponse, McpServer, NewSessionRequest, NewSessionResponse, PromptRequest, PromptResponse, SessionId, SessionNotification, SessionUpdate, StopReason, TextContent, diff --git a/src/agent-client-protocol/README.md b/src/agent-client-protocol/README.md index 81f4f2c2..7f87bb64 100644 --- a/src/agent-client-protocol/README.md +++ b/src/agent-client-protocol/README.md @@ -21,7 +21,7 @@ The most common use case is connecting to an existing ACP agent as a client: ```rust use agent_client_protocol::{Client, Agent, ConnectTo}; -use agent_client_protocol::schema::{InitializeRequest, ProtocolVersion}; +use agent_client_protocol::schema::{ProtocolVersion, v1::InitializeRequest}; Client.builder() .name("my-client") diff --git a/src/agent-client-protocol/examples/simple_agent.rs b/src/agent-client-protocol/examples/simple_agent.rs index 9d839317..a40c0e56 100644 --- a/src/agent-client-protocol/examples/simple_agent.rs +++ b/src/agent-client-protocol/examples/simple_agent.rs @@ -1,4 +1,4 @@ -use agent_client_protocol::schema::{AgentCapabilities, InitializeRequest, InitializeResponse}; +use agent_client_protocol::schema::v1::{AgentCapabilities, InitializeRequest, InitializeResponse}; use agent_client_protocol::{Agent, Client, ConnectionTo, Dispatch, Result, Stdio}; #[tokio::main] diff --git a/src/agent-client-protocol/examples/yolo_one_shot_client.rs b/src/agent-client-protocol/examples/yolo_one_shot_client.rs index 33e72832..69c14d57 100644 --- a/src/agent-client-protocol/examples/yolo_one_shot_client.rs +++ b/src/agent-client-protocol/examples/yolo_one_shot_client.rs @@ -11,10 +11,11 @@ //! cargo run --example yolo_one_shot_client -- --command "python my_agent.py" "What is 2+2?" //! ``` -use agent_client_protocol::schema::{ - ContentBlock, InitializeRequest, NewSessionRequest, PromptRequest, ProtocolVersion, - RequestPermissionOutcome, RequestPermissionRequest, RequestPermissionResponse, - SelectedPermissionOutcome, SessionNotification, TextContent, +use agent_client_protocol::schema::ProtocolVersion; +use agent_client_protocol::schema::v1::{ + ContentBlock, InitializeRequest, NewSessionRequest, PromptRequest, RequestPermissionOutcome, + RequestPermissionRequest, RequestPermissionResponse, SelectedPermissionOutcome, + SessionNotification, TextContent, }; use agent_client_protocol::{AcpAgent, Agent, ConnectionTo}; use clap::Parser; diff --git a/src/agent-client-protocol/src/acp_agent.rs b/src/agent-client-protocol/src/acp_agent.rs index a41ced62..1a1b2f04 100644 --- a/src/agent-client-protocol/src/acp_agent.rs +++ b/src/agent-client-protocol/src/acp_agent.rs @@ -1,6 +1,6 @@ //! Utilities for connecting to ACP agents and proxies. //! -//! This module provides [`AcpAgent`], a convenient wrapper around [`crate::schema::McpServer`] +//! This module provides [`AcpAgent`], a convenient wrapper around [`crate::schema::v1::McpServer`] //! that can be parsed from either a command string or JSON configuration. use std::path::PathBuf; @@ -10,6 +10,7 @@ use std::sync::Arc; use async_process::Child; use std::pin::pin; +use crate::schema::v1::{EnvVariable, McpServer as SchemaMcpServer, McpServerStdio}; use crate::{Client, Conductor, Role}; /// Direction of a line being sent or received. @@ -30,7 +31,7 @@ pub enum LineDirection { /// byte stream serialization automatically. This is the primary way to connect to agents /// that run as separate executables. /// -/// This is a wrapper around [`crate::schema::McpServer`] that provides convenient parsing +/// This is a wrapper around [`crate::schema::v1::McpServer`] that provides convenient parsing /// from command-line strings or JSON configurations. /// /// # Use Cases @@ -56,7 +57,7 @@ pub enum LineDirection { /// let agent = AcpAgent::from_str(r#"{"type": "stdio", "name": "my-agent", "command": "python", "args": ["my_agent.py"], "env": []}"#).unwrap(); /// ``` pub struct AcpAgent { - server: crate::schema::McpServer, + server: SchemaMcpServer, debug_callback: Option>, } @@ -73,9 +74,9 @@ impl std::fmt::Debug for AcpAgent { } impl AcpAgent { - /// Create a new `AcpAgent` from an [`crate::schema::McpServer`] configuration. + /// Create a new `AcpAgent` from an [`crate::schema::v1::McpServer`] configuration. #[must_use] - pub fn new(server: crate::schema::McpServer) -> Self { + pub fn new(server: SchemaMcpServer) -> Self { Self { server, debug_callback: None, @@ -104,15 +105,15 @@ impl AcpAgent { .expect("valid bash command") } - /// Get the underlying [`crate::schema::McpServer`] configuration. + /// Get the underlying [`crate::schema::v1::McpServer`] configuration. #[must_use] - pub fn server(&self) -> &crate::schema::McpServer { + pub fn server(&self) -> &SchemaMcpServer { &self.server } - /// Convert into the underlying [`crate::schema::McpServer`] configuration. + /// Convert into the underlying [`crate::schema::v1::McpServer`] configuration. #[must_use] - pub fn into_server(self) -> crate::schema::McpServer { + pub fn into_server(self) -> SchemaMcpServer { self.server } @@ -155,7 +156,7 @@ impl AcpAgent { crate::Error, > { match &self.server { - crate::schema::McpServer::Stdio(stdio) => { + SchemaMcpServer::Stdio(stdio) => { let mut cmd = async_process::Command::new(&stdio.command); cmd.args(&stdio.args); for env_var in &stdio.env { @@ -182,10 +183,10 @@ impl AcpAgent { Ok((child_stdin, child_stdout, child_stderr, child)) } - crate::schema::McpServer::Http(_) => Err(crate::util::internal_error( + SchemaMcpServer::Http(_) => Err(crate::util::internal_error( "HTTP transport not yet supported by AcpAgent", )), - crate::schema::McpServer::Sse(_) => Err(crate::util::internal_error( + SchemaMcpServer::Sse(_) => Err(crate::util::internal_error( "SSE transport not yet supported by AcpAgent", )), _ => Err(crate::util::internal_error( @@ -387,7 +388,7 @@ impl AcpAgent { for (i, arg) in args.iter().enumerate() { if let Some((name, value)) = parse_env_var(arg) { - env.push(crate::schema::EnvVariable::new(name, value)); + env.push(EnvVariable::new(name, value)); command_idx = i + 1; } else { break; @@ -410,10 +411,8 @@ impl AcpAgent { .to_string(); Ok(AcpAgent { - server: crate::schema::McpServer::Stdio( - crate::schema::McpServerStdio::new(name, command) - .args(cmd_args) - .env(env), + server: SchemaMcpServer::Stdio( + McpServerStdio::new(name, command).args(cmd_args).env(env), ), debug_callback: None, }) @@ -449,7 +448,7 @@ impl FromStr for AcpAgent { let trimmed = s.trim(); if trimmed.starts_with('{') { - let server: crate::schema::McpServer = serde_json::from_str(trimmed) + let server: SchemaMcpServer = serde_json::from_str(trimmed) .map_err(|e| crate::util::internal_error(format!("Failed to parse JSON: {e}")))?; return Ok(Self { server, @@ -472,7 +471,7 @@ mod tests { fn test_parse_simple_command() { let agent = AcpAgent::from_str("python agent.py").unwrap(); match agent.server { - crate::schema::McpServer::Stdio(stdio) => { + SchemaMcpServer::Stdio(stdio) => { assert_eq!(stdio.name, "python"); assert_eq!(stdio.command, PathBuf::from("python")); assert_eq!(stdio.args, vec!["agent.py"]); @@ -486,7 +485,7 @@ mod tests { fn test_parse_command_with_args() { let agent = AcpAgent::from_str("node server.js --port 8080 --verbose").unwrap(); match agent.server { - crate::schema::McpServer::Stdio(stdio) => { + SchemaMcpServer::Stdio(stdio) => { assert_eq!(stdio.name, "node"); assert_eq!(stdio.command, PathBuf::from("node")); assert_eq!(stdio.args, vec!["server.js", "--port", "8080", "--verbose"]); @@ -500,7 +499,7 @@ mod tests { fn test_parse_command_with_quotes() { let agent = AcpAgent::from_str(r#"python "my agent.py" --name "Test Agent""#).unwrap(); match agent.server { - crate::schema::McpServer::Stdio(stdio) => { + SchemaMcpServer::Stdio(stdio) => { assert_eq!(stdio.name, "python"); assert_eq!(stdio.command, PathBuf::from("python")); assert_eq!(stdio.args, vec!["my agent.py", "--name", "Test Agent"]); @@ -521,7 +520,7 @@ mod tests { }"#; let agent = AcpAgent::from_str(json).unwrap(); match agent.server { - crate::schema::McpServer::Stdio(stdio) => { + SchemaMcpServer::Stdio(stdio) => { assert_eq!(stdio.name, "my-agent"); assert_eq!(stdio.command, PathBuf::from("/usr/bin/python")); assert_eq!(stdio.args, vec!["agent.py", "--verbose"]); @@ -541,7 +540,7 @@ mod tests { }"#; let agent = AcpAgent::from_str(json).unwrap(); match agent.server { - crate::schema::McpServer::Http(http) => { + SchemaMcpServer::Http(http) => { assert_eq!(http.name, "remote-agent"); assert_eq!(http.url, "https://example.com/agent"); assert!(http.headers.is_empty()); diff --git a/src/agent-client-protocol/src/capabilities.rs b/src/agent-client-protocol/src/capabilities.rs index fd2a689e..21517fa8 100644 --- a/src/agent-client-protocol/src/capabilities.rs +++ b/src/agent-client-protocol/src/capabilities.rs @@ -7,7 +7,7 @@ //! //! ```rust,no_run //! use agent_client_protocol::{MetaCapability, MetaCapabilityExt}; -//! # use agent_client_protocol::schema::InitializeResponse; +//! # use agent_client_protocol::schema::v1::InitializeResponse; //! # let init_response: InitializeResponse = unimplemented!(); //! //! struct Proxy; @@ -21,7 +21,7 @@ //! } //! ``` -use crate::schema::{InitializeRequest, InitializeResponse}; +use crate::schema::v1::{InitializeRequest, InitializeResponse}; use serde_json::{Value, json}; /// Trait for capabilities stored in the `_meta.symposium` object. @@ -129,7 +129,8 @@ impl MetaCapabilityExt for InitializeResponse { #[cfg(test)] mod tests { use super::*; - use crate::schema::{ClientCapabilities, ProtocolVersion}; + use crate::schema::ProtocolVersion; + use crate::schema::v1::ClientCapabilities; use serde_json::json; struct TestCapability; diff --git a/src/agent-client-protocol/src/concepts/cancellation.rs b/src/agent-client-protocol/src/concepts/cancellation.rs index 81075c9a..663bd238 100644 --- a/src/agent-client-protocol/src/concepts/cancellation.rs +++ b/src/agent-client-protocol/src/concepts/cancellation.rs @@ -142,7 +142,7 @@ //! //! ``` //! # use agent_client_protocol::{ConnectionTo, Error, UntypedRole}; -//! use agent_client_protocol::schema::CancelRequestNotification; +//! use agent_client_protocol::schema::v1::CancelRequestNotification; //! //! # fn example() { //! let builder = UntypedRole.builder().on_receive_notification( @@ -187,5 +187,5 @@ //! [`Responder::cancellation`]: crate::Responder::cancellation //! [`Responder`]: crate::Responder //! [`Error::request_cancelled`]: crate::Error::request_cancelled -//! [`CancelRequestNotification`]: crate::schema::CancelRequestNotification -//! [`ProtocolLevelNotification`]: crate::schema::ProtocolLevelNotification +//! [`CancelRequestNotification`]: crate::schema::v1::CancelRequestNotification +//! [`ProtocolLevelNotification`]: crate::schema::v1::ProtocolLevelNotification diff --git a/src/agent-client-protocol/src/concepts/connections.rs b/src/agent-client-protocol/src/concepts/connections.rs index 1ffbd9e4..f28d2d75 100644 --- a/src/agent-client-protocol/src/concepts/connections.rs +++ b/src/agent-client-protocol/src/concepts/connections.rs @@ -41,7 +41,7 @@ //! //! ``` //! # use agent_client_protocol::{Client, Agent, ConnectTo}; -//! # use agent_client_protocol::schema::{InitializeRequest, ProtocolVersion}; +//! # use agent_client_protocol::schema::{ProtocolVersion, v1::InitializeRequest}; //! # use agent_client_protocol_test::StatusUpdate; //! # async fn example(transport: impl ConnectTo) -> Result<(), agent_client_protocol::Error> { //! # Client.builder().connect_with(transport, async |cx| { diff --git a/src/agent-client-protocol/src/concepts/peers.rs b/src/agent-client-protocol/src/concepts/peers.rs index 2bde50b8..7c7dbcf9 100644 --- a/src/agent-client-protocol/src/concepts/peers.rs +++ b/src/agent-client-protocol/src/concepts/peers.rs @@ -17,7 +17,7 @@ //! //! ``` //! # use agent_client_protocol::{Client, Agent, ConnectTo}; -//! # use agent_client_protocol::schema::{InitializeRequest, ProtocolVersion}; +//! # use agent_client_protocol::schema::{ProtocolVersion, v1::InitializeRequest}; //! # async fn example(transport: impl ConnectTo) -> Result<(), agent_client_protocol::Error> { //! # Client.builder().connect_with(transport, async |cx| { //! // As a client diff --git a/src/agent-client-protocol/src/concepts/proxies.rs b/src/agent-client-protocol/src/concepts/proxies.rs index 571d681a..9ba0f642 100644 --- a/src/agent-client-protocol/src/concepts/proxies.rs +++ b/src/agent-client-protocol/src/concepts/proxies.rs @@ -84,7 +84,7 @@ //! //! ```ignore //! # use agent_client_protocol::{Proxy, Client, Conductor, ConnectTo}; -//! # use agent_client_protocol::schema::NewSessionRequest; +//! # use agent_client_protocol::schema::v1::NewSessionRequest; //! # use agent_client_protocol::mcp_server::McpServer; //! # use agent_client_protocol_rmcp::McpServerExt; //! # async fn example(transport: impl ConnectTo) -> Result<(), agent_client_protocol::Error> { diff --git a/src/agent-client-protocol/src/concepts/sessions.rs b/src/agent-client-protocol/src/concepts/sessions.rs index 00370946..9ce21624 100644 --- a/src/agent-client-protocol/src/concepts/sessions.rs +++ b/src/agent-client-protocol/src/concepts/sessions.rs @@ -104,7 +104,7 @@ //! //! ``` //! # use agent_client_protocol::{Client, Agent, ConnectTo}; -//! # use agent_client_protocol::schema::NewSessionRequest; +//! # use agent_client_protocol::schema::v1::NewSessionRequest; //! # async fn example(transport: impl ConnectTo) -> Result<(), agent_client_protocol::Error> { //! Client.builder() //! .on_receive_request(async |req: NewSessionRequest, responder, cx| { diff --git a/src/agent-client-protocol/src/jsonrpc.rs b/src/agent-client-protocol/src/jsonrpc.rs index bb465545..468389a2 100644 --- a/src/agent-client-protocol/src/jsonrpc.rs +++ b/src/agent-client-protocol/src/jsonrpc.rs @@ -1,6 +1,6 @@ //! Core JSON-RPC server support. -use agent_client_protocol_schema::{ +use agent_client_protocol_schema::v1::{ JsonRpcMessage as VersionedJsonRpcMessage, Notification as RpcNotification, Request as RpcRequest, RequestId, Response as RpcResponse, SessionId, }; @@ -295,7 +295,7 @@ fn params_from_transport(params: Option) -> serde_json::Value /// /// ``` /// # use agent_client_protocol::{Agent, Client, ConnectTo}; -/// # use agent_client_protocol::schema::{InitializeRequest, InitializeResponse, AgentCapabilities}; +/// # use agent_client_protocol::schema::v1::{AgentCapabilities, InitializeRequest, InitializeResponse}; /// # use agent_client_protocol_test::StatusUpdate; /// # async fn example(transport: impl ConnectTo) -> Result<(), agent_client_protocol::Error> { /// Agent.builder() @@ -455,7 +455,7 @@ where /// /// ```no_run /// # use agent_client_protocol_test::*; -/// # use agent_client_protocol::schema::{InitializeRequest, InitializeResponse, SessionNotification}; +/// # use agent_client_protocol::schema::v1::{InitializeRequest, InitializeResponse, SessionNotification}; /// # async fn example() -> Result<(), agent_client_protocol::Error> { /// # let connection = mock_connection(); /// connection @@ -480,7 +480,7 @@ where /// ```no_run /// # use agent_client_protocol_test::*; /// # use agent_client_protocol::{JsonRpcRequest, JsonRpcMessage, UntypedMessage}; -/// # use agent_client_protocol::schema::{InitializeRequest, InitializeResponse, PromptRequest, PromptResponse}; +/// # use agent_client_protocol::schema::v1::{InitializeRequest, InitializeResponse, PromptRequest, PromptResponse}; /// # async fn example() -> Result<(), agent_client_protocol::Error> { /// # let connection = mock_connection(); /// // Define an enum for multiple request types @@ -518,7 +518,7 @@ where /// ```no_run /// # use agent_client_protocol_test::*; /// # use agent_client_protocol::Dispatch; -/// # use agent_client_protocol::schema::{InitializeRequest, InitializeResponse, SessionNotification}; +/// # use agent_client_protocol::schema::v1::{InitializeRequest, InitializeResponse, SessionNotification}; /// # async fn example() -> Result<(), agent_client_protocol::Error> { /// # let connection = mock_connection(); /// // on_receive_dispatch receives Dispatch which can be either a request or notification @@ -558,7 +558,7 @@ where /// ```no_run /// # use agent_client_protocol_test::*; /// # use agent_client_protocol::{Dispatch, UntypedMessage}; -/// # use agent_client_protocol::schema::{InitializeRequest, InitializeResponse, PromptRequest, PromptResponse}; +/// # use agent_client_protocol::schema::v1::{InitializeRequest, InitializeResponse, PromptRequest, PromptResponse}; /// # async fn example() -> Result<(), agent_client_protocol::Error> { /// # let connection = mock_connection(); /// connection @@ -668,7 +668,7 @@ where /// /// ```no_run /// # use agent_client_protocol_test::*; -/// # use agent_client_protocol::schema::InitializeRequest; +/// # use agent_client_protocol::schema::v1::InitializeRequest; /// # async fn example() -> Result<(), agent_client_protocol::Error> { /// # let connection = mock_connection(); /// connection @@ -700,7 +700,7 @@ where /// # use agent_client_protocol::UntypedRole; /// # use agent_client_protocol::{Builder}; /// # use agent_client_protocol::Stdio; -/// # use agent_client_protocol::schema::{InitializeRequest, InitializeResponse, PromptRequest, PromptResponse, SessionNotification}; +/// # use agent_client_protocol::schema::v1::{InitializeRequest, InitializeResponse, PromptRequest, PromptResponse, SessionNotification}; /// # async fn example() -> Result<(), agent_client_protocol::Error> { /// let transport = Stdio::new(); /// @@ -1002,7 +1002,7 @@ impl< /// ```ignore /// # use agent_client_protocol::UntypedRole; /// # use agent_client_protocol::{Builder}; - /// # use agent_client_protocol::schema::{PromptRequest, PromptResponse, SessionNotification}; + /// # use agent_client_protocol::schema::v1::{PromptRequest, PromptResponse, SessionNotification}; /// # fn example(connection: Builder>) { /// connection.on_receive_request(async |request: PromptRequest, responder, cx| { /// // Send a notification while processing @@ -1192,7 +1192,7 @@ impl< /// /// ```ignore /// use agent_client_protocol::Agent; - /// use agent_client_protocol::schema::InitializeRequest; + /// use agent_client_protocol::schema::v1::InitializeRequest; /// /// // Conductor receiving from agent direction - messages will be unwrapped from SuccessorMessage /// connection.on_receive_request_from(Agent, async |req: InitializeRequest, responder, cx| { @@ -1350,7 +1350,7 @@ impl< /// # use agent_client_protocol::UntypedRole; /// # use agent_client_protocol::{Builder}; /// # use agent_client_protocol::ByteStreams; - /// # use agent_client_protocol::schema::InitializeRequest; + /// # use agent_client_protocol::schema::v1::InitializeRequest; /// # use agent_client_protocol::Stdio; /// # use agent_client_protocol_test::*; /// # async fn example() -> Result<(), agent_client_protocol::Error> { @@ -1902,11 +1902,11 @@ fn cancellation_request_id_from_message( message: &UntypedMessage, ) -> Result, crate::Error> { let (method, params) = peel_successor_envelopes(&message.method, &message.params); - if !crate::schema::CancelRequestNotification::matches_method(method) { + if !crate::schema::v1::CancelRequestNotification::matches_method(method) { return Ok(None); } - let notification = crate::schema::CancelRequestNotification::parse_message(method, params)?; + let notification = crate::schema::v1::CancelRequestNotification::parse_message(method, params)?; Ok(Some(notification.request_id)) } @@ -1954,7 +1954,7 @@ fn peel_successor_envelopes<'message>( #[must_use] pub fn is_cancel_request_notification(notification: &N) -> bool { let method = notification.method(); - if crate::schema::CancelRequestNotification::matches_method(method) { + if crate::schema::v1::CancelRequestNotification::matches_method(method) { return true; } if !crate::schema::SuccessorMessage::::matches_method(method) { @@ -1964,7 +1964,7 @@ pub fn is_cancel_request_notification(notification: &N) match notification.to_untyped_message() { Ok(untyped) => { let (method, _params) = peel_successor_envelopes(&untyped.method, &untyped.params); - crate::schema::CancelRequestNotification::matches_method(method) + crate::schema::v1::CancelRequestNotification::matches_method(method) } Err(error) => { tracing::debug!( @@ -2522,7 +2522,7 @@ impl ConnectionTo { #[cfg(feature = "unstable_cancel_request")] pub fn send_cancel_request( &self, - request_id: impl Into, + request_id: impl Into, ) -> Result<(), crate::Error> where Counterpart: HasPeer, @@ -2541,14 +2541,14 @@ impl ConnectionTo { pub fn send_cancel_request_to( &self, peer: Peer, - request_id: impl Into, + request_id: impl Into, ) -> Result<(), crate::Error> where Counterpart: HasPeer, { self.send_notification_to( peer, - crate::schema::CancelRequestNotification::new(request_id), + crate::schema::v1::CancelRequestNotification::new(request_id), ) } @@ -3669,7 +3669,7 @@ impl SentRequestCancellation { // Build the notification lazily: most requests are never cancelled, // so this avoids serializing a notification per outgoing request. let untyped = self.remote_style.transform_outgoing_message( - crate::schema::CancelRequestNotification::new(self.request_id.clone()), + crate::schema::v1::CancelRequestNotification::new(self.request_id.clone()), )?; send_raw_message(&self.message_tx, OutgoingMessage::Notification { untyped }) diff --git a/src/agent-client-protocol/src/jsonrpc/incoming_actor.rs b/src/agent-client-protocol/src/jsonrpc/incoming_actor.rs index 239606bc..e602926b 100644 --- a/src/agent-client-protocol/src/jsonrpc/incoming_actor.rs +++ b/src/agent-client-protocol/src/jsonrpc/incoming_actor.rs @@ -25,6 +25,7 @@ use crate::jsonrpc::outgoing_actor::send_raw_message; use crate::jsonrpc::protocol_compat::ProtocolCompat; use crate::role::Role; +use crate::schema::v1::{RequestId, Response}; use super::Handled; @@ -70,8 +71,7 @@ pub(super) async fn incoming_protocol_actor( // Map from request ID to (method, sender) for response dispatch. // The method is stored to allow routing responses through typed handlers. - let mut pending_replies: HashMap = - HashMap::new(); + let mut pending_replies: HashMap = HashMap::new(); while let Some(message_result) = my_rx.next().await { tracing::trace!(message = ?message_result, actor = "incoming_protocol_actor"); @@ -211,12 +211,8 @@ pub(super) async fn incoming_protocol_actor( } RawJsonRpcMessage::Response(response) => { let (id, result) = match response { - agent_client_protocol_schema::Response::Result { id, result } => { - (id, Ok(result)) - } - agent_client_protocol_schema::Response::Error { id, error } => { - (id, Err(error)) - } + Response::Result { id, result } => (id, Ok(result)), + Response::Error { id, error } => (id, Err(error)), }; tracing::trace!(?id, "Handling response"); @@ -267,7 +263,7 @@ fn dispatch_from_message( connection: &ConnectionTo, method: std::sync::Arc, params: Option, - id: Option, + id: Option, protocol_compat: &ProtocolCompat, request_cancellations: &super::RequestCancellationRegistry, ) -> Result, crate::Error> { @@ -301,7 +297,7 @@ fn dispatch_from_message( /// the awaiting code. The default behavior is to forward the response to the /// local awaiter via the oneshot channel. fn dispatch_from_response( - id: agent_client_protocol_schema::RequestId, + id: RequestId, pending_reply: PendingReply, result: Result, ) -> Dispatch { @@ -488,8 +484,7 @@ fn report_handler_error( match id { Some(id) => { // Request: send error response with the original request id - let jsonrpc_id = - serde_json::from_value(id).unwrap_or(agent_client_protocol_schema::RequestId::Null); + let jsonrpc_id = serde_json::from_value(id).unwrap_or(RequestId::Null); send_raw_message( &connection.message_tx, OutgoingMessage::Response { diff --git a/src/agent-client-protocol/src/jsonrpc/outgoing_actor.rs b/src/agent-client-protocol/src/jsonrpc/outgoing_actor.rs index ee9a5712..ae55221d 100644 --- a/src/agent-client-protocol/src/jsonrpc/outgoing_actor.rs +++ b/src/agent-client-protocol/src/jsonrpc/outgoing_actor.rs @@ -5,6 +5,7 @@ use futures::channel::mpsc; use crate::jsonrpc::ReplyMessage; use crate::jsonrpc::protocol_compat::ProtocolCompat; use crate::jsonrpc::{OutgoingMessage, RawJsonRpcMessage}; +use crate::schema::v1::RequestId; pub type OutgoingMessageTx = mpsc::UnboundedSender; @@ -118,10 +119,7 @@ pub(super) async fn outgoing_protocol_actor( OutgoingMessage::Error { error } => { // JSON-RPC reports parse/invalid-request errors with id null when // they cannot be correlated to a specific request. - RawJsonRpcMessage::response( - agent_client_protocol_schema::RequestId::Null, - Err(error), - ) + RawJsonRpcMessage::response(RequestId::Null, Err(error)) } }; @@ -173,7 +171,7 @@ mod tests { outgoing_tx .unbounded_send(OutgoingMessage::Request { - id: agent_client_protocol_schema::RequestId::Number(1), + id: RequestId::Number(1), role_id: crate::Agent.role_id(), method: "session/new".into(), untyped: malformed_v2_known_method()?, diff --git a/src/agent-client-protocol/src/jsonrpc/protocol_compat.rs b/src/agent-client-protocol/src/jsonrpc/protocol_compat.rs index 2e7c8f8d..cbca8fe0 100644 --- a/src/agent-client-protocol/src/jsonrpc/protocol_compat.rs +++ b/src/agent-client-protocol/src/jsonrpc/protocol_compat.rs @@ -87,9 +87,10 @@ mod imp { conversion::{IntoV1, IntoV1Many, IntoV2, v1_to_v2, v2_to_v1, v2_to_v1_many}, }; - use crate::schema::{ + use crate::schema::ProtocolVersion; + use crate::schema::v1::{ AgentNotification, AgentRequest, AgentResponse, ClientNotification, ClientRequest, - ClientResponse, ErrorCode, ProtocolVersion, + ClientResponse, ErrorCode, }; use crate::{JsonRpcMessage, JsonRpcResponse, UntypedMessage}; diff --git a/src/agent-client-protocol/src/jsonrpc/transport_actor.rs b/src/agent-client-protocol/src/jsonrpc/transport_actor.rs index 64b638ed..023b0ef6 100644 --- a/src/agent-client-protocol/src/jsonrpc/transport_actor.rs +++ b/src/agent-client-protocol/src/jsonrpc/transport_actor.rs @@ -2,6 +2,7 @@ use std::pin::pin; // Types re-exported from crate root use crate::jsonrpc::RawJsonRpcMessage; +use crate::schema::v1::Response; use futures::StreamExt as _; use futures::channel::mpsc; @@ -53,8 +54,7 @@ pub(super) async fn transport_outgoing_lines_actor( // If we failed to serialize a *response*, // send an error in response. let id = match response { - agent_client_protocol_schema::Response::Result { id, .. } - | agent_client_protocol_schema::Response::Error { id, .. } => id, + Response::Result { id, .. } | Response::Error { id, .. } => id, }; tracing::error!( ?serialization_error, diff --git a/src/agent-client-protocol/src/lib.rs b/src/agent-client-protocol/src/lib.rs index 2edd3deb..af92d7bd 100644 --- a/src/agent-client-protocol/src/lib.rs +++ b/src/agent-client-protocol/src/lib.rs @@ -23,7 +23,7 @@ //! //! ```no_run //! use agent_client_protocol::Client; -//! use agent_client_protocol::schema::{InitializeRequest, ProtocolVersion}; +//! use agent_client_protocol::schema::{ProtocolVersion, v1::InitializeRequest}; //! //! # async fn run(transport: impl agent_client_protocol::ConnectTo) -> agent_client_protocol::Result<()> { //! Client.builder() @@ -114,14 +114,8 @@ pub use component::{ConnectTo, DynConnectTo}; // Re-export BoxFuture for implementing Component traits pub use futures::future::BoxFuture; -// Re-export the six primary message enum types at the root -pub use schema::{ - AgentNotification, AgentRequest, AgentResponse, ClientNotification, ClientRequest, - ClientResponse, -}; - // Re-export commonly used infrastructure types for convenience -pub use schema::{Error, ErrorCode, Result}; +pub use schema::v1::{Error, ErrorCode, Result}; // Re-export derive macros for custom JSON-RPC types pub use agent_client_protocol_derive::{JsonRpcNotification, JsonRpcRequest, JsonRpcResponse}; diff --git a/src/agent-client-protocol/src/mcp_server/server.rs b/src/agent-client-protocol/src/mcp_server/server.rs index 868483a2..1ab97b39 100644 --- a/src/agent-client-protocol/src/mcp_server/server.rs +++ b/src/agent-client-protocol/src/mcp_server/server.rs @@ -2,7 +2,6 @@ use std::{marker::PhantomData, sync::Arc}; -use agent_client_protocol_schema::NewSessionRequest; use futures::{StreamExt, channel::mpsc}; use uuid::Uuid; @@ -15,6 +14,7 @@ use crate::{ }, mcp_server::{McpConnectionTo, McpServerConnect, active_session::McpActiveSession}, role::{self, HasPeer}, + schema::v1::{McpServer as SchemaMcpServer, McpServerHttp, NewSessionRequest}, util::MatchDispatchFrom, }; @@ -124,9 +124,12 @@ where /// Modify the new session request to include this MCP server. fn modify_new_session_request(&self, request: &mut NewSessionRequest) { - request.mcp_servers.push(crate::schema::McpServer::Http( - crate::schema::McpServerHttp::new(self.connect.name(), self.acp_id.clone()), - )); + request + .mcp_servers + .push(SchemaMcpServer::Http(McpServerHttp::new( + self.connect.name(), + self.acp_id.clone(), + ))); } } diff --git a/src/agent-client-protocol/src/role/acp.rs b/src/agent-client-protocol/src/role/acp.rs index 59176550..71d1e3b7 100644 --- a/src/agent-client-protocol/src/role/acp.rs +++ b/src/agent-client-protocol/src/role/acp.rs @@ -1,10 +1,9 @@ use std::{fmt::Debug, hash::Hash}; -use agent_client_protocol_schema::{NewSessionRequest, NewSessionResponse, SessionId}; - use crate::jsonrpc::{Builder, handlers::NullHandler, run::NullRun}; use crate::role::{HasPeer, RemoteStyle}; -use crate::schema::{InitializeProxyRequest, InitializeRequest, METHOD_INITIALIZE_PROXY}; +use crate::schema::v1::{InitializeRequest, NewSessionRequest, NewSessionResponse, SessionId}; +use crate::schema::{InitializeProxyRequest, METHOD_INITIALIZE_PROXY}; use crate::util::MatchDispatchFrom; use crate::{ConnectTo, ConnectionTo, Dispatch, HandleDispatchFrom, Handled, Role, RoleId}; diff --git a/src/agent-client-protocol/src/schema/agent_to_client/notifications.rs b/src/agent-client-protocol/src/schema/agent_to_client/notifications.rs index 22c8c5f6..e68e9569 100644 --- a/src/agent-client-protocol/src/schema/agent_to_client/notifications.rs +++ b/src/agent-client-protocol/src/schema/agent_to_client/notifications.rs @@ -1,6 +1,6 @@ #[cfg(feature = "unstable_elicitation")] -use crate::schema::CompleteElicitationNotification; -use crate::schema::SessionNotification; +use crate::schema::v1::CompleteElicitationNotification; +use crate::schema::v1::SessionNotification; impl_jsonrpc_notification!(SessionNotification, "session/update"); #[cfg(feature = "unstable_elicitation")] diff --git a/src/agent-client-protocol/src/schema/agent_to_client/requests.rs b/src/agent-client-protocol/src/schema/agent_to_client/requests.rs index d3bbb5a4..c6b8ab2f 100644 --- a/src/agent-client-protocol/src/schema/agent_to_client/requests.rs +++ b/src/agent-client-protocol/src/schema/agent_to_client/requests.rs @@ -1,6 +1,6 @@ #[cfg(feature = "unstable_elicitation")] -use crate::schema::{CreateElicitationRequest, CreateElicitationResponse}; -use crate::schema::{ +use crate::schema::v1::{CreateElicitationRequest, CreateElicitationResponse}; +use crate::schema::v1::{ CreateTerminalRequest, CreateTerminalResponse, KillTerminalRequest, KillTerminalResponse, ReadTextFileRequest, ReadTextFileResponse, ReleaseTerminalRequest, ReleaseTerminalResponse, RequestPermissionRequest, RequestPermissionResponse, TerminalOutputRequest, diff --git a/src/agent-client-protocol/src/schema/client_to_agent/notifications.rs b/src/agent-client-protocol/src/schema/client_to_agent/notifications.rs index 8162c236..c1a27a4e 100644 --- a/src/agent-client-protocol/src/schema/client_to_agent/notifications.rs +++ b/src/agent-client-protocol/src/schema/client_to_agent/notifications.rs @@ -1,3 +1,3 @@ -use crate::schema::CancelNotification; +use crate::schema::v1::CancelNotification; impl_jsonrpc_notification!(CancelNotification, "session/cancel"); diff --git a/src/agent-client-protocol/src/schema/client_to_agent/requests.rs b/src/agent-client-protocol/src/schema/client_to_agent/requests.rs index 536263f2..7a4f2333 100644 --- a/src/agent-client-protocol/src/schema/client_to_agent/requests.rs +++ b/src/agent-client-protocol/src/schema/client_to_agent/requests.rs @@ -1,4 +1,4 @@ -use crate::schema::{ +use crate::schema::v1::{ AuthenticateRequest, AuthenticateResponse, CloseSessionRequest, CloseSessionResponse, DeleteSessionRequest, DeleteSessionResponse, InitializeRequest, InitializeResponse, ListSessionsRequest, ListSessionsResponse, LoadSessionRequest, LoadSessionResponse, @@ -7,7 +7,7 @@ use crate::schema::{ SetSessionConfigOptionResponse, SetSessionModeRequest, SetSessionModeResponse, }; #[cfg(feature = "unstable_session_fork")] -use crate::schema::{ForkSessionRequest, ForkSessionResponse}; +use crate::schema::v1::{ForkSessionRequest, ForkSessionResponse}; impl_jsonrpc_request!(InitializeRequest, InitializeResponse, "initialize"); impl_jsonrpc_request!(AuthenticateRequest, AuthenticateResponse, "authenticate"); diff --git a/src/agent-client-protocol/src/schema/enum_impls.rs b/src/agent-client-protocol/src/schema/enum_impls.rs index ab024f86..680158b1 100644 --- a/src/agent-client-protocol/src/schema/enum_impls.rs +++ b/src/agent-client-protocol/src/schema/enum_impls.rs @@ -1,7 +1,7 @@ //! JsonRpcMessage and JsonRpcNotification/JsonRpcRequest implementations for //! the ACP enum types from agent-client-protocol-schema. -use crate::schema::{ +use crate::schema::v1::{ AgentNotification, AgentRequest, AgentResponse, ClientNotification, ClientRequest, ClientResponse, }; diff --git a/src/agent-client-protocol/src/schema/mod.rs b/src/agent-client-protocol/src/schema/mod.rs index 321aa66e..89b1de93 100644 --- a/src/agent-client-protocol/src/schema/mod.rs +++ b/src/agent-client-protocol/src/schema/mod.rs @@ -135,8 +135,8 @@ macro_rules! impl_jsonrpc_request_enum { _ => { if let Some(custom_method) = method.strip_prefix('_') { $crate::util::json_cast_params(params).map( - |ext_req: $crate::schema::ExtRequest| { - Self::$ext_variant($crate::schema::ExtRequest::new( + |ext_req: $crate::schema::v1::ExtRequest| { + Self::$ext_variant($crate::schema::v1::ExtRequest::new( custom_method.to_string(), ext_req.params, )) @@ -198,8 +198,8 @@ macro_rules! impl_jsonrpc_notification_enum { _ => { if let Some(custom_method) = method.strip_prefix('_') { $crate::util::json_cast_params(params).map( - |ext_notif: $crate::schema::ExtNotification| { - Self::$ext_variant($crate::schema::ExtNotification::new( + |ext_notif: $crate::schema::v1::ExtNotification| { + Self::$ext_variant($crate::schema::v1::ExtNotification::new( custom_method.to_string(), ext_notif.params, )) @@ -315,8 +315,20 @@ mod proxy_protocol; #[cfg(feature = "unstable_protocol_v2")] mod v2_impls; -// Re-export everything from agent_client_protocol_schema -pub use agent_client_protocol_schema::*; +/// Agent Client Protocol v1 schema types. +pub mod v1 { + pub use agent_client_protocol_schema::v1::*; +} + +/// Agent Client Protocol v2 draft schema types. +#[cfg(feature = "unstable_protocol_v2")] +pub mod v2 { + pub use agent_client_protocol_schema::v2::*; +} + +pub use agent_client_protocol_schema::{ + IntoMaybeUndefined, IntoOption, MaybeUndefined, ProtocolVersion, +}; -// Re-export proxy/MCP protocol types +// Re-export SDK-local proxy/MCP bridge protocol types flatly. pub use proxy_protocol::*; diff --git a/src/agent-client-protocol/src/schema/protocol_level.rs b/src/agent-client-protocol/src/schema/protocol_level.rs index 61aebd9a..0441bf5a 100644 --- a/src/agent-client-protocol/src/schema/protocol_level.rs +++ b/src/agent-client-protocol/src/schema/protocol_level.rs @@ -1,7 +1,7 @@ //! JSON-RPC trait implementations for protocol-level (`$/`-prefixed) messages. #[cfg(feature = "unstable_cancel_request")] -use crate::schema::{CancelRequestNotification, ProtocolLevelNotification}; +use crate::schema::v1::{CancelRequestNotification, ProtocolLevelNotification}; #[cfg(feature = "unstable_cancel_request")] impl_jsonrpc_notification!(CancelRequestNotification, "$/cancel_request"); diff --git a/src/agent-client-protocol/src/schema/proxy_protocol.rs b/src/agent-client-protocol/src/schema/proxy_protocol.rs index 4dce6ee7..18eeb3ce 100644 --- a/src/agent-client-protocol/src/schema/proxy_protocol.rs +++ b/src/agent-client-protocol/src/schema/proxy_protocol.rs @@ -3,7 +3,7 @@ //! These types are intended to become part of the ACP protocol specification. use crate::{JsonRpcMessage, JsonRpcNotification, JsonRpcRequest, UntypedMessage}; -use agent_client_protocol_schema::InitializeResponse; +use agent_client_protocol_schema::v1::{InitializeRequest, InitializeResponse}; use serde::{Deserialize, Serialize}; // ============================================================================= @@ -217,11 +217,11 @@ pub const METHOD_INITIALIZE_PROXY: &str = "_proxy/initialize"; pub struct InitializeProxyRequest { /// The underlying initialize request data. #[serde(flatten)] - pub initialize: agent_client_protocol_schema::InitializeRequest, + pub initialize: InitializeRequest, } -impl From for InitializeProxyRequest { - fn from(initialize: agent_client_protocol_schema::InitializeRequest) -> Self { +impl From for InitializeProxyRequest { + fn from(initialize: InitializeRequest) -> Self { Self { initialize } } } diff --git a/src/agent-client-protocol/src/session.rs b/src/agent-client-protocol/src/session.rs index 64673425..a62752c6 100644 --- a/src/agent-client-protocol/src/session.rs +++ b/src/agent-client-protocol/src/session.rs @@ -1,9 +1,5 @@ use std::{future::Future, marker::PhantomData, path::Path}; -use agent_client_protocol_schema::{ - ContentBlock, ContentChunk, NewSessionRequest, NewSessionResponse, PromptRequest, - PromptResponse, SessionModeState, SessionNotification, SessionUpdate, StopReason, -}; use futures::channel::{mpsc, oneshot}; use crate::{ @@ -14,7 +10,11 @@ use crate::{ }, mcp_server::McpServer, role::{HasPeer, acp::ProxySessionMessages}, - schema::SessionId, + schema::v1::{ + ContentBlock, ContentChunk, NewSessionRequest, NewSessionResponse, PromptRequest, + PromptResponse, SessionId, SessionModeState, SessionNotification, SessionUpdate, + StopReason, + }, util::{MatchDispatch, MatchDispatchFrom, run_until}, }; @@ -258,7 +258,7 @@ where /// /// ```ignore /// # use agent_client_protocol::{Proxy, Client, Conductor, ConnectTo}; - /// # use agent_client_protocol::schema::NewSessionRequest; + /// # use agent_client_protocol::schema::v1::NewSessionRequest; /// # use agent_client_protocol::mcp_server::McpServer; /// # use agent_client_protocol_rmcp::McpServerExt; /// # async fn example(transport: impl ConnectTo) -> Result<(), agent_client_protocol::Error> { diff --git a/src/agent-client-protocol/src/util.rs b/src/agent-client-protocol/src/util.rs index 0b672e6c..770dcb3b 100644 --- a/src/agent-client-protocol/src/util.rs +++ b/src/agent-client-protocol/src/util.rs @@ -68,7 +68,7 @@ pub fn parse_error(message: impl ToString) -> crate::Error { } /// Convert a JSON-RPC id to a serde_json::Value. -pub(crate) fn id_to_json(id: &agent_client_protocol_schema::RequestId) -> serde_json::Value { +pub(crate) fn id_to_json(id: &crate::schema::v1::RequestId) -> serde_json::Value { serde_json::to_value(id).expect("RequestId serializes infallibly") } diff --git a/src/agent-client-protocol/src/util/typed.rs b/src/agent-client-protocol/src/util/typed.rs index 9e5b91a4..7450c2e4 100644 --- a/src/agent-client-protocol/src/util/typed.rs +++ b/src/agent-client-protocol/src/util/typed.rs @@ -35,7 +35,7 @@ use crate::{ /// /// ``` /// # use agent_client_protocol::Dispatch; -/// # use agent_client_protocol::schema::{InitializeRequest, InitializeResponse, AgentCapabilities}; +/// # use agent_client_protocol::schema::v1::{AgentCapabilities, InitializeRequest, InitializeResponse}; /// # use agent_client_protocol::util::MatchDispatch; /// # async fn example(message: Dispatch) -> Result<(), agent_client_protocol::Error> { /// MatchDispatch::new(message) @@ -427,7 +427,7 @@ impl MatchDispatch { /// /// ``` /// # use agent_client_protocol::Dispatch; -/// # use agent_client_protocol::schema::{InitializeRequest, InitializeResponse, PromptRequest, PromptResponse, AgentCapabilities, StopReason}; +/// # use agent_client_protocol::schema::v1::{AgentCapabilities, InitializeRequest, InitializeResponse, PromptRequest, PromptResponse, StopReason}; /// # use agent_client_protocol::util::MatchDispatchFrom; /// # async fn example(message: Dispatch, cx: &agent_client_protocol::ConnectionTo) -> Result<(), agent_client_protocol::Error> { /// MatchDispatchFrom::new(message, cx) @@ -820,7 +820,7 @@ impl MatchDispatchFrom { /// /// ``` /// # use agent_client_protocol::{UntypedMessage, ConnectionTo, Agent}; -/// # use agent_client_protocol::schema::SessionNotification; +/// # use agent_client_protocol::schema::v1::SessionNotification; /// # use agent_client_protocol::util::TypeNotification; /// # async fn example(message: UntypedMessage, cx: &ConnectionTo) -> Result<(), agent_client_protocol::Error> { /// TypeNotification::new(message, cx) diff --git a/src/agent-client-protocol/tests/jsonrpc_edge_cases.rs b/src/agent-client-protocol/tests/jsonrpc_edge_cases.rs index 516dd5de..cba15434 100644 --- a/src/agent-client-protocol/tests/jsonrpc_edge_cases.rs +++ b/src/agent-client-protocol/tests/jsonrpc_edge_cases.rs @@ -20,7 +20,7 @@ fn raw_jsonrpc_message_rejects_scalar_params() { RawJsonRpcMessage::request( "scalar_params".into(), serde_json::json!(1), - agent_client_protocol::schema::RequestId::Number(1), + agent_client_protocol::schema::v1::RequestId::Number(1), ) .is_err() ); @@ -49,7 +49,7 @@ fn raw_jsonrpc_message_rejects_scalar_params() { ); let response = RawJsonRpcMessage::response( - agent_client_protocol::schema::RequestId::Number(1), + agent_client_protocol::schema::v1::RequestId::Number(1), Ok(serde_json::json!(1)), ); assert_eq!( diff --git a/src/agent-client-protocol/tests/jsonrpc_request_cancellation.rs b/src/agent-client-protocol/tests/jsonrpc_request_cancellation.rs index 4e5197d3..a5e38a97 100644 --- a/src/agent-client-protocol/tests/jsonrpc_request_cancellation.rs +++ b/src/agent-client-protocol/tests/jsonrpc_request_cancellation.rs @@ -18,7 +18,7 @@ use agent_client_protocol::{ Channel, ConnectionTo, Dispatch, HandleDispatchFrom, Handled, JsonRpcMessage, JsonRpcRequest, JsonRpcResponse, Responder, Role, RoleId, SentRequest, role::UntypedRole, - schema::{CancelRequestNotification, ProtocolLevelNotification, RequestId}, + schema::v1::{CancelRequestNotification, ProtocolLevelNotification, RequestId}, }; use expect_test::expect; use futures::channel::mpsc; diff --git a/src/agent-client-protocol/tests/meta_propagation.rs b/src/agent-client-protocol/tests/meta_propagation.rs index fbf5d357..72561c01 100644 --- a/src/agent-client-protocol/tests/meta_propagation.rs +++ b/src/agent-client-protocol/tests/meta_propagation.rs @@ -1,6 +1,7 @@ -use agent_client_protocol::schema::{ - ContentBlock, McpOverAcpMessage, Meta, PromptRequest, SessionId, SuccessorMessage, TextContent, +use agent_client_protocol::schema::v1::{ + ContentBlock, Meta, PromptRequest, SessionId, TextContent, }; +use agent_client_protocol::schema::{McpOverAcpMessage, SuccessorMessage}; use agent_client_protocol::{JsonRpcMessage, UntypedMessage}; use serde_json::{Value, json}; diff --git a/src/agent-client-protocol/tests/protocol_v2.rs b/src/agent-client-protocol/tests/protocol_v2.rs index 01e7e93a..f05f0325 100644 --- a/src/agent-client-protocol/tests/protocol_v2.rs +++ b/src/agent-client-protocol/tests/protocol_v2.rs @@ -2,7 +2,7 @@ use std::path::PathBuf; -use agent_client_protocol::schema::{self, ProtocolVersion, v2}; +use agent_client_protocol::schema::{ProtocolVersion, v1, v2}; use agent_client_protocol::{ Agent, Builder, Client, ConnectTo, Error, JsonRpcMessage, JsonRpcRequest, JsonRpcResponse, NullHandler, RawJsonRpcMessage, Role, UntypedRole, @@ -76,7 +76,7 @@ async fn assert_malformed_initialize_rejected(params: Map) -> Res .unbounded_send(Ok(RawJsonRpcMessage::request( "initialize".into(), Value::Object(params), - schema::RequestId::Number(1), + v1::RequestId::Number(1), )?)) .map_err(Error::into_internal_error)?; @@ -85,7 +85,7 @@ async fn assert_malformed_initialize_rejected(params: Map) -> Res let RawJsonRpcMessage::Response(response) = message else { continue; }; - let schema::Response::Error { error, .. } = response else { + let v1::Response::Error { error, .. } = response else { panic!("malformed initialize should fail"); }; assert_eq!(error.code, agent_client_protocol::ErrorCode::InvalidParams); @@ -162,9 +162,9 @@ async fn v2_agent_rejects_initialize_with_malformed_protocol_version() -> Result #[tokio::test(flavor = "current_thread")] async fn role_builder_v1_agent_rejects_v2_client_negotiation() -> Result<(), Error> { let agent = ::builder(Agent).on_receive_request( - async |initialize: schema::InitializeRequest, responder, _cx| { + async |initialize: v1::InitializeRequest, responder, _cx| { assert_eq!(initialize.protocol_version, ProtocolVersion::V1); - responder.respond(schema::InitializeResponse::new(initialize.protocol_version)) + responder.respond(v1::InitializeResponse::new(initialize.protocol_version)) }, agent_client_protocol::on_receive_request!(), ); @@ -194,9 +194,9 @@ async fn role_builder_v1_agent_rejects_v2_client_negotiation() -> Result<(), Err #[tokio::test(flavor = "current_thread")] async fn builder_new_v1_agent_rejects_v2_client_negotiation() -> Result<(), Error> { let agent = Builder::new(Agent).on_receive_request( - async |initialize: schema::InitializeRequest, responder, _cx| { + async |initialize: v1::InitializeRequest, responder, _cx| { assert_eq!(initialize.protocol_version, ProtocolVersion::V1); - responder.respond(schema::InitializeResponse::new(initialize.protocol_version)) + responder.respond(v1::InitializeResponse::new(initialize.protocol_version)) }, agent_client_protocol::on_receive_request!(), ); @@ -207,9 +207,9 @@ async fn builder_new_v1_agent_rejects_v2_client_negotiation() -> Result<(), Erro #[tokio::test(flavor = "current_thread")] async fn builder_new_with_v1_agent_rejects_v2_client_negotiation() -> Result<(), Error> { let agent = Builder::new_with(Agent, NullHandler).on_receive_request( - async |initialize: schema::InitializeRequest, responder, _cx| { + async |initialize: v1::InitializeRequest, responder, _cx| { assert_eq!(initialize.protocol_version, ProtocolVersion::V1); - responder.respond(schema::InitializeResponse::new(initialize.protocol_version)) + responder.respond(v1::InitializeResponse::new(initialize.protocol_version)) }, agent_client_protocol::on_receive_request!(), ); @@ -232,7 +232,7 @@ async fn role_builder_v1_client_downgrades_initialize_for_v2_agent() -> Result<( ::builder(Client) .connect_with(agent, async |cx| { let initialize = cx - .send_request(schema::InitializeRequest::new(ProtocolVersion::V2)) + .send_request(v1::InitializeRequest::new(ProtocolVersion::V2)) .block_task() .await?; assert_eq!(initialize.protocol_version, ProtocolVersion::V1); @@ -288,70 +288,70 @@ fn mcp_over_acp_variants_are_jsonrpc_mapped() -> Result<(), Error> { assert_notification::(); assert_message_mapping!( - schema::ClientRequest, + v1::ClientRequest, "mcp/message", - json_value(schema::MessageMcpRequest::new("conn-1", "tools/list"))?, - schema::ClientRequest::MessageMcpRequest(_) + json_value(v1::MessageMcpRequest::new("conn-1", "tools/list"))?, + v1::ClientRequest::MessageMcpRequest(_) ); assert_response_mapping!( - schema::AgentResponse, + v1::AgentResponse, "mcp/message", serde_json::json!({ "tools": [] }), - schema::AgentResponse::MessageMcpResponse(_) + v1::AgentResponse::MessageMcpResponse(_) ); assert_message_mapping!( - schema::ClientNotification, + v1::ClientNotification, "mcp/message", - json_value(schema::MessageMcpNotification::new( + json_value(v1::MessageMcpNotification::new( "conn-1", "notifications/tools/list" ))?, - schema::ClientNotification::MessageMcpNotification(_) + v1::ClientNotification::MessageMcpNotification(_) ); assert_message_mapping!( - schema::AgentRequest, + v1::AgentRequest, "mcp/connect", - json_value(schema::ConnectMcpRequest::new("server-1"))?, - schema::AgentRequest::ConnectMcpRequest(_) + json_value(v1::ConnectMcpRequest::new("server-1"))?, + v1::AgentRequest::ConnectMcpRequest(_) ); assert_message_mapping!( - schema::AgentRequest, + v1::AgentRequest, "mcp/message", - json_value(schema::MessageMcpRequest::new("conn-1", "tools/list"))?, - schema::AgentRequest::MessageMcpRequest(_) + json_value(v1::MessageMcpRequest::new("conn-1", "tools/list"))?, + v1::AgentRequest::MessageMcpRequest(_) ); assert_message_mapping!( - schema::AgentRequest, + v1::AgentRequest, "mcp/disconnect", - json_value(schema::DisconnectMcpRequest::new("conn-1"))?, - schema::AgentRequest::DisconnectMcpRequest(_) + json_value(v1::DisconnectMcpRequest::new("conn-1"))?, + v1::AgentRequest::DisconnectMcpRequest(_) ); assert_response_mapping!( - schema::ClientResponse, + v1::ClientResponse, "mcp/connect", - json_value(schema::ConnectMcpResponse::new("conn-1"))?, - schema::ClientResponse::ConnectMcpResponse(_) + json_value(v1::ConnectMcpResponse::new("conn-1"))?, + v1::ClientResponse::ConnectMcpResponse(_) ); assert_response_mapping!( - schema::ClientResponse, + v1::ClientResponse, "mcp/message", serde_json::json!({ "tools": [] }), - schema::ClientResponse::MessageMcpResponse(_) + v1::ClientResponse::MessageMcpResponse(_) ); assert_response_mapping!( - schema::ClientResponse, + v1::ClientResponse, "mcp/disconnect", serde_json::json!({}), - schema::ClientResponse::DisconnectMcpResponse(_) + v1::ClientResponse::DisconnectMcpResponse(_) ); assert_message_mapping!( - schema::AgentNotification, + v1::AgentNotification, "mcp/message", - json_value(schema::MessageMcpNotification::new( + json_value(v1::MessageMcpNotification::new( "conn-1", "notifications/tools/list" ))?, - schema::AgentNotification::MessageMcpNotification(_) + v1::AgentNotification::MessageMcpNotification(_) ); assert_message_mapping!( @@ -478,13 +478,13 @@ async fn v2_agent_serves_v1_client_with_v2_handlers() -> Result<(), Error> { .builder() .connect_with(agent, async |cx| { let initialize = cx - .send_request(schema::InitializeRequest::new(ProtocolVersion::V1)) + .send_request(v1::InitializeRequest::new(ProtocolVersion::V1)) .block_task() .await?; assert_eq!(initialize.protocol_version, ProtocolVersion::V1); let session = cx - .send_request(schema::NewSessionRequest::new(cwd()?)) + .send_request(v1::NewSessionRequest::new(cwd()?)) .block_task() .await?; assert_eq!(session.session_id.0.as_ref(), "v2-session"); @@ -620,12 +620,12 @@ async fn v1_client_can_cancel_request_to_v2_agent() -> Result<(), Error> { .builder() .connect_with(v2_agent_with_cancellable_new_session(), async |cx| { let initialize = cx - .send_request(schema::InitializeRequest::new(ProtocolVersion::V1)) + .send_request(v1::InitializeRequest::new(ProtocolVersion::V1)) .block_task() .await?; assert_eq!(initialize.protocol_version, ProtocolVersion::V1); - let request = cx.send_request(schema::NewSessionRequest::new(cwd()?)); + let request = cx.send_request(v1::NewSessionRequest::new(cwd()?)); request.cancel()?; let error = request .block_task() diff --git a/src/agent-client-protocol/tests/schema_elicitation.rs b/src/agent-client-protocol/tests/schema_elicitation.rs index e47fdada..8ea8dc96 100644 --- a/src/agent-client-protocol/tests/schema_elicitation.rs +++ b/src/agent-client-protocol/tests/schema_elicitation.rs @@ -1,6 +1,6 @@ #![cfg(feature = "unstable_elicitation")] -use agent_client_protocol::schema::{ +use agent_client_protocol::schema::v1::{ AgentNotification, AgentRequest, ClientCapabilities, ClientResponse, CompleteElicitationNotification, CreateElicitationRequest, CreateElicitationResponse, ElicitationAction, ElicitationCapabilities, ElicitationFormCapabilities, ElicitationFormMode, @@ -47,7 +47,7 @@ fn create_elicitation_request_has_jsonrpc_metadata() { CreateElicitationRequest::parse_message("elicitation/create", &untyped.params).unwrap(); assert!(matches!( parsed.mode, - agent_client_protocol::schema::ElicitationMode::Form(_) + agent_client_protocol::schema::v1::ElicitationMode::Form(_) )); assert_request_response_pair::(); @@ -187,7 +187,7 @@ fn protocol_v2_elicitation_variants_are_jsonrpc_mapped() -> Result<(), Error> { #[cfg(feature = "unstable_protocol_v2")] #[tokio::test(flavor = "current_thread")] async fn v2_agent_can_elicit_from_v1_client_before_prompt_completion() -> Result<(), Error> { - use agent_client_protocol::schema::{self, ProtocolVersion, v2}; + use agent_client_protocol::schema::{ProtocolVersion, v1, v2}; use agent_client_protocol::{Agent, Client}; use std::collections::BTreeMap; @@ -245,25 +245,25 @@ async fn v2_agent_can_elicit_from_v1_client_before_prompt_completion() -> Result assert_eq!(request.method(), "elicitation/create"); assert!(matches!( request.mode, - schema::ElicitationMode::Form(schema::ElicitationFormMode { .. }) + v1::ElicitationMode::Form(v1::ElicitationFormMode { .. }) )); let content = BTreeMap::from([("name".to_string(), "Ada".into())]); responder.respond(CreateElicitationResponse::new(ElicitationAction::Accept( - schema::ElicitationAcceptAction::new().content(content), + v1::ElicitationAcceptAction::new().content(content), ))) }, agent_client_protocol::on_receive_request!(), ) .connect_with(agent, async |cx| { let initialize = cx - .send_request(schema::InitializeRequest::new(ProtocolVersion::V1)) + .send_request(v1::InitializeRequest::new(ProtocolVersion::V1)) .block_task() .await?; assert_eq!(initialize.protocol_version, ProtocolVersion::V1); let error = cx - .send_request(schema::PromptRequest::new( + .send_request(v1::PromptRequest::new( "sess_abc123", vec!["continue".into()], )) diff --git a/src/agent-client-protocol/tests/schema_session_delete.rs b/src/agent-client-protocol/tests/schema_session_delete.rs index 785a8a11..1aa50529 100644 --- a/src/agent-client-protocol/tests/schema_session_delete.rs +++ b/src/agent-client-protocol/tests/schema_session_delete.rs @@ -1,4 +1,6 @@ -use agent_client_protocol::schema::{ClientRequest, DeleteSessionRequest, DeleteSessionResponse}; +use agent_client_protocol::schema::v1::{ + ClientRequest, DeleteSessionRequest, DeleteSessionResponse, +}; use agent_client_protocol::{JsonRpcMessage, JsonRpcRequest, JsonRpcResponse}; use serde_json::json; diff --git a/src/yopo/src/lib.rs b/src/yopo/src/lib.rs index 212bc019..35dfac45 100644 --- a/src/yopo/src/lib.rs +++ b/src/yopo/src/lib.rs @@ -2,10 +2,12 @@ //! //! Provides a convenient API for running one-shot prompts against ACP components. -use agent_client_protocol::schema::{ +use agent_client_protocol::schema::ProtocolVersion; +use agent_client_protocol::schema::v1::{ AudioContent, ContentBlock, EmbeddedResourceResource, ImageContent, InitializeRequest, - ProtocolVersion, RequestPermissionOutcome, RequestPermissionRequest, RequestPermissionResponse, - SelectedPermissionOutcome, SessionNotification, TextContent, + PermissionOptionKind, RequestPermissionOutcome, RequestPermissionRequest, + RequestPermissionResponse, SelectedPermissionOutcome, SessionNotification, SessionUpdate, + StopReason, TextContent, }; use agent_client_protocol::util::MatchDispatch; use agent_client_protocol::{Agent, Client, ConnectTo, Dispatch, Handled, UntypedMessage}; @@ -24,7 +26,7 @@ use std::path::PathBuf; /// /// ```no_run /// use yopo::content_block_to_string; -/// use agent_client_protocol::schema::{ContentBlock, TextContent}; +/// use agent_client_protocol::schema::v1::{ContentBlock, TextContent}; /// /// let block = ContentBlock::Text(TextContent::new("Hello".to_string())); /// assert_eq!(content_block_to_string(&block), "Hello"); @@ -99,101 +101,103 @@ pub async fn prompt_with_callback( }, agent_client_protocol::on_receive_dispatch!(), ) - .connect_with(component, |cx: agent_client_protocol::ConnectionTo| async move { - // Initialize the agent - let _init_response = cx - .send_request(InitializeRequest::new(ProtocolVersion::V1)) - .block_task() - .await?; + .connect_with( + component, + |cx: agent_client_protocol::ConnectionTo| async move { + // Initialize the agent + let _init_response = cx + .send_request(InitializeRequest::new(ProtocolVersion::V1)) + .block_task() + .await?; - let mut session = cx - .build_session(PathBuf::from(".")) - .block_task() - .start_session() - .await?; + let mut session = cx + .build_session(PathBuf::from(".")) + .block_task() + .start_session() + .await?; - session.send_prompt(prompt_text)?; + session.send_prompt(prompt_text)?; - loop { - let update = session.read_update().await?; - match update { - agent_client_protocol::SessionMessage::SessionMessage(message) => { - MatchDispatch::new(message) - .if_notification(async |notification: SessionNotification| { - tracing::debug!( - ?notification, - "yopo: received SessionNotification" - ); - // Call the callback for each agent message chunk - if let agent_client_protocol::schema::SessionUpdate::AgentMessageChunk( - content_chunk, - ) = notification.update - { - callback(content_chunk.content).await; - } - Ok(()) - }) - .await - .if_request(async |request: RequestPermissionRequest, responder| { - // Auto-approve all permission requests by selecting the first option - // that looks "allow-ish" - let outcome = request - .options - .iter() - .find(|option| match option.kind { - agent_client_protocol::schema::PermissionOptionKind::AllowOnce - | agent_client_protocol::schema::PermissionOptionKind::AllowAlways => true, - agent_client_protocol::schema::PermissionOptionKind::RejectOnce - | agent_client_protocol::schema::PermissionOptionKind::RejectAlways - | _ => false, - }) - .map_or(RequestPermissionOutcome::Cancelled, |option| { - RequestPermissionOutcome::Selected( - SelectedPermissionOutcome::new( - option.option_id.clone(), - ), - ) - }); + loop { + let update = session.read_update().await?; + match update { + agent_client_protocol::SessionMessage::SessionMessage(message) => { + MatchDispatch::new(message) + .if_notification(async |notification: SessionNotification| { + tracing::debug!( + ?notification, + "yopo: received SessionNotification" + ); + // Call the callback for each agent message chunk + if let SessionUpdate::AgentMessageChunk(content_chunk) = + notification.update + { + callback(content_chunk.content).await; + } + Ok(()) + }) + .await + .if_request(async |request: RequestPermissionRequest, responder| { + // Auto-approve all permission requests by selecting the first option + // that looks "allow-ish" + let outcome = request + .options + .iter() + .find(|option| match option.kind { + PermissionOptionKind::AllowOnce + | PermissionOptionKind::AllowAlways => true, + PermissionOptionKind::RejectOnce + | PermissionOptionKind::RejectAlways + | _ => false, + }) + .map_or(RequestPermissionOutcome::Cancelled, |option| { + RequestPermissionOutcome::Selected( + SelectedPermissionOutcome::new( + option.option_id.clone(), + ), + ) + }); - responder.respond(RequestPermissionResponse::new(outcome))?; + responder.respond(RequestPermissionResponse::new(outcome))?; - Ok(()) - }) - .await - .otherwise(async |_msg| Ok(())) - .await?; - } - agent_client_protocol::SessionMessage::StopReason(stop_reason) => { - match stop_reason { - agent_client_protocol::schema::StopReason::EndTurn => break, - agent_client_protocol::schema::StopReason::MaxTokens => { - tracing::debug!("Agent hit max tokens limit"); - break; - } - agent_client_protocol::schema::StopReason::MaxTurnRequests => { - tracing::debug!("Agent hit max turn requests limit"); - break; - } - agent_client_protocol::schema::StopReason::Refusal => { - tracing::warn!("Agent refused to continue"); - break; - } - agent_client_protocol::schema::StopReason::Cancelled => { - tracing::debug!("Session was cancelled"); - break; - } - other => { - tracing::warn!("Unknown stop reason: {:?}", other); - break; + Ok(()) + }) + .await + .otherwise(async |_msg| Ok(())) + .await?; + } + agent_client_protocol::SessionMessage::StopReason(stop_reason) => { + match stop_reason { + StopReason::EndTurn => break, + StopReason::MaxTokens => { + tracing::debug!("Agent hit max tokens limit"); + break; + } + StopReason::MaxTurnRequests => { + tracing::debug!("Agent hit max turn requests limit"); + break; + } + StopReason::Refusal => { + tracing::warn!("Agent refused to continue"); + break; + } + StopReason::Cancelled => { + tracing::debug!("Session was cancelled"); + break; + } + other => { + tracing::warn!("Unknown stop reason: {:?}", other); + break; + } } } + _ => {} } - _ => {} } - } - Ok(()) - }) + Ok(()) + }, + ) .await?; Ok(())