agent_client_protocol_schema/lib.rs
1//! [](https://agentclientprotocol.com/)
2//!
3//! # Agent Client Protocol (ACP)
4//!
5//! The Agent Client Protocol standardizes communication between code editors
6//! (IDEs, text-editors, etc.) and coding agents (programs that use generative AI
7//! to autonomously modify code).
8//!
9//! ## Protocol & Transport
10//!
11//! ACP is a JSON-RPC based protocol. While clients typically start agents as
12//! subprocesses and communicate over stdio (stdin/stdout), this crate is
13//! transport-agnostic.
14//!
15//! You can use any bidirectional stream that implements `AsyncRead` and `AsyncWrite`.
16//!
17//! ## Core Components
18//!
19//! - **Agent**: Programs that use generative AI to autonomously modify code
20//! - See: [Agent](https://agentclientprotocol.com/protocol/overview#agent)
21//! - **Client**: Code editors that provide the interface between users and agents
22//! - See: [Client](https://agentclientprotocol.com/protocol/overview#client)
23//!
24//! ## Getting Started
25//!
26//! To understand the protocol, start by exploring the [`Agent`] and [`Client`] traits,
27//! which define the core methods and capabilities of each side of the connection.
28//!
29//! To see working examples of these traits in action, check out the
30//! [agent](https://github.com/agentclientprotocol/rust-sdk/blob/main/examples/agent.rs)
31//! and
32//! [client](https://github.com/agentclientprotocol/rust-sdk/blob/main/examples/client.rs)
33//! example binaries included with this crate.
34//!
35//! ### Implementation Pattern
36//!
37//! ACP uses a symmetric design where each participant implements one trait and
38//! creates a connection that provides the complementary trait:
39//!
40//! - **Agent builders** implement the [`Agent`] trait to handle client requests
41//! (like initialization, authentication, and prompts). They pass this implementation
42//! to [`AgentSideConnection::new`], which returns a connection providing [`Client`]
43//! methods for requesting permissions and accessing the file system.
44//!
45//! - **Client builders** implement the [`Client`] trait to handle agent requests
46//! (like file system operations and permission checks). They pass this implementation
47//! to [`ClientSideConnection::new`], which returns a connection providing [`Agent`]
48//! methods for managing sessions and sending prompts.
49//!
50//! For the complete protocol specification and documentation, visit:
51//! [https://agentclientprotocol.com](https://agentclientprotocol.com)
52
53mod agent;
54mod client;
55mod content;
56#[cfg(feature = "unstable_elicitation")]
57mod elicitation;
58mod error;
59mod ext;
60mod maybe_undefined;
61#[cfg(feature = "unstable_nes")]
62mod nes;
63mod plan;
64#[cfg(feature = "unstable_cancel_request")]
65mod protocol_level;
66mod rpc;
67mod tool_call;
68mod version;
69
70pub use agent::*;
71pub use client::*;
72pub use content::*;
73use derive_more::{Display, From};
74#[cfg(feature = "unstable_elicitation")]
75pub use elicitation::*;
76pub use error::*;
77pub use ext::*;
78pub use maybe_undefined::*;
79#[cfg(feature = "unstable_nes")]
80pub use nes::*;
81pub use plan::*;
82#[cfg(feature = "unstable_cancel_request")]
83pub use protocol_level::*;
84pub use rpc::*;
85pub use serde_json::value::RawValue;
86pub use tool_call::*;
87pub use version::*;
88
89use schemars::JsonSchema;
90use serde::{Deserialize, Serialize};
91use std::{
92 borrow::Cow,
93 ffi::OsStr,
94 path::{Path, PathBuf},
95 sync::Arc,
96};
97
98/// A unique identifier for a conversation session between a client and agent.
99///
100/// Sessions maintain their own context, conversation history, and state,
101/// allowing multiple independent interactions with the same agent.
102///
103/// See protocol docs: [Session ID](https://agentclientprotocol.com/protocol/session-setup#session-id)
104#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, Display, From)]
105#[serde(transparent)]
106#[from(Arc<str>, String, &'static str)]
107#[non_exhaustive]
108pub struct SessionId(pub Arc<str>);
109
110impl SessionId {
111 #[must_use]
112 pub fn new(id: impl Into<Arc<str>>) -> Self {
113 Self(id.into())
114 }
115}
116
117/// Utility trait for builder methods for optional values.
118/// This allows the caller to either pass in the value itself without wrapping it in `Some`,
119/// or to just pass in an Option if that is what they have.
120pub trait IntoOption<T> {
121 fn into_option(self) -> Option<T>;
122}
123
124impl<T> IntoOption<T> for Option<T> {
125 fn into_option(self) -> Option<T> {
126 self
127 }
128}
129
130impl<T> IntoOption<T> for T {
131 fn into_option(self) -> Option<T> {
132 Some(self)
133 }
134}
135
136impl IntoOption<String> for &str {
137 fn into_option(self) -> Option<String> {
138 Some(self.into())
139 }
140}
141
142impl IntoOption<String> for &mut str {
143 fn into_option(self) -> Option<String> {
144 Some(self.into())
145 }
146}
147
148impl IntoOption<String> for &String {
149 fn into_option(self) -> Option<String> {
150 Some(self.into())
151 }
152}
153
154impl IntoOption<String> for Box<str> {
155 fn into_option(self) -> Option<String> {
156 Some(self.into())
157 }
158}
159
160impl IntoOption<String> for Cow<'_, str> {
161 fn into_option(self) -> Option<String> {
162 Some(self.into())
163 }
164}
165
166impl IntoOption<String> for Arc<str> {
167 fn into_option(self) -> Option<String> {
168 Some(self.to_string())
169 }
170}
171
172impl<T: ?Sized + AsRef<OsStr>> IntoOption<PathBuf> for &T {
173 fn into_option(self) -> Option<PathBuf> {
174 Some(self.into())
175 }
176}
177
178impl IntoOption<PathBuf> for Box<Path> {
179 fn into_option(self) -> Option<PathBuf> {
180 Some(self.into())
181 }
182}
183
184impl IntoOption<PathBuf> for Cow<'_, Path> {
185 fn into_option(self) -> Option<PathBuf> {
186 Some(self.into())
187 }
188}
189
190impl IntoOption<serde_json::Value> for &str {
191 fn into_option(self) -> Option<serde_json::Value> {
192 Some(self.into())
193 }
194}
195
196impl IntoOption<serde_json::Value> for String {
197 fn into_option(self) -> Option<serde_json::Value> {
198 Some(self.into())
199 }
200}
201
202impl IntoOption<serde_json::Value> for Cow<'_, str> {
203 fn into_option(self) -> Option<serde_json::Value> {
204 Some(self.into())
205 }
206}