Skip to main content

agent_client_protocol_schema/
lib.rs

1//! [![Agent Client Protocol](https://zed.dev/img/acp/banner-dark.webp)](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;
61mod plan;
62#[cfg(feature = "unstable_cancel_request")]
63mod protocol_level;
64mod rpc;
65mod tool_call;
66mod version;
67
68pub use agent::*;
69pub use client::*;
70pub use content::*;
71use derive_more::{Display, From};
72#[cfg(feature = "unstable_elicitation")]
73pub use elicitation::*;
74pub use error::*;
75pub use ext::*;
76pub use maybe_undefined::*;
77pub use plan::*;
78#[cfg(feature = "unstable_cancel_request")]
79pub use protocol_level::*;
80pub use rpc::*;
81pub use serde_json::value::RawValue;
82pub use tool_call::*;
83pub use version::*;
84
85use schemars::JsonSchema;
86use serde::{Deserialize, Serialize};
87use std::{
88    borrow::Cow,
89    ffi::OsStr,
90    path::{Path, PathBuf},
91    sync::Arc,
92};
93
94/// A unique identifier for a conversation session between a client and agent.
95///
96/// Sessions maintain their own context, conversation history, and state,
97/// allowing multiple independent interactions with the same agent.
98///
99/// See protocol docs: [Session ID](https://agentclientprotocol.com/protocol/session-setup#session-id)
100#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, Display, From)]
101#[serde(transparent)]
102#[from(Arc<str>, String, &'static str)]
103#[non_exhaustive]
104pub struct SessionId(pub Arc<str>);
105
106impl SessionId {
107    #[must_use]
108    pub fn new(id: impl Into<Arc<str>>) -> Self {
109        Self(id.into())
110    }
111}
112
113/// Utility trait for builder methods for optional values.
114/// This allows the caller to either pass in the value itself without wrapping it in `Some`,
115/// or to just pass in an Option if that is what they have.
116pub trait IntoOption<T> {
117    fn into_option(self) -> Option<T>;
118}
119
120impl<T> IntoOption<T> for Option<T> {
121    fn into_option(self) -> Option<T> {
122        self
123    }
124}
125
126impl<T> IntoOption<T> for T {
127    fn into_option(self) -> Option<T> {
128        Some(self)
129    }
130}
131
132impl IntoOption<String> for &str {
133    fn into_option(self) -> Option<String> {
134        Some(self.into())
135    }
136}
137
138impl IntoOption<String> for &mut str {
139    fn into_option(self) -> Option<String> {
140        Some(self.into())
141    }
142}
143
144impl IntoOption<String> for &String {
145    fn into_option(self) -> Option<String> {
146        Some(self.into())
147    }
148}
149
150impl IntoOption<String> for Box<str> {
151    fn into_option(self) -> Option<String> {
152        Some(self.into())
153    }
154}
155
156impl IntoOption<String> for Cow<'_, str> {
157    fn into_option(self) -> Option<String> {
158        Some(self.into())
159    }
160}
161
162impl IntoOption<String> for Arc<str> {
163    fn into_option(self) -> Option<String> {
164        Some(self.to_string())
165    }
166}
167
168impl<T: ?Sized + AsRef<OsStr>> IntoOption<PathBuf> for &T {
169    fn into_option(self) -> Option<PathBuf> {
170        Some(self.into())
171    }
172}
173
174impl IntoOption<PathBuf> for Box<Path> {
175    fn into_option(self) -> Option<PathBuf> {
176        Some(self.into())
177    }
178}
179
180impl IntoOption<PathBuf> for Cow<'_, Path> {
181    fn into_option(self) -> Option<PathBuf> {
182        Some(self.into())
183    }
184}
185
186impl IntoOption<serde_json::Value> for &str {
187    fn into_option(self) -> Option<serde_json::Value> {
188        Some(self.into())
189    }
190}
191
192impl IntoOption<serde_json::Value> for String {
193    fn into_option(self) -> Option<serde_json::Value> {
194        Some(self.into())
195    }
196}
197
198impl IntoOption<serde_json::Value> for Cow<'_, str> {
199    fn into_option(self) -> Option<serde_json::Value> {
200        Some(self.into())
201    }
202}