agent_client_protocol_schema/agent.rs
1//! Methods and notifications the agent handles/receives.
2//!
3//! This module defines the Agent trait and all associated types for implementing
4//! an AI coding agent that follows the Agent Client Protocol (ACP).
5
6use std::{path::PathBuf, sync::Arc};
7
8#[cfg(feature = "unstable_auth_methods")]
9use std::collections::HashMap;
10
11use derive_more::{Display, From};
12use schemars::JsonSchema;
13use serde::{Deserialize, Serialize};
14
15use crate::{
16 ClientCapabilities, ContentBlock, ExtNotification, ExtRequest, ExtResponse, IntoOption, Meta,
17 ProtocolVersion, SessionId,
18};
19
20// Initialize
21
22/// Request parameters for the initialize method.
23///
24/// Sent by the client to establish connection and negotiate capabilities.
25///
26/// See protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)
27#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
28#[schemars(extend("x-side" = "agent", "x-method" = INITIALIZE_METHOD_NAME))]
29#[serde(rename_all = "camelCase")]
30#[non_exhaustive]
31pub struct InitializeRequest {
32 /// The latest protocol version supported by the client.
33 pub protocol_version: ProtocolVersion,
34 /// Capabilities supported by the client.
35 #[serde(default)]
36 pub client_capabilities: ClientCapabilities,
37 /// Information about the Client name and version sent to the Agent.
38 ///
39 /// Note: in future versions of the protocol, this will be required.
40 #[serde(skip_serializing_if = "Option::is_none")]
41 pub client_info: Option<Implementation>,
42 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
43 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
44 /// these keys.
45 ///
46 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
47 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
48 pub meta: Option<Meta>,
49}
50
51impl InitializeRequest {
52 #[must_use]
53 pub fn new(protocol_version: ProtocolVersion) -> Self {
54 Self {
55 protocol_version,
56 client_capabilities: ClientCapabilities::default(),
57 client_info: None,
58 meta: None,
59 }
60 }
61
62 /// Capabilities supported by the client.
63 #[must_use]
64 pub fn client_capabilities(mut self, client_capabilities: ClientCapabilities) -> Self {
65 self.client_capabilities = client_capabilities;
66 self
67 }
68
69 /// Information about the Client name and version sent to the Agent.
70 #[must_use]
71 pub fn client_info(mut self, client_info: impl IntoOption<Implementation>) -> Self {
72 self.client_info = client_info.into_option();
73 self
74 }
75
76 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
77 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
78 /// these keys.
79 ///
80 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
81 #[must_use]
82 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
83 self.meta = meta.into_option();
84 self
85 }
86}
87
88/// Response to the `initialize` method.
89///
90/// Contains the negotiated protocol version and agent capabilities.
91///
92/// See protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)
93#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
94#[schemars(extend("x-side" = "agent", "x-method" = INITIALIZE_METHOD_NAME))]
95#[serde(rename_all = "camelCase")]
96#[non_exhaustive]
97pub struct InitializeResponse {
98 /// The protocol version the client specified if supported by the agent,
99 /// or the latest protocol version supported by the agent.
100 ///
101 /// The client should disconnect, if it doesn't support this version.
102 pub protocol_version: ProtocolVersion,
103 /// Capabilities supported by the agent.
104 #[serde(default)]
105 pub agent_capabilities: AgentCapabilities,
106 /// Authentication methods supported by the agent.
107 #[serde(default)]
108 pub auth_methods: Vec<AuthMethod>,
109 /// Information about the Agent name and version sent to the Client.
110 ///
111 /// Note: in future versions of the protocol, this will be required.
112 #[serde(skip_serializing_if = "Option::is_none")]
113 pub agent_info: Option<Implementation>,
114 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
115 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
116 /// these keys.
117 ///
118 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
119 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
120 pub meta: Option<Meta>,
121}
122
123impl InitializeResponse {
124 #[must_use]
125 pub fn new(protocol_version: ProtocolVersion) -> Self {
126 Self {
127 protocol_version,
128 agent_capabilities: AgentCapabilities::default(),
129 auth_methods: vec![],
130 agent_info: None,
131 meta: None,
132 }
133 }
134
135 /// Capabilities supported by the agent.
136 #[must_use]
137 pub fn agent_capabilities(mut self, agent_capabilities: AgentCapabilities) -> Self {
138 self.agent_capabilities = agent_capabilities;
139 self
140 }
141
142 /// Authentication methods supported by the agent.
143 #[must_use]
144 pub fn auth_methods(mut self, auth_methods: Vec<AuthMethod>) -> Self {
145 self.auth_methods = auth_methods;
146 self
147 }
148
149 /// Information about the Agent name and version sent to the Client.
150 #[must_use]
151 pub fn agent_info(mut self, agent_info: impl IntoOption<Implementation>) -> Self {
152 self.agent_info = agent_info.into_option();
153 self
154 }
155
156 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
157 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
158 /// these keys.
159 ///
160 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
161 #[must_use]
162 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
163 self.meta = meta.into_option();
164 self
165 }
166}
167
168/// Metadata about the implementation of the client or agent.
169/// Describes the name and version of an MCP implementation, with an optional
170/// title for UI representation.
171#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
172#[serde(rename_all = "camelCase")]
173#[non_exhaustive]
174pub struct Implementation {
175 /// Intended for programmatic or logical use, but can be used as a display
176 /// name fallback if title isn’t present.
177 pub name: String,
178 /// Intended for UI and end-user contexts — optimized to be human-readable
179 /// and easily understood.
180 ///
181 /// If not provided, the name should be used for display.
182 pub title: Option<String>,
183 /// Version of the implementation. Can be displayed to the user or used
184 /// for debugging or metrics purposes. (e.g. "1.0.0").
185 pub version: String,
186 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
187 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
188 /// these keys.
189 ///
190 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
191 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
192 pub meta: Option<Meta>,
193}
194
195impl Implementation {
196 #[must_use]
197 pub fn new(name: impl Into<String>, version: impl Into<String>) -> Self {
198 Self {
199 name: name.into(),
200 title: None,
201 version: version.into(),
202 meta: None,
203 }
204 }
205
206 /// Intended for UI and end-user contexts — optimized to be human-readable
207 /// and easily understood.
208 ///
209 /// If not provided, the name should be used for display.
210 #[must_use]
211 pub fn title(mut self, title: impl IntoOption<String>) -> Self {
212 self.title = title.into_option();
213 self
214 }
215
216 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
217 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
218 /// these keys.
219 ///
220 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
221 #[must_use]
222 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
223 self.meta = meta.into_option();
224 self
225 }
226}
227
228// Authentication
229
230/// Request parameters for the authenticate method.
231///
232/// Specifies which authentication method to use.
233#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
234#[schemars(extend("x-side" = "agent", "x-method" = AUTHENTICATE_METHOD_NAME))]
235#[serde(rename_all = "camelCase")]
236#[non_exhaustive]
237pub struct AuthenticateRequest {
238 /// The ID of the authentication method to use.
239 /// Must be one of the methods advertised in the initialize response.
240 pub method_id: AuthMethodId,
241 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
242 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
243 /// these keys.
244 ///
245 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
246 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
247 pub meta: Option<Meta>,
248}
249
250impl AuthenticateRequest {
251 #[must_use]
252 pub fn new(method_id: impl Into<AuthMethodId>) -> Self {
253 Self {
254 method_id: method_id.into(),
255 meta: None,
256 }
257 }
258
259 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
260 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
261 /// these keys.
262 ///
263 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
264 #[must_use]
265 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
266 self.meta = meta.into_option();
267 self
268 }
269}
270
271/// Response to the `authenticate` method.
272#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
273#[schemars(extend("x-side" = "agent", "x-method" = AUTHENTICATE_METHOD_NAME))]
274#[serde(rename_all = "camelCase")]
275#[non_exhaustive]
276pub struct AuthenticateResponse {
277 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
278 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
279 /// these keys.
280 ///
281 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
282 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
283 pub meta: Option<Meta>,
284}
285
286impl AuthenticateResponse {
287 #[must_use]
288 pub fn new() -> Self {
289 Self::default()
290 }
291
292 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
293 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
294 /// these keys.
295 ///
296 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
297 #[must_use]
298 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
299 self.meta = meta.into_option();
300 self
301 }
302}
303
304#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, Display, From)]
305#[serde(transparent)]
306#[from(Arc<str>, String, &'static str)]
307#[non_exhaustive]
308pub struct AuthMethodId(pub Arc<str>);
309
310impl AuthMethodId {
311 #[must_use]
312 pub fn new(id: impl Into<Arc<str>>) -> Self {
313 Self(id.into())
314 }
315}
316
317/// Describes an available authentication method.
318///
319/// The `type` field acts as the discriminator in the serialized JSON form.
320/// When no `type` is present, the method is treated as `agent`.
321#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
322#[serde(tag = "type", rename_all = "snake_case")]
323#[non_exhaustive]
324pub enum AuthMethod {
325 /// **UNSTABLE**
326 ///
327 /// This capability is not part of the spec yet, and may be removed or changed at any point.
328 ///
329 /// User provides a key that the client passes to the agent as an environment variable.
330 #[cfg(feature = "unstable_auth_methods")]
331 EnvVar(AuthMethodEnvVar),
332 /// **UNSTABLE**
333 ///
334 /// This capability is not part of the spec yet, and may be removed or changed at any point.
335 ///
336 /// Client runs an interactive terminal for the user to authenticate via a TUI.
337 #[cfg(feature = "unstable_auth_methods")]
338 Terminal(AuthMethodTerminal),
339 /// Agent handles authentication itself.
340 ///
341 /// This is the default when no `type` is specified.
342 #[serde(untagged)]
343 Agent(AuthMethodAgent),
344}
345
346impl AuthMethod {
347 /// The unique identifier for this authentication method.
348 #[must_use]
349 pub fn id(&self) -> &AuthMethodId {
350 match self {
351 Self::Agent(a) => &a.id,
352 #[cfg(feature = "unstable_auth_methods")]
353 Self::EnvVar(e) => &e.id,
354 #[cfg(feature = "unstable_auth_methods")]
355 Self::Terminal(t) => &t.id,
356 }
357 }
358
359 /// The human-readable name of this authentication method.
360 #[must_use]
361 pub fn name(&self) -> &str {
362 match self {
363 Self::Agent(a) => &a.name,
364 #[cfg(feature = "unstable_auth_methods")]
365 Self::EnvVar(e) => &e.name,
366 #[cfg(feature = "unstable_auth_methods")]
367 Self::Terminal(t) => &t.name,
368 }
369 }
370
371 /// Optional description providing more details about this authentication method.
372 #[must_use]
373 pub fn description(&self) -> Option<&str> {
374 match self {
375 Self::Agent(a) => a.description.as_deref(),
376 #[cfg(feature = "unstable_auth_methods")]
377 Self::EnvVar(e) => e.description.as_deref(),
378 #[cfg(feature = "unstable_auth_methods")]
379 Self::Terminal(t) => t.description.as_deref(),
380 }
381 }
382}
383
384/// Agent handles authentication itself.
385///
386/// This is the default authentication method type.
387#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
388#[serde(rename_all = "camelCase")]
389#[non_exhaustive]
390pub struct AuthMethodAgent {
391 /// Unique identifier for this authentication method.
392 pub id: AuthMethodId,
393 /// Human-readable name of the authentication method.
394 pub name: String,
395 /// Optional description providing more details about this authentication method.
396 #[serde(skip_serializing_if = "Option::is_none")]
397 pub description: Option<String>,
398 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
399 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
400 /// these keys.
401 ///
402 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
403 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
404 pub meta: Option<Meta>,
405}
406
407impl AuthMethodAgent {
408 #[must_use]
409 pub fn new(id: impl Into<AuthMethodId>, name: impl Into<String>) -> Self {
410 Self {
411 id: id.into(),
412 name: name.into(),
413 description: None,
414 meta: None,
415 }
416 }
417
418 /// Optional description providing more details about this authentication method.
419 #[must_use]
420 pub fn description(mut self, description: impl IntoOption<String>) -> Self {
421 self.description = description.into_option();
422 self
423 }
424
425 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
426 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
427 /// these keys.
428 ///
429 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
430 #[must_use]
431 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
432 self.meta = meta.into_option();
433 self
434 }
435}
436
437/// **UNSTABLE**
438///
439/// This capability is not part of the spec yet, and may be removed or changed at any point.
440///
441/// Environment variable authentication method.
442///
443/// The user provides credentials that the client passes to the agent as environment variables.
444#[cfg(feature = "unstable_auth_methods")]
445#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
446#[serde(rename_all = "camelCase")]
447#[non_exhaustive]
448pub struct AuthMethodEnvVar {
449 /// Unique identifier for this authentication method.
450 pub id: AuthMethodId,
451 /// Human-readable name of the authentication method.
452 pub name: String,
453 /// Optional description providing more details about this authentication method.
454 #[serde(skip_serializing_if = "Option::is_none")]
455 pub description: Option<String>,
456 /// The environment variables the client should set.
457 pub vars: Vec<AuthEnvVar>,
458 /// Optional link to a page where the user can obtain their credentials.
459 #[serde(skip_serializing_if = "Option::is_none")]
460 pub link: Option<String>,
461 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
462 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
463 /// these keys.
464 ///
465 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
466 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
467 pub meta: Option<Meta>,
468}
469
470#[cfg(feature = "unstable_auth_methods")]
471impl AuthMethodEnvVar {
472 #[must_use]
473 pub fn new(
474 id: impl Into<AuthMethodId>,
475 name: impl Into<String>,
476 vars: Vec<AuthEnvVar>,
477 ) -> Self {
478 Self {
479 id: id.into(),
480 name: name.into(),
481 description: None,
482 vars,
483 link: None,
484 meta: None,
485 }
486 }
487
488 /// Optional link to a page where the user can obtain their credentials.
489 #[must_use]
490 pub fn link(mut self, link: impl IntoOption<String>) -> Self {
491 self.link = link.into_option();
492 self
493 }
494
495 /// Optional description providing more details about this authentication method.
496 #[must_use]
497 pub fn description(mut self, description: impl IntoOption<String>) -> Self {
498 self.description = description.into_option();
499 self
500 }
501
502 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
503 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
504 /// these keys.
505 ///
506 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
507 #[must_use]
508 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
509 self.meta = meta.into_option();
510 self
511 }
512}
513
514/// **UNSTABLE**
515///
516/// This capability is not part of the spec yet, and may be removed or changed at any point.
517///
518/// Describes a single environment variable for an [`AuthMethodEnvVar`] authentication method.
519#[cfg(feature = "unstable_auth_methods")]
520#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
521#[serde(rename_all = "camelCase")]
522#[non_exhaustive]
523pub struct AuthEnvVar {
524 /// The environment variable name (e.g. `"OPENAI_API_KEY"`).
525 pub name: String,
526 /// Human-readable label for this variable, displayed in client UI.
527 #[serde(skip_serializing_if = "Option::is_none")]
528 pub label: Option<String>,
529 /// Whether this value is a secret (e.g. API key, token).
530 /// Clients should use a password-style input for secret vars.
531 ///
532 /// Defaults to `true`.
533 #[serde(default = "default_true", skip_serializing_if = "is_true")]
534 #[schemars(extend("default" = true))]
535 pub secret: bool,
536 /// Whether this variable is optional.
537 ///
538 /// Defaults to `false`.
539 #[serde(default, skip_serializing_if = "is_false")]
540 #[schemars(extend("default" = false))]
541 pub optional: bool,
542 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
543 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
544 /// these keys.
545 ///
546 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
547 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
548 pub meta: Option<Meta>,
549}
550
551#[cfg(feature = "unstable_auth_methods")]
552fn default_true() -> bool {
553 true
554}
555
556#[cfg(feature = "unstable_auth_methods")]
557#[expect(clippy::trivially_copy_pass_by_ref)]
558fn is_true(v: &bool) -> bool {
559 *v
560}
561
562#[cfg(feature = "unstable_auth_methods")]
563#[expect(clippy::trivially_copy_pass_by_ref)]
564fn is_false(v: &bool) -> bool {
565 !*v
566}
567
568#[cfg(feature = "unstable_auth_methods")]
569impl AuthEnvVar {
570 /// Creates a new auth env var.
571 #[must_use]
572 pub fn new(name: impl Into<String>) -> Self {
573 Self {
574 name: name.into(),
575 label: None,
576 secret: true,
577 optional: false,
578 meta: None,
579 }
580 }
581
582 /// Human-readable label for this variable, displayed in client UI.
583 #[must_use]
584 pub fn label(mut self, label: impl IntoOption<String>) -> Self {
585 self.label = label.into_option();
586 self
587 }
588
589 /// Whether this value is a secret (e.g. API key, token).
590 /// Clients should use a password-style input for secret vars.
591 #[must_use]
592 pub fn secret(mut self, secret: bool) -> Self {
593 self.secret = secret;
594 self
595 }
596
597 /// Whether this variable is optional.
598 #[must_use]
599 pub fn optional(mut self, optional: bool) -> Self {
600 self.optional = optional;
601 self
602 }
603
604 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
605 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
606 /// these keys.
607 ///
608 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
609 #[must_use]
610 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
611 self.meta = meta.into_option();
612 self
613 }
614}
615
616/// **UNSTABLE**
617///
618/// This capability is not part of the spec yet, and may be removed or changed at any point.
619///
620/// Terminal-based authentication method.
621///
622/// The client runs an interactive terminal for the user to authenticate via a TUI.
623#[cfg(feature = "unstable_auth_methods")]
624#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
625#[serde(rename_all = "camelCase")]
626#[non_exhaustive]
627pub struct AuthMethodTerminal {
628 /// Unique identifier for this authentication method.
629 pub id: AuthMethodId,
630 /// Human-readable name of the authentication method.
631 pub name: String,
632 /// Optional description providing more details about this authentication method.
633 #[serde(skip_serializing_if = "Option::is_none")]
634 pub description: Option<String>,
635 /// Additional arguments to pass when running the agent binary for terminal auth.
636 #[serde(default, skip_serializing_if = "Vec::is_empty")]
637 pub args: Vec<String>,
638 /// Additional environment variables to set when running the agent binary for terminal auth.
639 #[serde(default, skip_serializing_if = "HashMap::is_empty")]
640 pub env: HashMap<String, String>,
641 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
642 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
643 /// these keys.
644 ///
645 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
646 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
647 pub meta: Option<Meta>,
648}
649
650#[cfg(feature = "unstable_auth_methods")]
651impl AuthMethodTerminal {
652 #[must_use]
653 pub fn new(id: impl Into<AuthMethodId>, name: impl Into<String>) -> Self {
654 Self {
655 id: id.into(),
656 name: name.into(),
657 description: None,
658 args: Vec::new(),
659 env: HashMap::new(),
660 meta: None,
661 }
662 }
663
664 /// Additional arguments to pass when running the agent binary for terminal auth.
665 #[must_use]
666 pub fn args(mut self, args: Vec<String>) -> Self {
667 self.args = args;
668 self
669 }
670
671 /// Additional environment variables to set when running the agent binary for terminal auth.
672 #[must_use]
673 pub fn env(mut self, env: HashMap<String, String>) -> Self {
674 self.env = env;
675 self
676 }
677
678 /// Optional description providing more details about this authentication method.
679 #[must_use]
680 pub fn description(mut self, description: impl IntoOption<String>) -> Self {
681 self.description = description.into_option();
682 self
683 }
684
685 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
686 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
687 /// these keys.
688 ///
689 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
690 #[must_use]
691 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
692 self.meta = meta.into_option();
693 self
694 }
695}
696
697// New session
698
699/// Request parameters for creating a new session.
700///
701/// See protocol docs: [Creating a Session](https://agentclientprotocol.com/protocol/session-setup#creating-a-session)
702#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
703#[schemars(extend("x-side" = "agent", "x-method" = SESSION_NEW_METHOD_NAME))]
704#[serde(rename_all = "camelCase")]
705#[non_exhaustive]
706pub struct NewSessionRequest {
707 /// The working directory for this session. Must be an absolute path.
708 pub cwd: PathBuf,
709 /// List of MCP (Model Context Protocol) servers the agent should connect to.
710 pub mcp_servers: Vec<McpServer>,
711 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
712 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
713 /// these keys.
714 ///
715 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
716 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
717 pub meta: Option<Meta>,
718}
719
720impl NewSessionRequest {
721 #[must_use]
722 pub fn new(cwd: impl Into<PathBuf>) -> Self {
723 Self {
724 cwd: cwd.into(),
725 mcp_servers: vec![],
726 meta: None,
727 }
728 }
729
730 /// List of MCP (Model Context Protocol) servers the agent should connect to.
731 #[must_use]
732 pub fn mcp_servers(mut self, mcp_servers: Vec<McpServer>) -> Self {
733 self.mcp_servers = mcp_servers;
734 self
735 }
736
737 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
738 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
739 /// these keys.
740 ///
741 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
742 #[must_use]
743 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
744 self.meta = meta.into_option();
745 self
746 }
747}
748
749/// Response from creating a new session.
750///
751/// See protocol docs: [Creating a Session](https://agentclientprotocol.com/protocol/session-setup#creating-a-session)
752#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
753#[schemars(extend("x-side" = "agent", "x-method" = SESSION_NEW_METHOD_NAME))]
754#[serde(rename_all = "camelCase")]
755#[non_exhaustive]
756pub struct NewSessionResponse {
757 /// Unique identifier for the created session.
758 ///
759 /// Used in all subsequent requests for this conversation.
760 pub session_id: SessionId,
761 /// Initial mode state if supported by the Agent
762 ///
763 /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
764 #[serde(skip_serializing_if = "Option::is_none")]
765 pub modes: Option<SessionModeState>,
766 /// **UNSTABLE**
767 ///
768 /// This capability is not part of the spec yet, and may be removed or changed at any point.
769 ///
770 /// Initial model state if supported by the Agent
771 #[cfg(feature = "unstable_session_model")]
772 #[serde(skip_serializing_if = "Option::is_none")]
773 pub models: Option<SessionModelState>,
774 /// Initial session configuration options if supported by the Agent.
775 #[serde(skip_serializing_if = "Option::is_none")]
776 pub config_options: Option<Vec<SessionConfigOption>>,
777 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
778 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
779 /// these keys.
780 ///
781 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
782 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
783 pub meta: Option<Meta>,
784}
785
786impl NewSessionResponse {
787 #[must_use]
788 pub fn new(session_id: impl Into<SessionId>) -> Self {
789 Self {
790 session_id: session_id.into(),
791 modes: None,
792 #[cfg(feature = "unstable_session_model")]
793 models: None,
794 config_options: None,
795 meta: None,
796 }
797 }
798
799 /// Initial mode state if supported by the Agent
800 ///
801 /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
802 #[must_use]
803 pub fn modes(mut self, modes: impl IntoOption<SessionModeState>) -> Self {
804 self.modes = modes.into_option();
805 self
806 }
807
808 /// **UNSTABLE**
809 ///
810 /// This capability is not part of the spec yet, and may be removed or changed at any point.
811 ///
812 /// Initial model state if supported by the Agent
813 #[cfg(feature = "unstable_session_model")]
814 #[must_use]
815 pub fn models(mut self, models: impl IntoOption<SessionModelState>) -> Self {
816 self.models = models.into_option();
817 self
818 }
819
820 /// Initial session configuration options if supported by the Agent.
821 #[must_use]
822 pub fn config_options(
823 mut self,
824 config_options: impl IntoOption<Vec<SessionConfigOption>>,
825 ) -> Self {
826 self.config_options = config_options.into_option();
827 self
828 }
829
830 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
831 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
832 /// these keys.
833 ///
834 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
835 #[must_use]
836 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
837 self.meta = meta.into_option();
838 self
839 }
840}
841
842// Load session
843
844/// Request parameters for loading an existing session.
845///
846/// Only available if the Agent supports the `loadSession` capability.
847///
848/// See protocol docs: [Loading Sessions](https://agentclientprotocol.com/protocol/session-setup#loading-sessions)
849#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
850#[schemars(extend("x-side" = "agent", "x-method" = SESSION_LOAD_METHOD_NAME))]
851#[serde(rename_all = "camelCase")]
852#[non_exhaustive]
853pub struct LoadSessionRequest {
854 /// List of MCP servers to connect to for this session.
855 pub mcp_servers: Vec<McpServer>,
856 /// The working directory for this session.
857 pub cwd: PathBuf,
858 /// The ID of the session to load.
859 pub session_id: SessionId,
860 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
861 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
862 /// these keys.
863 ///
864 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
865 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
866 pub meta: Option<Meta>,
867}
868
869impl LoadSessionRequest {
870 #[must_use]
871 pub fn new(session_id: impl Into<SessionId>, cwd: impl Into<PathBuf>) -> Self {
872 Self {
873 mcp_servers: vec![],
874 cwd: cwd.into(),
875 session_id: session_id.into(),
876 meta: None,
877 }
878 }
879
880 /// List of MCP servers to connect to for this session.
881 #[must_use]
882 pub fn mcp_servers(mut self, mcp_servers: Vec<McpServer>) -> Self {
883 self.mcp_servers = mcp_servers;
884 self
885 }
886
887 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
888 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
889 /// these keys.
890 ///
891 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
892 #[must_use]
893 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
894 self.meta = meta.into_option();
895 self
896 }
897}
898
899/// Response from loading an existing session.
900#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
901#[schemars(extend("x-side" = "agent", "x-method" = SESSION_LOAD_METHOD_NAME))]
902#[serde(rename_all = "camelCase")]
903#[non_exhaustive]
904pub struct LoadSessionResponse {
905 /// Initial mode state if supported by the Agent
906 ///
907 /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
908 #[serde(default, skip_serializing_if = "Option::is_none")]
909 pub modes: Option<SessionModeState>,
910 /// **UNSTABLE**
911 ///
912 /// This capability is not part of the spec yet, and may be removed or changed at any point.
913 ///
914 /// Initial model state if supported by the Agent
915 #[cfg(feature = "unstable_session_model")]
916 #[serde(default, skip_serializing_if = "Option::is_none")]
917 pub models: Option<SessionModelState>,
918 /// Initial session configuration options if supported by the Agent.
919 #[serde(default, skip_serializing_if = "Option::is_none")]
920 pub config_options: Option<Vec<SessionConfigOption>>,
921 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
922 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
923 /// these keys.
924 ///
925 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
926 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
927 pub meta: Option<Meta>,
928}
929
930impl LoadSessionResponse {
931 #[must_use]
932 pub fn new() -> Self {
933 Self::default()
934 }
935
936 /// Initial mode state if supported by the Agent
937 ///
938 /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
939 #[must_use]
940 pub fn modes(mut self, modes: impl IntoOption<SessionModeState>) -> Self {
941 self.modes = modes.into_option();
942 self
943 }
944
945 /// **UNSTABLE**
946 ///
947 /// This capability is not part of the spec yet, and may be removed or changed at any point.
948 ///
949 /// Initial model state if supported by the Agent
950 #[cfg(feature = "unstable_session_model")]
951 #[must_use]
952 pub fn models(mut self, models: impl IntoOption<SessionModelState>) -> Self {
953 self.models = models.into_option();
954 self
955 }
956
957 /// Initial session configuration options if supported by the Agent.
958 #[must_use]
959 pub fn config_options(
960 mut self,
961 config_options: impl IntoOption<Vec<SessionConfigOption>>,
962 ) -> Self {
963 self.config_options = config_options.into_option();
964 self
965 }
966
967 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
968 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
969 /// these keys.
970 ///
971 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
972 #[must_use]
973 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
974 self.meta = meta.into_option();
975 self
976 }
977}
978
979// Fork session
980
981/// **UNSTABLE**
982///
983/// This capability is not part of the spec yet, and may be removed or changed at any point.
984///
985/// Request parameters for forking an existing session.
986///
987/// Creates a new session based on the context of an existing one, allowing
988/// operations like generating summaries without affecting the original session's history.
989///
990/// Only available if the Agent supports the `session.fork` capability.
991#[cfg(feature = "unstable_session_fork")]
992#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
993#[schemars(extend("x-side" = "agent", "x-method" = SESSION_FORK_METHOD_NAME))]
994#[serde(rename_all = "camelCase")]
995#[non_exhaustive]
996pub struct ForkSessionRequest {
997 /// The ID of the session to fork.
998 pub session_id: SessionId,
999 /// The working directory for this session.
1000 pub cwd: PathBuf,
1001 /// List of MCP servers to connect to for this session.
1002 #[serde(default, skip_serializing_if = "Vec::is_empty")]
1003 pub mcp_servers: Vec<McpServer>,
1004 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1005 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1006 /// these keys.
1007 ///
1008 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1009 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1010 pub meta: Option<Meta>,
1011}
1012
1013#[cfg(feature = "unstable_session_fork")]
1014impl ForkSessionRequest {
1015 #[must_use]
1016 pub fn new(session_id: impl Into<SessionId>, cwd: impl Into<PathBuf>) -> Self {
1017 Self {
1018 session_id: session_id.into(),
1019 cwd: cwd.into(),
1020 mcp_servers: vec![],
1021 meta: None,
1022 }
1023 }
1024
1025 /// List of MCP servers to connect to for this session.
1026 #[must_use]
1027 pub fn mcp_servers(mut self, mcp_servers: Vec<McpServer>) -> Self {
1028 self.mcp_servers = mcp_servers;
1029 self
1030 }
1031
1032 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1033 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1034 /// these keys.
1035 ///
1036 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1037 #[must_use]
1038 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1039 self.meta = meta.into_option();
1040 self
1041 }
1042}
1043
1044/// **UNSTABLE**
1045///
1046/// This capability is not part of the spec yet, and may be removed or changed at any point.
1047///
1048/// Response from forking an existing session.
1049#[cfg(feature = "unstable_session_fork")]
1050#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1051#[schemars(extend("x-side" = "agent", "x-method" = SESSION_FORK_METHOD_NAME))]
1052#[serde(rename_all = "camelCase")]
1053#[non_exhaustive]
1054pub struct ForkSessionResponse {
1055 /// Unique identifier for the newly created forked session.
1056 pub session_id: SessionId,
1057 /// Initial mode state if supported by the Agent
1058 ///
1059 /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
1060 #[serde(skip_serializing_if = "Option::is_none")]
1061 pub modes: Option<SessionModeState>,
1062 /// **UNSTABLE**
1063 ///
1064 /// This capability is not part of the spec yet, and may be removed or changed at any point.
1065 ///
1066 /// Initial model state if supported by the Agent
1067 #[cfg(feature = "unstable_session_model")]
1068 #[serde(skip_serializing_if = "Option::is_none")]
1069 pub models: Option<SessionModelState>,
1070 /// Initial session configuration options if supported by the Agent.
1071 #[serde(skip_serializing_if = "Option::is_none")]
1072 pub config_options: Option<Vec<SessionConfigOption>>,
1073 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1074 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1075 /// these keys.
1076 ///
1077 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1078 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1079 pub meta: Option<Meta>,
1080}
1081
1082#[cfg(feature = "unstable_session_fork")]
1083impl ForkSessionResponse {
1084 #[must_use]
1085 pub fn new(session_id: impl Into<SessionId>) -> Self {
1086 Self {
1087 session_id: session_id.into(),
1088 modes: None,
1089 #[cfg(feature = "unstable_session_model")]
1090 models: None,
1091 config_options: None,
1092 meta: None,
1093 }
1094 }
1095
1096 /// Initial mode state if supported by the Agent
1097 ///
1098 /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
1099 #[must_use]
1100 pub fn modes(mut self, modes: impl IntoOption<SessionModeState>) -> Self {
1101 self.modes = modes.into_option();
1102 self
1103 }
1104
1105 /// **UNSTABLE**
1106 ///
1107 /// This capability is not part of the spec yet, and may be removed or changed at any point.
1108 ///
1109 /// Initial model state if supported by the Agent
1110 #[cfg(feature = "unstable_session_model")]
1111 #[must_use]
1112 pub fn models(mut self, models: impl IntoOption<SessionModelState>) -> Self {
1113 self.models = models.into_option();
1114 self
1115 }
1116
1117 /// Initial session configuration options if supported by the Agent.
1118 #[must_use]
1119 pub fn config_options(
1120 mut self,
1121 config_options: impl IntoOption<Vec<SessionConfigOption>>,
1122 ) -> Self {
1123 self.config_options = config_options.into_option();
1124 self
1125 }
1126
1127 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1128 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1129 /// these keys.
1130 ///
1131 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1132 #[must_use]
1133 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1134 self.meta = meta.into_option();
1135 self
1136 }
1137}
1138
1139// Resume session
1140
1141/// **UNSTABLE**
1142///
1143/// This capability is not part of the spec yet, and may be removed or changed at any point.
1144///
1145/// Request parameters for resuming an existing session.
1146///
1147/// Resumes an existing session without returning previous messages (unlike `session/load`).
1148/// This is useful for agents that can resume sessions but don't implement full session loading.
1149///
1150/// Only available if the Agent supports the `session.resume` capability.
1151#[cfg(feature = "unstable_session_resume")]
1152#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1153#[schemars(extend("x-side" = "agent", "x-method" = SESSION_RESUME_METHOD_NAME))]
1154#[serde(rename_all = "camelCase")]
1155#[non_exhaustive]
1156pub struct ResumeSessionRequest {
1157 /// The ID of the session to resume.
1158 pub session_id: SessionId,
1159 /// The working directory for this session.
1160 pub cwd: PathBuf,
1161 /// List of MCP servers to connect to for this session.
1162 #[serde(default, skip_serializing_if = "Vec::is_empty")]
1163 pub mcp_servers: Vec<McpServer>,
1164 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1165 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1166 /// these keys.
1167 ///
1168 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1169 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1170 pub meta: Option<Meta>,
1171}
1172
1173#[cfg(feature = "unstable_session_resume")]
1174impl ResumeSessionRequest {
1175 #[must_use]
1176 pub fn new(session_id: impl Into<SessionId>, cwd: impl Into<PathBuf>) -> Self {
1177 Self {
1178 session_id: session_id.into(),
1179 cwd: cwd.into(),
1180 mcp_servers: vec![],
1181 meta: None,
1182 }
1183 }
1184
1185 /// List of MCP servers to connect to for this session.
1186 #[must_use]
1187 pub fn mcp_servers(mut self, mcp_servers: Vec<McpServer>) -> Self {
1188 self.mcp_servers = mcp_servers;
1189 self
1190 }
1191
1192 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1193 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1194 /// these keys.
1195 ///
1196 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1197 #[must_use]
1198 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1199 self.meta = meta.into_option();
1200 self
1201 }
1202}
1203
1204/// **UNSTABLE**
1205///
1206/// This capability is not part of the spec yet, and may be removed or changed at any point.
1207///
1208/// Response from resuming an existing session.
1209#[cfg(feature = "unstable_session_resume")]
1210#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1211#[schemars(extend("x-side" = "agent", "x-method" = SESSION_RESUME_METHOD_NAME))]
1212#[serde(rename_all = "camelCase")]
1213#[non_exhaustive]
1214pub struct ResumeSessionResponse {
1215 /// Initial mode state if supported by the Agent
1216 ///
1217 /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
1218 #[serde(default, skip_serializing_if = "Option::is_none")]
1219 pub modes: Option<SessionModeState>,
1220 /// **UNSTABLE**
1221 ///
1222 /// This capability is not part of the spec yet, and may be removed or changed at any point.
1223 ///
1224 /// Initial model state if supported by the Agent
1225 #[cfg(feature = "unstable_session_model")]
1226 #[serde(default, skip_serializing_if = "Option::is_none")]
1227 pub models: Option<SessionModelState>,
1228 /// Initial session configuration options if supported by the Agent.
1229 #[serde(default, skip_serializing_if = "Option::is_none")]
1230 pub config_options: Option<Vec<SessionConfigOption>>,
1231 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1232 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1233 /// these keys.
1234 ///
1235 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1236 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1237 pub meta: Option<Meta>,
1238}
1239
1240#[cfg(feature = "unstable_session_resume")]
1241impl ResumeSessionResponse {
1242 #[must_use]
1243 pub fn new() -> Self {
1244 Self::default()
1245 }
1246
1247 /// Initial mode state if supported by the Agent
1248 ///
1249 /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
1250 #[must_use]
1251 pub fn modes(mut self, modes: impl IntoOption<SessionModeState>) -> Self {
1252 self.modes = modes.into_option();
1253 self
1254 }
1255
1256 /// **UNSTABLE**
1257 ///
1258 /// This capability is not part of the spec yet, and may be removed or changed at any point.
1259 ///
1260 /// Initial model state if supported by the Agent
1261 #[cfg(feature = "unstable_session_model")]
1262 #[must_use]
1263 pub fn models(mut self, models: impl IntoOption<SessionModelState>) -> Self {
1264 self.models = models.into_option();
1265 self
1266 }
1267
1268 /// Initial session configuration options if supported by the Agent.
1269 #[must_use]
1270 pub fn config_options(
1271 mut self,
1272 config_options: impl IntoOption<Vec<SessionConfigOption>>,
1273 ) -> Self {
1274 self.config_options = config_options.into_option();
1275 self
1276 }
1277
1278 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1279 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1280 /// these keys.
1281 ///
1282 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1283 #[must_use]
1284 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1285 self.meta = meta.into_option();
1286 self
1287 }
1288}
1289
1290// Stop session
1291
1292/// **UNSTABLE**
1293///
1294/// This capability is not part of the spec yet, and may be removed or changed at any point.
1295///
1296/// Request parameters for stopping an active session.
1297///
1298/// If supported, the agent **must** cancel any ongoing work related to the session
1299/// (treat it as if `session/cancel` was called) and then free up any resources
1300/// associated with the session.
1301///
1302/// Only available if the Agent supports the `session.stop` capability.
1303#[cfg(feature = "unstable_session_stop")]
1304#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1305#[schemars(extend("x-side" = "agent", "x-method" = SESSION_STOP_METHOD_NAME))]
1306#[serde(rename_all = "camelCase")]
1307#[non_exhaustive]
1308pub struct StopSessionRequest {
1309 /// The ID of the session to stop.
1310 pub session_id: SessionId,
1311 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1312 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1313 /// these keys.
1314 ///
1315 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1316 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1317 pub meta: Option<Meta>,
1318}
1319
1320#[cfg(feature = "unstable_session_stop")]
1321impl StopSessionRequest {
1322 #[must_use]
1323 pub fn new(session_id: impl Into<SessionId>) -> Self {
1324 Self {
1325 session_id: session_id.into(),
1326 meta: None,
1327 }
1328 }
1329
1330 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1331 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1332 /// these keys.
1333 ///
1334 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1335 #[must_use]
1336 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1337 self.meta = meta.into_option();
1338 self
1339 }
1340}
1341
1342/// **UNSTABLE**
1343///
1344/// This capability is not part of the spec yet, and may be removed or changed at any point.
1345///
1346/// Response from stopping a session.
1347#[cfg(feature = "unstable_session_stop")]
1348#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1349#[schemars(extend("x-side" = "agent", "x-method" = SESSION_STOP_METHOD_NAME))]
1350#[serde(rename_all = "camelCase")]
1351#[non_exhaustive]
1352pub struct StopSessionResponse {
1353 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1354 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1355 /// these keys.
1356 ///
1357 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1358 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1359 pub meta: Option<Meta>,
1360}
1361
1362#[cfg(feature = "unstable_session_stop")]
1363impl StopSessionResponse {
1364 #[must_use]
1365 pub fn new() -> Self {
1366 Self::default()
1367 }
1368
1369 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1370 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1371 /// these keys.
1372 ///
1373 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1374 #[must_use]
1375 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1376 self.meta = meta.into_option();
1377 self
1378 }
1379}
1380
1381// List sessions
1382
1383/// **UNSTABLE**
1384///
1385/// This capability is not part of the spec yet, and may be removed or changed at any point.
1386///
1387/// Request parameters for listing existing sessions.
1388///
1389/// Only available if the Agent supports the `listSessions` capability.
1390#[cfg(feature = "unstable_session_list")]
1391#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1392#[schemars(extend("x-side" = "agent", "x-method" = SESSION_LIST_METHOD_NAME))]
1393#[serde(rename_all = "camelCase")]
1394#[non_exhaustive]
1395pub struct ListSessionsRequest {
1396 /// Filter sessions by working directory. Must be an absolute path.
1397 #[serde(skip_serializing_if = "Option::is_none")]
1398 pub cwd: Option<PathBuf>,
1399 /// Opaque cursor token from a previous response's nextCursor field for cursor-based pagination
1400 #[serde(skip_serializing_if = "Option::is_none")]
1401 pub cursor: Option<String>,
1402 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1403 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1404 /// these keys.
1405 ///
1406 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1407 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1408 pub meta: Option<Meta>,
1409}
1410
1411#[cfg(feature = "unstable_session_list")]
1412impl ListSessionsRequest {
1413 #[must_use]
1414 pub fn new() -> Self {
1415 Self::default()
1416 }
1417
1418 /// Filter sessions by working directory. Must be an absolute path.
1419 #[must_use]
1420 pub fn cwd(mut self, cwd: impl IntoOption<PathBuf>) -> Self {
1421 self.cwd = cwd.into_option();
1422 self
1423 }
1424
1425 /// Opaque cursor token from a previous response's nextCursor field for cursor-based pagination
1426 #[must_use]
1427 pub fn cursor(mut self, cursor: impl IntoOption<String>) -> Self {
1428 self.cursor = cursor.into_option();
1429 self
1430 }
1431
1432 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1433 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1434 /// these keys.
1435 ///
1436 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1437 #[must_use]
1438 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1439 self.meta = meta.into_option();
1440 self
1441 }
1442}
1443
1444/// **UNSTABLE**
1445///
1446/// This capability is not part of the spec yet, and may be removed or changed at any point.
1447///
1448/// Response from listing sessions.
1449#[cfg(feature = "unstable_session_list")]
1450#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1451#[schemars(extend("x-side" = "agent", "x-method" = SESSION_LIST_METHOD_NAME))]
1452#[serde(rename_all = "camelCase")]
1453#[non_exhaustive]
1454pub struct ListSessionsResponse {
1455 /// Array of session information objects
1456 pub sessions: Vec<SessionInfo>,
1457 /// Opaque cursor token. If present, pass this in the next request's cursor parameter
1458 /// to fetch the next page. If absent, there are no more results.
1459 #[serde(skip_serializing_if = "Option::is_none")]
1460 pub next_cursor: Option<String>,
1461 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1462 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1463 /// these keys.
1464 ///
1465 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1466 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1467 pub meta: Option<Meta>,
1468}
1469
1470#[cfg(feature = "unstable_session_list")]
1471impl ListSessionsResponse {
1472 #[must_use]
1473 pub fn new(sessions: Vec<SessionInfo>) -> Self {
1474 Self {
1475 sessions,
1476 next_cursor: None,
1477 meta: None,
1478 }
1479 }
1480
1481 #[must_use]
1482 pub fn next_cursor(mut self, next_cursor: impl IntoOption<String>) -> Self {
1483 self.next_cursor = next_cursor.into_option();
1484 self
1485 }
1486
1487 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1488 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1489 /// these keys.
1490 ///
1491 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1492 #[must_use]
1493 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1494 self.meta = meta.into_option();
1495 self
1496 }
1497}
1498
1499/// **UNSTABLE**
1500///
1501/// This capability is not part of the spec yet, and may be removed or changed at any point.
1502///
1503/// Information about a session returned by session/list
1504#[cfg(feature = "unstable_session_list")]
1505#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1506#[serde(rename_all = "camelCase")]
1507#[non_exhaustive]
1508pub struct SessionInfo {
1509 /// Unique identifier for the session
1510 pub session_id: SessionId,
1511 /// The working directory for this session. Must be an absolute path.
1512 pub cwd: PathBuf,
1513 /// Human-readable title for the session
1514 #[serde(skip_serializing_if = "Option::is_none")]
1515 pub title: Option<String>,
1516 /// ISO 8601 timestamp of last activity
1517 #[serde(skip_serializing_if = "Option::is_none")]
1518 pub updated_at: Option<String>,
1519 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1520 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1521 /// these keys.
1522 ///
1523 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1524 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1525 pub meta: Option<Meta>,
1526}
1527
1528#[cfg(feature = "unstable_session_list")]
1529impl SessionInfo {
1530 #[must_use]
1531 pub fn new(session_id: impl Into<SessionId>, cwd: impl Into<PathBuf>) -> Self {
1532 Self {
1533 session_id: session_id.into(),
1534 cwd: cwd.into(),
1535 title: None,
1536 updated_at: None,
1537 meta: None,
1538 }
1539 }
1540
1541 /// Human-readable title for the session
1542 #[must_use]
1543 pub fn title(mut self, title: impl IntoOption<String>) -> Self {
1544 self.title = title.into_option();
1545 self
1546 }
1547
1548 /// ISO 8601 timestamp of last activity
1549 #[must_use]
1550 pub fn updated_at(mut self, updated_at: impl IntoOption<String>) -> Self {
1551 self.updated_at = updated_at.into_option();
1552 self
1553 }
1554
1555 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1556 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1557 /// these keys.
1558 ///
1559 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1560 #[must_use]
1561 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1562 self.meta = meta.into_option();
1563 self
1564 }
1565}
1566
1567// Session modes
1568
1569/// The set of modes and the one currently active.
1570#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1571#[serde(rename_all = "camelCase")]
1572#[non_exhaustive]
1573pub struct SessionModeState {
1574 /// The current mode the Agent is in.
1575 pub current_mode_id: SessionModeId,
1576 /// The set of modes that the Agent can operate in
1577 pub available_modes: Vec<SessionMode>,
1578 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1579 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1580 /// these keys.
1581 ///
1582 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1583 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1584 pub meta: Option<Meta>,
1585}
1586
1587impl SessionModeState {
1588 #[must_use]
1589 pub fn new(
1590 current_mode_id: impl Into<SessionModeId>,
1591 available_modes: Vec<SessionMode>,
1592 ) -> Self {
1593 Self {
1594 current_mode_id: current_mode_id.into(),
1595 available_modes,
1596 meta: None,
1597 }
1598 }
1599
1600 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1601 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1602 /// these keys.
1603 ///
1604 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1605 #[must_use]
1606 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1607 self.meta = meta.into_option();
1608 self
1609 }
1610}
1611
1612/// A mode the agent can operate in.
1613///
1614/// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
1615#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1616#[serde(rename_all = "camelCase")]
1617#[non_exhaustive]
1618pub struct SessionMode {
1619 pub id: SessionModeId,
1620 pub name: String,
1621 #[serde(default, skip_serializing_if = "Option::is_none")]
1622 pub description: Option<String>,
1623 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1624 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1625 /// these keys.
1626 ///
1627 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1628 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1629 pub meta: Option<Meta>,
1630}
1631
1632impl SessionMode {
1633 #[must_use]
1634 pub fn new(id: impl Into<SessionModeId>, name: impl Into<String>) -> Self {
1635 Self {
1636 id: id.into(),
1637 name: name.into(),
1638 description: None,
1639 meta: None,
1640 }
1641 }
1642
1643 #[must_use]
1644 pub fn description(mut self, description: impl IntoOption<String>) -> Self {
1645 self.description = description.into_option();
1646 self
1647 }
1648
1649 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1650 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1651 /// these keys.
1652 ///
1653 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1654 #[must_use]
1655 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1656 self.meta = meta.into_option();
1657 self
1658 }
1659}
1660
1661/// Unique identifier for a Session Mode.
1662#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, From, Display)]
1663#[serde(transparent)]
1664#[from(Arc<str>, String, &'static str)]
1665#[non_exhaustive]
1666pub struct SessionModeId(pub Arc<str>);
1667
1668impl SessionModeId {
1669 #[must_use]
1670 pub fn new(id: impl Into<Arc<str>>) -> Self {
1671 Self(id.into())
1672 }
1673}
1674
1675/// Request parameters for setting a session mode.
1676#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1677#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODE_METHOD_NAME))]
1678#[serde(rename_all = "camelCase")]
1679#[non_exhaustive]
1680pub struct SetSessionModeRequest {
1681 /// The ID of the session to set the mode for.
1682 pub session_id: SessionId,
1683 /// The ID of the mode to set.
1684 pub mode_id: SessionModeId,
1685 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1686 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1687 /// these keys.
1688 ///
1689 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1690 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1691 pub meta: Option<Meta>,
1692}
1693
1694impl SetSessionModeRequest {
1695 #[must_use]
1696 pub fn new(session_id: impl Into<SessionId>, mode_id: impl Into<SessionModeId>) -> Self {
1697 Self {
1698 session_id: session_id.into(),
1699 mode_id: mode_id.into(),
1700 meta: None,
1701 }
1702 }
1703
1704 #[must_use]
1705 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1706 self.meta = meta.into_option();
1707 self
1708 }
1709}
1710
1711/// Response to `session/set_mode` method.
1712#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1713#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODE_METHOD_NAME))]
1714#[serde(rename_all = "camelCase")]
1715#[non_exhaustive]
1716pub struct SetSessionModeResponse {
1717 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1718 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1719 /// these keys.
1720 ///
1721 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1722 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1723 pub meta: Option<Meta>,
1724}
1725
1726impl SetSessionModeResponse {
1727 #[must_use]
1728 pub fn new() -> Self {
1729 Self::default()
1730 }
1731
1732 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1733 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1734 /// these keys.
1735 ///
1736 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1737 #[must_use]
1738 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1739 self.meta = meta.into_option();
1740 self
1741 }
1742}
1743
1744// Session config options
1745
1746/// Unique identifier for a session configuration option.
1747#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, From, Display)]
1748#[serde(transparent)]
1749#[from(Arc<str>, String, &'static str)]
1750#[non_exhaustive]
1751pub struct SessionConfigId(pub Arc<str>);
1752
1753impl SessionConfigId {
1754 #[must_use]
1755 pub fn new(id: impl Into<Arc<str>>) -> Self {
1756 Self(id.into())
1757 }
1758}
1759
1760/// Unique identifier for a session configuration option value.
1761#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, From, Display)]
1762#[serde(transparent)]
1763#[from(Arc<str>, String, &'static str)]
1764#[non_exhaustive]
1765pub struct SessionConfigValueId(pub Arc<str>);
1766
1767impl SessionConfigValueId {
1768 #[must_use]
1769 pub fn new(id: impl Into<Arc<str>>) -> Self {
1770 Self(id.into())
1771 }
1772}
1773
1774/// Unique identifier for a session configuration option value group.
1775#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, From, Display)]
1776#[serde(transparent)]
1777#[from(Arc<str>, String, &'static str)]
1778#[non_exhaustive]
1779pub struct SessionConfigGroupId(pub Arc<str>);
1780
1781impl SessionConfigGroupId {
1782 #[must_use]
1783 pub fn new(id: impl Into<Arc<str>>) -> Self {
1784 Self(id.into())
1785 }
1786}
1787
1788/// A possible value for a session configuration option.
1789#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1790#[serde(rename_all = "camelCase")]
1791#[non_exhaustive]
1792pub struct SessionConfigSelectOption {
1793 /// Unique identifier for this option value.
1794 pub value: SessionConfigValueId,
1795 /// Human-readable label for this option value.
1796 pub name: String,
1797 /// Optional description for this option value.
1798 #[serde(default, skip_serializing_if = "Option::is_none")]
1799 pub description: Option<String>,
1800 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1801 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1802 /// these keys.
1803 ///
1804 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1805 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1806 pub meta: Option<Meta>,
1807}
1808
1809impl SessionConfigSelectOption {
1810 #[must_use]
1811 pub fn new(value: impl Into<SessionConfigValueId>, name: impl Into<String>) -> Self {
1812 Self {
1813 value: value.into(),
1814 name: name.into(),
1815 description: None,
1816 meta: None,
1817 }
1818 }
1819
1820 #[must_use]
1821 pub fn description(mut self, description: impl IntoOption<String>) -> Self {
1822 self.description = description.into_option();
1823 self
1824 }
1825
1826 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1827 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1828 /// these keys.
1829 ///
1830 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1831 #[must_use]
1832 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1833 self.meta = meta.into_option();
1834 self
1835 }
1836}
1837
1838/// A group of possible values for a session configuration option.
1839#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1840#[serde(rename_all = "camelCase")]
1841#[non_exhaustive]
1842pub struct SessionConfigSelectGroup {
1843 /// Unique identifier for this group.
1844 pub group: SessionConfigGroupId,
1845 /// Human-readable label for this group.
1846 pub name: String,
1847 /// The set of option values in this group.
1848 pub options: Vec<SessionConfigSelectOption>,
1849 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1850 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1851 /// these keys.
1852 ///
1853 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1854 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1855 pub meta: Option<Meta>,
1856}
1857
1858impl SessionConfigSelectGroup {
1859 #[must_use]
1860 pub fn new(
1861 group: impl Into<SessionConfigGroupId>,
1862 name: impl Into<String>,
1863 options: Vec<SessionConfigSelectOption>,
1864 ) -> Self {
1865 Self {
1866 group: group.into(),
1867 name: name.into(),
1868 options,
1869 meta: None,
1870 }
1871 }
1872
1873 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1874 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1875 /// these keys.
1876 ///
1877 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1878 #[must_use]
1879 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1880 self.meta = meta.into_option();
1881 self
1882 }
1883}
1884
1885/// Possible values for a session configuration option.
1886#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1887#[serde(untagged)]
1888#[non_exhaustive]
1889pub enum SessionConfigSelectOptions {
1890 /// A flat list of options with no grouping.
1891 Ungrouped(Vec<SessionConfigSelectOption>),
1892 /// A list of options grouped under headers.
1893 Grouped(Vec<SessionConfigSelectGroup>),
1894}
1895
1896impl From<Vec<SessionConfigSelectOption>> for SessionConfigSelectOptions {
1897 fn from(options: Vec<SessionConfigSelectOption>) -> Self {
1898 SessionConfigSelectOptions::Ungrouped(options)
1899 }
1900}
1901
1902impl From<Vec<SessionConfigSelectGroup>> for SessionConfigSelectOptions {
1903 fn from(groups: Vec<SessionConfigSelectGroup>) -> Self {
1904 SessionConfigSelectOptions::Grouped(groups)
1905 }
1906}
1907
1908/// A single-value selector (dropdown) session configuration option payload.
1909#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1910#[serde(rename_all = "camelCase")]
1911#[non_exhaustive]
1912pub struct SessionConfigSelect {
1913 /// The currently selected value.
1914 pub current_value: SessionConfigValueId,
1915 /// The set of selectable options.
1916 pub options: SessionConfigSelectOptions,
1917}
1918
1919impl SessionConfigSelect {
1920 #[must_use]
1921 pub fn new(
1922 current_value: impl Into<SessionConfigValueId>,
1923 options: impl Into<SessionConfigSelectOptions>,
1924 ) -> Self {
1925 Self {
1926 current_value: current_value.into(),
1927 options: options.into(),
1928 }
1929 }
1930}
1931
1932/// Semantic category for a session configuration option.
1933///
1934/// This is intended to help Clients distinguish broadly common selectors (e.g. model selector vs
1935/// session mode selector vs thought/reasoning level) for UX purposes (keyboard shortcuts, icons,
1936/// placement). It MUST NOT be required for correctness. Clients MUST handle missing or unknown
1937/// categories gracefully.
1938///
1939/// Category names beginning with `_` are free for custom use, like other ACP extension methods.
1940/// Category names that do not begin with `_` are reserved for the ACP spec.
1941#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1942#[serde(rename_all = "snake_case")]
1943#[non_exhaustive]
1944pub enum SessionConfigOptionCategory {
1945 /// Session mode selector.
1946 Mode,
1947 /// Model selector.
1948 Model,
1949 /// Thought/reasoning level selector.
1950 ThoughtLevel,
1951 /// Unknown / uncategorized selector.
1952 #[serde(untagged)]
1953 Other(String),
1954}
1955
1956/// Type-specific session configuration option payload.
1957#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1958#[serde(tag = "type", rename_all = "snake_case")]
1959#[schemars(extend("discriminator" = {"propertyName": "type"}))]
1960#[non_exhaustive]
1961pub enum SessionConfigKind {
1962 /// Single-value selector (dropdown).
1963 Select(SessionConfigSelect),
1964}
1965
1966/// A session configuration option selector and its current state.
1967#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1968#[serde(rename_all = "camelCase")]
1969#[non_exhaustive]
1970pub struct SessionConfigOption {
1971 /// Unique identifier for the configuration option.
1972 pub id: SessionConfigId,
1973 /// Human-readable label for the option.
1974 pub name: String,
1975 /// Optional description for the Client to display to the user.
1976 #[serde(default, skip_serializing_if = "Option::is_none")]
1977 pub description: Option<String>,
1978 /// Optional semantic category for this option (UX only).
1979 #[serde(default, skip_serializing_if = "Option::is_none")]
1980 pub category: Option<SessionConfigOptionCategory>,
1981 /// Type-specific fields for this configuration option.
1982 #[serde(flatten)]
1983 pub kind: SessionConfigKind,
1984 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1985 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1986 /// these keys.
1987 ///
1988 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1989 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1990 pub meta: Option<Meta>,
1991}
1992
1993impl SessionConfigOption {
1994 #[must_use]
1995 pub fn new(
1996 id: impl Into<SessionConfigId>,
1997 name: impl Into<String>,
1998 kind: SessionConfigKind,
1999 ) -> Self {
2000 Self {
2001 id: id.into(),
2002 name: name.into(),
2003 description: None,
2004 category: None,
2005 kind,
2006 meta: None,
2007 }
2008 }
2009
2010 #[must_use]
2011 pub fn select(
2012 id: impl Into<SessionConfigId>,
2013 name: impl Into<String>,
2014 current_value: impl Into<SessionConfigValueId>,
2015 options: impl Into<SessionConfigSelectOptions>,
2016 ) -> Self {
2017 Self::new(
2018 id,
2019 name,
2020 SessionConfigKind::Select(SessionConfigSelect::new(current_value, options)),
2021 )
2022 }
2023
2024 #[must_use]
2025 pub fn description(mut self, description: impl IntoOption<String>) -> Self {
2026 self.description = description.into_option();
2027 self
2028 }
2029
2030 #[must_use]
2031 pub fn category(mut self, category: impl IntoOption<SessionConfigOptionCategory>) -> Self {
2032 self.category = category.into_option();
2033 self
2034 }
2035
2036 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2037 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2038 /// these keys.
2039 ///
2040 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2041 #[must_use]
2042 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2043 self.meta = meta.into_option();
2044 self
2045 }
2046}
2047
2048/// Request parameters for setting a session configuration option.
2049#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2050#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_CONFIG_OPTION_METHOD_NAME))]
2051#[serde(rename_all = "camelCase")]
2052#[non_exhaustive]
2053pub struct SetSessionConfigOptionRequest {
2054 /// The ID of the session to set the configuration option for.
2055 pub session_id: SessionId,
2056 /// The ID of the configuration option to set.
2057 pub config_id: SessionConfigId,
2058 /// The ID of the configuration option value to set.
2059 pub value: SessionConfigValueId,
2060 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2061 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2062 /// these keys.
2063 ///
2064 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2065 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2066 pub meta: Option<Meta>,
2067}
2068
2069impl SetSessionConfigOptionRequest {
2070 #[must_use]
2071 pub fn new(
2072 session_id: impl Into<SessionId>,
2073 config_id: impl Into<SessionConfigId>,
2074 value: impl Into<SessionConfigValueId>,
2075 ) -> Self {
2076 Self {
2077 session_id: session_id.into(),
2078 config_id: config_id.into(),
2079 value: value.into(),
2080 meta: None,
2081 }
2082 }
2083
2084 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2085 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2086 /// these keys.
2087 ///
2088 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2089 #[must_use]
2090 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2091 self.meta = meta.into_option();
2092 self
2093 }
2094}
2095
2096/// Response to `session/set_config_option` method.
2097#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2098#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_CONFIG_OPTION_METHOD_NAME))]
2099#[serde(rename_all = "camelCase")]
2100#[non_exhaustive]
2101pub struct SetSessionConfigOptionResponse {
2102 /// The full set of configuration options and their current values.
2103 pub config_options: Vec<SessionConfigOption>,
2104 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2105 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2106 /// these keys.
2107 ///
2108 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2109 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2110 pub meta: Option<Meta>,
2111}
2112
2113impl SetSessionConfigOptionResponse {
2114 #[must_use]
2115 pub fn new(config_options: Vec<SessionConfigOption>) -> Self {
2116 Self {
2117 config_options,
2118 meta: None,
2119 }
2120 }
2121
2122 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2123 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2124 /// these keys.
2125 ///
2126 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2127 #[must_use]
2128 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2129 self.meta = meta.into_option();
2130 self
2131 }
2132}
2133
2134// MCP
2135
2136/// Configuration for connecting to an MCP (Model Context Protocol) server.
2137///
2138/// MCP servers provide tools and context that the agent can use when
2139/// processing prompts.
2140///
2141/// See protocol docs: [MCP Servers](https://agentclientprotocol.com/protocol/session-setup#mcp-servers)
2142#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2143#[serde(tag = "type", rename_all = "snake_case")]
2144#[non_exhaustive]
2145pub enum McpServer {
2146 /// HTTP transport configuration
2147 ///
2148 /// Only available when the Agent capabilities indicate `mcp_capabilities.http` is `true`.
2149 Http(McpServerHttp),
2150 /// SSE transport configuration
2151 ///
2152 /// Only available when the Agent capabilities indicate `mcp_capabilities.sse` is `true`.
2153 Sse(McpServerSse),
2154 /// Stdio transport configuration
2155 ///
2156 /// All Agents MUST support this transport.
2157 #[serde(untagged)]
2158 Stdio(McpServerStdio),
2159}
2160
2161/// HTTP transport configuration for MCP.
2162#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2163#[serde(rename_all = "camelCase")]
2164#[non_exhaustive]
2165pub struct McpServerHttp {
2166 /// Human-readable name identifying this MCP server.
2167 pub name: String,
2168 /// URL to the MCP server.
2169 pub url: String,
2170 /// HTTP headers to set when making requests to the MCP server.
2171 pub headers: Vec<HttpHeader>,
2172 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2173 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2174 /// these keys.
2175 ///
2176 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2177 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2178 pub meta: Option<Meta>,
2179}
2180
2181impl McpServerHttp {
2182 #[must_use]
2183 pub fn new(name: impl Into<String>, url: impl Into<String>) -> Self {
2184 Self {
2185 name: name.into(),
2186 url: url.into(),
2187 headers: Vec::new(),
2188 meta: None,
2189 }
2190 }
2191
2192 /// HTTP headers to set when making requests to the MCP server.
2193 #[must_use]
2194 pub fn headers(mut self, headers: Vec<HttpHeader>) -> Self {
2195 self.headers = headers;
2196 self
2197 }
2198
2199 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2200 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2201 /// these keys.
2202 ///
2203 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2204 #[must_use]
2205 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2206 self.meta = meta.into_option();
2207 self
2208 }
2209}
2210
2211/// SSE transport configuration for MCP.
2212#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2213#[serde(rename_all = "camelCase")]
2214#[non_exhaustive]
2215pub struct McpServerSse {
2216 /// Human-readable name identifying this MCP server.
2217 pub name: String,
2218 /// URL to the MCP server.
2219 pub url: String,
2220 /// HTTP headers to set when making requests to the MCP server.
2221 pub headers: Vec<HttpHeader>,
2222 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2223 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2224 /// these keys.
2225 ///
2226 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2227 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2228 pub meta: Option<Meta>,
2229}
2230
2231impl McpServerSse {
2232 #[must_use]
2233 pub fn new(name: impl Into<String>, url: impl Into<String>) -> Self {
2234 Self {
2235 name: name.into(),
2236 url: url.into(),
2237 headers: Vec::new(),
2238 meta: None,
2239 }
2240 }
2241
2242 /// HTTP headers to set when making requests to the MCP server.
2243 #[must_use]
2244 pub fn headers(mut self, headers: Vec<HttpHeader>) -> Self {
2245 self.headers = headers;
2246 self
2247 }
2248
2249 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2250 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2251 /// these keys.
2252 ///
2253 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2254 #[must_use]
2255 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2256 self.meta = meta.into_option();
2257 self
2258 }
2259}
2260
2261/// Stdio transport configuration for MCP.
2262#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2263#[serde(rename_all = "camelCase")]
2264#[non_exhaustive]
2265pub struct McpServerStdio {
2266 /// Human-readable name identifying this MCP server.
2267 pub name: String,
2268 /// Path to the MCP server executable.
2269 pub command: PathBuf,
2270 /// Command-line arguments to pass to the MCP server.
2271 pub args: Vec<String>,
2272 /// Environment variables to set when launching the MCP server.
2273 pub env: Vec<EnvVariable>,
2274 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2275 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2276 /// these keys.
2277 ///
2278 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2279 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2280 pub meta: Option<Meta>,
2281}
2282
2283impl McpServerStdio {
2284 #[must_use]
2285 pub fn new(name: impl Into<String>, command: impl Into<PathBuf>) -> Self {
2286 Self {
2287 name: name.into(),
2288 command: command.into(),
2289 args: Vec::new(),
2290 env: Vec::new(),
2291 meta: None,
2292 }
2293 }
2294
2295 /// Command-line arguments to pass to the MCP server.
2296 #[must_use]
2297 pub fn args(mut self, args: Vec<String>) -> Self {
2298 self.args = args;
2299 self
2300 }
2301
2302 /// Environment variables to set when launching the MCP server.
2303 #[must_use]
2304 pub fn env(mut self, env: Vec<EnvVariable>) -> Self {
2305 self.env = env;
2306 self
2307 }
2308
2309 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2310 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2311 /// these keys.
2312 ///
2313 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2314 #[must_use]
2315 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2316 self.meta = meta.into_option();
2317 self
2318 }
2319}
2320
2321/// An environment variable to set when launching an MCP server.
2322#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2323#[serde(rename_all = "camelCase")]
2324#[non_exhaustive]
2325pub struct EnvVariable {
2326 /// The name of the environment variable.
2327 pub name: String,
2328 /// The value to set for the environment variable.
2329 pub value: String,
2330 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2331 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2332 /// these keys.
2333 ///
2334 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2335 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2336 pub meta: Option<Meta>,
2337}
2338
2339impl EnvVariable {
2340 #[must_use]
2341 pub fn new(name: impl Into<String>, value: impl Into<String>) -> Self {
2342 Self {
2343 name: name.into(),
2344 value: value.into(),
2345 meta: None,
2346 }
2347 }
2348
2349 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2350 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2351 /// these keys.
2352 ///
2353 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2354 #[must_use]
2355 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2356 self.meta = meta.into_option();
2357 self
2358 }
2359}
2360
2361/// An HTTP header to set when making requests to the MCP server.
2362#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2363#[serde(rename_all = "camelCase")]
2364#[non_exhaustive]
2365pub struct HttpHeader {
2366 /// The name of the HTTP header.
2367 pub name: String,
2368 /// The value to set for the HTTP header.
2369 pub value: String,
2370 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2371 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2372 /// these keys.
2373 ///
2374 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2375 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2376 pub meta: Option<Meta>,
2377}
2378
2379impl HttpHeader {
2380 #[must_use]
2381 pub fn new(name: impl Into<String>, value: impl Into<String>) -> Self {
2382 Self {
2383 name: name.into(),
2384 value: value.into(),
2385 meta: None,
2386 }
2387 }
2388
2389 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2390 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2391 /// these keys.
2392 ///
2393 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2394 #[must_use]
2395 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2396 self.meta = meta.into_option();
2397 self
2398 }
2399}
2400
2401// Prompt
2402
2403/// Request parameters for sending a user prompt to the agent.
2404///
2405/// Contains the user's message and any additional context.
2406///
2407/// See protocol docs: [User Message](https://agentclientprotocol.com/protocol/prompt-turn#1-user-message)
2408#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
2409#[schemars(extend("x-side" = "agent", "x-method" = SESSION_PROMPT_METHOD_NAME))]
2410#[serde(rename_all = "camelCase")]
2411#[non_exhaustive]
2412pub struct PromptRequest {
2413 /// The ID of the session to send this user message to
2414 pub session_id: SessionId,
2415 /// **UNSTABLE**
2416 ///
2417 /// This capability is not part of the spec yet, and may be removed or changed at any point.
2418 ///
2419 /// A client-generated unique identifier for this user message.
2420 ///
2421 /// If provided, the Agent SHOULD echo this value as `userMessageId` in the
2422 /// [`PromptResponse`] to confirm it was recorded.
2423 /// Both clients and agents MUST use UUID format for message IDs.
2424 #[cfg(feature = "unstable_message_id")]
2425 #[serde(skip_serializing_if = "Option::is_none")]
2426 pub message_id: Option<String>,
2427 /// The blocks of content that compose the user's message.
2428 ///
2429 /// As a baseline, the Agent MUST support [`ContentBlock::Text`] and [`ContentBlock::ResourceLink`],
2430 /// while other variants are optionally enabled via [`PromptCapabilities`].
2431 ///
2432 /// The Client MUST adapt its interface according to [`PromptCapabilities`].
2433 ///
2434 /// The client MAY include referenced pieces of context as either
2435 /// [`ContentBlock::Resource`] or [`ContentBlock::ResourceLink`].
2436 ///
2437 /// When available, [`ContentBlock::Resource`] is preferred
2438 /// as it avoids extra round-trips and allows the message to include
2439 /// pieces of context from sources the agent may not have access to.
2440 pub prompt: Vec<ContentBlock>,
2441 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2442 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2443 /// these keys.
2444 ///
2445 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2446 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2447 pub meta: Option<Meta>,
2448}
2449
2450impl PromptRequest {
2451 #[must_use]
2452 pub fn new(session_id: impl Into<SessionId>, prompt: Vec<ContentBlock>) -> Self {
2453 Self {
2454 session_id: session_id.into(),
2455 #[cfg(feature = "unstable_message_id")]
2456 message_id: None,
2457 prompt,
2458 meta: None,
2459 }
2460 }
2461
2462 /// **UNSTABLE**
2463 ///
2464 /// This capability is not part of the spec yet, and may be removed or changed at any point.
2465 ///
2466 /// A client-generated unique identifier for this user message.
2467 ///
2468 /// If provided, the Agent SHOULD echo this value as `userMessageId` in the
2469 /// [`PromptResponse`] to confirm it was recorded.
2470 /// Both clients and agents MUST use UUID format for message IDs.
2471 #[cfg(feature = "unstable_message_id")]
2472 #[must_use]
2473 pub fn message_id(mut self, message_id: impl IntoOption<String>) -> Self {
2474 self.message_id = message_id.into_option();
2475 self
2476 }
2477
2478 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2479 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2480 /// these keys.
2481 ///
2482 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2483 #[must_use]
2484 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2485 self.meta = meta.into_option();
2486 self
2487 }
2488}
2489
2490/// Response from processing a user prompt.
2491///
2492/// See protocol docs: [Check for Completion](https://agentclientprotocol.com/protocol/prompt-turn#4-check-for-completion)
2493#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2494#[schemars(extend("x-side" = "agent", "x-method" = SESSION_PROMPT_METHOD_NAME))]
2495#[serde(rename_all = "camelCase")]
2496#[non_exhaustive]
2497pub struct PromptResponse {
2498 /// **UNSTABLE**
2499 ///
2500 /// This capability is not part of the spec yet, and may be removed or changed at any point.
2501 ///
2502 /// The acknowledged user message ID.
2503 ///
2504 /// If the client provided a `messageId` in the [`PromptRequest`], the agent echoes it here
2505 /// to confirm it was recorded. If the client did not provide one, the agent MAY assign one
2506 /// and return it here. Absence of this field indicates the agent did not record a message ID.
2507 #[cfg(feature = "unstable_message_id")]
2508 #[serde(skip_serializing_if = "Option::is_none")]
2509 pub user_message_id: Option<String>,
2510 /// Indicates why the agent stopped processing the turn.
2511 pub stop_reason: StopReason,
2512 /// **UNSTABLE**
2513 ///
2514 /// This capability is not part of the spec yet, and may be removed or changed at any point.
2515 ///
2516 /// Token usage for this turn (optional).
2517 #[cfg(feature = "unstable_session_usage")]
2518 #[serde(skip_serializing_if = "Option::is_none")]
2519 pub usage: Option<Usage>,
2520 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2521 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2522 /// these keys.
2523 ///
2524 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2525 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2526 pub meta: Option<Meta>,
2527}
2528
2529impl PromptResponse {
2530 #[must_use]
2531 pub fn new(stop_reason: StopReason) -> Self {
2532 Self {
2533 #[cfg(feature = "unstable_message_id")]
2534 user_message_id: None,
2535 stop_reason,
2536 #[cfg(feature = "unstable_session_usage")]
2537 usage: None,
2538 meta: None,
2539 }
2540 }
2541
2542 /// **UNSTABLE**
2543 ///
2544 /// This capability is not part of the spec yet, and may be removed or changed at any point.
2545 ///
2546 /// The acknowledged user message ID.
2547 ///
2548 /// If the client provided a `messageId` in the [`PromptRequest`], the agent echoes it here
2549 /// to confirm it was recorded. If the client did not provide one, the agent MAY assign one
2550 /// and return it here. Absence of this field indicates the agent did not record a message ID.
2551 #[cfg(feature = "unstable_message_id")]
2552 #[must_use]
2553 pub fn user_message_id(mut self, user_message_id: impl IntoOption<String>) -> Self {
2554 self.user_message_id = user_message_id.into_option();
2555 self
2556 }
2557
2558 /// **UNSTABLE**
2559 ///
2560 /// This capability is not part of the spec yet, and may be removed or changed at any point.
2561 ///
2562 /// Token usage for this turn.
2563 #[cfg(feature = "unstable_session_usage")]
2564 #[must_use]
2565 pub fn usage(mut self, usage: impl IntoOption<Usage>) -> Self {
2566 self.usage = usage.into_option();
2567 self
2568 }
2569
2570 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2571 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2572 /// these keys.
2573 ///
2574 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2575 #[must_use]
2576 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2577 self.meta = meta.into_option();
2578 self
2579 }
2580}
2581
2582/// Reasons why an agent stops processing a prompt turn.
2583///
2584/// See protocol docs: [Stop Reasons](https://agentclientprotocol.com/protocol/prompt-turn#stop-reasons)
2585#[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
2586#[serde(rename_all = "snake_case")]
2587#[non_exhaustive]
2588pub enum StopReason {
2589 /// The turn ended successfully.
2590 EndTurn,
2591 /// The turn ended because the agent reached the maximum number of tokens.
2592 MaxTokens,
2593 /// The turn ended because the agent reached the maximum number of allowed
2594 /// agent requests between user turns.
2595 MaxTurnRequests,
2596 /// The turn ended because the agent refused to continue. The user prompt
2597 /// and everything that comes after it won't be included in the next
2598 /// prompt, so this should be reflected in the UI.
2599 Refusal,
2600 /// The turn was cancelled by the client via `session/cancel`.
2601 ///
2602 /// This stop reason MUST be returned when the client sends a `session/cancel`
2603 /// notification, even if the cancellation causes exceptions in underlying operations.
2604 /// Agents should catch these exceptions and return this semantically meaningful
2605 /// response to confirm successful cancellation.
2606 Cancelled,
2607}
2608
2609/// **UNSTABLE**
2610///
2611/// This capability is not part of the spec yet, and may be removed or changed at any point.
2612///
2613/// Token usage information for a prompt turn.
2614#[cfg(feature = "unstable_session_usage")]
2615#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2616#[serde(rename_all = "camelCase")]
2617#[non_exhaustive]
2618pub struct Usage {
2619 /// Sum of all token types across session.
2620 pub total_tokens: u64,
2621 /// Total input tokens across all turns.
2622 pub input_tokens: u64,
2623 /// Total output tokens across all turns.
2624 pub output_tokens: u64,
2625 /// Total thought/reasoning tokens
2626 #[serde(skip_serializing_if = "Option::is_none")]
2627 pub thought_tokens: Option<u64>,
2628 /// Total cache read tokens.
2629 #[serde(skip_serializing_if = "Option::is_none")]
2630 pub cached_read_tokens: Option<u64>,
2631 /// Total cache write tokens.
2632 #[serde(skip_serializing_if = "Option::is_none")]
2633 pub cached_write_tokens: Option<u64>,
2634}
2635
2636#[cfg(feature = "unstable_session_usage")]
2637impl Usage {
2638 #[must_use]
2639 pub fn new(total_tokens: u64, input_tokens: u64, output_tokens: u64) -> Self {
2640 Self {
2641 total_tokens,
2642 input_tokens,
2643 output_tokens,
2644 thought_tokens: None,
2645 cached_read_tokens: None,
2646 cached_write_tokens: None,
2647 }
2648 }
2649
2650 /// Total thought/reasoning tokens
2651 #[must_use]
2652 pub fn thought_tokens(mut self, thought_tokens: impl IntoOption<u64>) -> Self {
2653 self.thought_tokens = thought_tokens.into_option();
2654 self
2655 }
2656
2657 /// Total cache read tokens.
2658 #[must_use]
2659 pub fn cached_read_tokens(mut self, cached_read_tokens: impl IntoOption<u64>) -> Self {
2660 self.cached_read_tokens = cached_read_tokens.into_option();
2661 self
2662 }
2663
2664 /// Total cache write tokens.
2665 #[must_use]
2666 pub fn cached_write_tokens(mut self, cached_write_tokens: impl IntoOption<u64>) -> Self {
2667 self.cached_write_tokens = cached_write_tokens.into_option();
2668 self
2669 }
2670}
2671
2672// Model
2673
2674/// **UNSTABLE**
2675///
2676/// This capability is not part of the spec yet, and may be removed or changed at any point.
2677///
2678/// The set of models and the one currently active.
2679#[cfg(feature = "unstable_session_model")]
2680#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2681#[serde(rename_all = "camelCase")]
2682#[non_exhaustive]
2683pub struct SessionModelState {
2684 /// The current model the Agent is in.
2685 pub current_model_id: ModelId,
2686 /// The set of models that the Agent can use
2687 pub available_models: Vec<ModelInfo>,
2688 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2689 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2690 /// these keys.
2691 ///
2692 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2693 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2694 pub meta: Option<Meta>,
2695}
2696
2697#[cfg(feature = "unstable_session_model")]
2698impl SessionModelState {
2699 #[must_use]
2700 pub fn new(current_model_id: impl Into<ModelId>, available_models: Vec<ModelInfo>) -> Self {
2701 Self {
2702 current_model_id: current_model_id.into(),
2703 available_models,
2704 meta: None,
2705 }
2706 }
2707
2708 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2709 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2710 /// these keys.
2711 ///
2712 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2713 #[must_use]
2714 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2715 self.meta = meta.into_option();
2716 self
2717 }
2718}
2719
2720/// **UNSTABLE**
2721///
2722/// This capability is not part of the spec yet, and may be removed or changed at any point.
2723///
2724/// A unique identifier for a model.
2725#[cfg(feature = "unstable_session_model")]
2726#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, Display, From)]
2727#[serde(transparent)]
2728#[from(Arc<str>, String, &'static str)]
2729#[non_exhaustive]
2730pub struct ModelId(pub Arc<str>);
2731
2732#[cfg(feature = "unstable_session_model")]
2733impl ModelId {
2734 #[must_use]
2735 pub fn new(id: impl Into<Arc<str>>) -> Self {
2736 Self(id.into())
2737 }
2738}
2739
2740/// **UNSTABLE**
2741///
2742/// This capability is not part of the spec yet, and may be removed or changed at any point.
2743///
2744/// Information about a selectable model.
2745#[cfg(feature = "unstable_session_model")]
2746#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2747#[serde(rename_all = "camelCase")]
2748#[non_exhaustive]
2749pub struct ModelInfo {
2750 /// Unique identifier for the model.
2751 pub model_id: ModelId,
2752 /// Human-readable name of the model.
2753 pub name: String,
2754 /// Optional description of the model.
2755 #[serde(default, skip_serializing_if = "Option::is_none")]
2756 pub description: Option<String>,
2757 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2758 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2759 /// these keys.
2760 ///
2761 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2762 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2763 pub meta: Option<Meta>,
2764}
2765
2766#[cfg(feature = "unstable_session_model")]
2767impl ModelInfo {
2768 #[must_use]
2769 pub fn new(model_id: impl Into<ModelId>, name: impl Into<String>) -> Self {
2770 Self {
2771 model_id: model_id.into(),
2772 name: name.into(),
2773 description: None,
2774 meta: None,
2775 }
2776 }
2777
2778 /// Optional description of the model.
2779 #[must_use]
2780 pub fn description(mut self, description: impl IntoOption<String>) -> Self {
2781 self.description = description.into_option();
2782 self
2783 }
2784
2785 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2786 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2787 /// these keys.
2788 ///
2789 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2790 #[must_use]
2791 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2792 self.meta = meta.into_option();
2793 self
2794 }
2795}
2796
2797/// **UNSTABLE**
2798///
2799/// This capability is not part of the spec yet, and may be removed or changed at any point.
2800///
2801/// Request parameters for setting a session model.
2802#[cfg(feature = "unstable_session_model")]
2803#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2804#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODEL_METHOD_NAME))]
2805#[serde(rename_all = "camelCase")]
2806#[non_exhaustive]
2807pub struct SetSessionModelRequest {
2808 /// The ID of the session to set the model for.
2809 pub session_id: SessionId,
2810 /// The ID of the model to set.
2811 pub model_id: ModelId,
2812 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2813 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2814 /// these keys.
2815 ///
2816 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2817 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2818 pub meta: Option<Meta>,
2819}
2820
2821#[cfg(feature = "unstable_session_model")]
2822impl SetSessionModelRequest {
2823 #[must_use]
2824 pub fn new(session_id: impl Into<SessionId>, model_id: impl Into<ModelId>) -> Self {
2825 Self {
2826 session_id: session_id.into(),
2827 model_id: model_id.into(),
2828 meta: None,
2829 }
2830 }
2831
2832 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2833 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2834 /// these keys.
2835 ///
2836 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2837 #[must_use]
2838 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2839 self.meta = meta.into_option();
2840 self
2841 }
2842}
2843
2844/// **UNSTABLE**
2845///
2846/// This capability is not part of the spec yet, and may be removed or changed at any point.
2847///
2848/// Response to `session/set_model` method.
2849#[cfg(feature = "unstable_session_model")]
2850#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2851#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODEL_METHOD_NAME))]
2852#[serde(rename_all = "camelCase")]
2853#[non_exhaustive]
2854pub struct SetSessionModelResponse {
2855 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2856 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2857 /// these keys.
2858 ///
2859 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2860 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2861 pub meta: Option<Meta>,
2862}
2863
2864#[cfg(feature = "unstable_session_model")]
2865impl SetSessionModelResponse {
2866 #[must_use]
2867 pub fn new() -> Self {
2868 Self::default()
2869 }
2870
2871 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2872 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2873 /// these keys.
2874 ///
2875 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2876 #[must_use]
2877 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2878 self.meta = meta.into_option();
2879 self
2880 }
2881}
2882
2883// Capabilities
2884
2885/// Capabilities supported by the agent.
2886///
2887/// Advertised during initialization to inform the client about
2888/// available features and content types.
2889///
2890/// See protocol docs: [Agent Capabilities](https://agentclientprotocol.com/protocol/initialization#agent-capabilities)
2891#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2892#[serde(rename_all = "camelCase")]
2893#[non_exhaustive]
2894pub struct AgentCapabilities {
2895 /// Whether the agent supports `session/load`.
2896 #[serde(default)]
2897 pub load_session: bool,
2898 /// Prompt capabilities supported by the agent.
2899 #[serde(default)]
2900 pub prompt_capabilities: PromptCapabilities,
2901 /// MCP capabilities supported by the agent.
2902 #[serde(default)]
2903 pub mcp_capabilities: McpCapabilities,
2904 #[serde(default)]
2905 pub session_capabilities: SessionCapabilities,
2906 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2907 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2908 /// these keys.
2909 ///
2910 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2911 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2912 pub meta: Option<Meta>,
2913}
2914
2915impl AgentCapabilities {
2916 #[must_use]
2917 pub fn new() -> Self {
2918 Self::default()
2919 }
2920
2921 /// Whether the agent supports `session/load`.
2922 #[must_use]
2923 pub fn load_session(mut self, load_session: bool) -> Self {
2924 self.load_session = load_session;
2925 self
2926 }
2927
2928 /// Prompt capabilities supported by the agent.
2929 #[must_use]
2930 pub fn prompt_capabilities(mut self, prompt_capabilities: PromptCapabilities) -> Self {
2931 self.prompt_capabilities = prompt_capabilities;
2932 self
2933 }
2934
2935 /// MCP capabilities supported by the agent.
2936 #[must_use]
2937 pub fn mcp_capabilities(mut self, mcp_capabilities: McpCapabilities) -> Self {
2938 self.mcp_capabilities = mcp_capabilities;
2939 self
2940 }
2941
2942 /// Session capabilities supported by the agent.
2943 #[must_use]
2944 pub fn session_capabilities(mut self, session_capabilities: SessionCapabilities) -> Self {
2945 self.session_capabilities = session_capabilities;
2946 self
2947 }
2948
2949 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2950 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2951 /// these keys.
2952 ///
2953 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2954 #[must_use]
2955 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2956 self.meta = meta.into_option();
2957 self
2958 }
2959}
2960
2961/// Session capabilities supported by the agent.
2962///
2963/// As a baseline, all Agents **MUST** support `session/new`, `session/prompt`, `session/cancel`, and `session/update`.
2964///
2965/// Optionally, they **MAY** support other session methods and notifications by specifying additional capabilities.
2966///
2967/// Note: `session/load` is still handled by the top-level `load_session` capability. This will be unified in future versions of the protocol.
2968///
2969/// See protocol docs: [Session Capabilities](https://agentclientprotocol.com/protocol/initialization#session-capabilities)
2970#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2971#[non_exhaustive]
2972pub struct SessionCapabilities {
2973 /// **UNSTABLE**
2974 ///
2975 /// This capability is not part of the spec yet, and may be removed or changed at any point.
2976 ///
2977 /// Whether the agent supports `session/list`.
2978 #[cfg(feature = "unstable_session_list")]
2979 #[serde(skip_serializing_if = "Option::is_none")]
2980 pub list: Option<SessionListCapabilities>,
2981 /// **UNSTABLE**
2982 ///
2983 /// This capability is not part of the spec yet, and may be removed or changed at any point.
2984 ///
2985 /// Whether the agent supports `session/fork`.
2986 #[cfg(feature = "unstable_session_fork")]
2987 #[serde(skip_serializing_if = "Option::is_none")]
2988 pub fork: Option<SessionForkCapabilities>,
2989 /// **UNSTABLE**
2990 ///
2991 /// This capability is not part of the spec yet, and may be removed or changed at any point.
2992 ///
2993 /// Whether the agent supports `session/resume`.
2994 #[cfg(feature = "unstable_session_resume")]
2995 #[serde(skip_serializing_if = "Option::is_none")]
2996 pub resume: Option<SessionResumeCapabilities>,
2997 /// **UNSTABLE**
2998 ///
2999 /// This capability is not part of the spec yet, and may be removed or changed at any point.
3000 ///
3001 /// Whether the agent supports `session/stop`.
3002 #[cfg(feature = "unstable_session_stop")]
3003 #[serde(skip_serializing_if = "Option::is_none")]
3004 pub stop: Option<SessionStopCapabilities>,
3005 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
3006 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
3007 /// these keys.
3008 ///
3009 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
3010 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
3011 pub meta: Option<Meta>,
3012}
3013
3014impl SessionCapabilities {
3015 #[must_use]
3016 pub fn new() -> Self {
3017 Self::default()
3018 }
3019
3020 #[cfg(feature = "unstable_session_list")]
3021 /// Whether the agent supports `session/list`.
3022 #[must_use]
3023 pub fn list(mut self, list: impl IntoOption<SessionListCapabilities>) -> Self {
3024 self.list = list.into_option();
3025 self
3026 }
3027
3028 #[cfg(feature = "unstable_session_fork")]
3029 /// Whether the agent supports `session/fork`.
3030 #[must_use]
3031 pub fn fork(mut self, fork: impl IntoOption<SessionForkCapabilities>) -> Self {
3032 self.fork = fork.into_option();
3033 self
3034 }
3035
3036 #[cfg(feature = "unstable_session_resume")]
3037 /// Whether the agent supports `session/resume`.
3038 #[must_use]
3039 pub fn resume(mut self, resume: impl IntoOption<SessionResumeCapabilities>) -> Self {
3040 self.resume = resume.into_option();
3041 self
3042 }
3043
3044 #[cfg(feature = "unstable_session_stop")]
3045 /// Whether the agent supports `session/stop`.
3046 #[must_use]
3047 pub fn stop(mut self, stop: impl IntoOption<SessionStopCapabilities>) -> Self {
3048 self.stop = stop.into_option();
3049 self
3050 }
3051
3052 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
3053 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
3054 /// these keys.
3055 ///
3056 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
3057 #[must_use]
3058 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
3059 self.meta = meta.into_option();
3060 self
3061 }
3062}
3063
3064/// Capabilities for the `session/list` method.
3065///
3066/// By supplying `{}` it means that the agent supports listing of sessions.
3067///
3068/// Further capabilities can be added in the future for other means of filtering or searching the list.
3069#[cfg(feature = "unstable_session_list")]
3070#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
3071#[non_exhaustive]
3072pub struct SessionListCapabilities {
3073 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
3074 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
3075 /// these keys.
3076 ///
3077 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
3078 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
3079 pub meta: Option<Meta>,
3080}
3081
3082#[cfg(feature = "unstable_session_list")]
3083impl SessionListCapabilities {
3084 #[must_use]
3085 pub fn new() -> Self {
3086 Self::default()
3087 }
3088 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
3089 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
3090 /// these keys.
3091 ///
3092 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
3093 #[must_use]
3094 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
3095 self.meta = meta.into_option();
3096 self
3097 }
3098}
3099
3100/// **UNSTABLE**
3101///
3102/// This capability is not part of the spec yet, and may be removed or changed at any point.
3103///
3104/// Capabilities for the `session/fork` method.
3105///
3106/// By supplying `{}` it means that the agent supports forking of sessions.
3107#[cfg(feature = "unstable_session_fork")]
3108#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
3109#[non_exhaustive]
3110pub struct SessionForkCapabilities {
3111 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
3112 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
3113 /// these keys.
3114 ///
3115 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
3116 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
3117 pub meta: Option<Meta>,
3118}
3119
3120#[cfg(feature = "unstable_session_fork")]
3121impl SessionForkCapabilities {
3122 #[must_use]
3123 pub fn new() -> Self {
3124 Self::default()
3125 }
3126
3127 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
3128 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
3129 /// these keys.
3130 ///
3131 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
3132 #[must_use]
3133 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
3134 self.meta = meta.into_option();
3135 self
3136 }
3137}
3138
3139/// **UNSTABLE**
3140///
3141/// This capability is not part of the spec yet, and may be removed or changed at any point.
3142///
3143/// Capabilities for the `session/resume` method.
3144///
3145/// By supplying `{}` it means that the agent supports resuming of sessions.
3146#[cfg(feature = "unstable_session_resume")]
3147#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
3148#[non_exhaustive]
3149pub struct SessionResumeCapabilities {
3150 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
3151 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
3152 /// these keys.
3153 ///
3154 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
3155 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
3156 pub meta: Option<Meta>,
3157}
3158
3159#[cfg(feature = "unstable_session_resume")]
3160impl SessionResumeCapabilities {
3161 #[must_use]
3162 pub fn new() -> Self {
3163 Self::default()
3164 }
3165
3166 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
3167 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
3168 /// these keys.
3169 ///
3170 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
3171 #[must_use]
3172 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
3173 self.meta = meta.into_option();
3174 self
3175 }
3176}
3177
3178/// **UNSTABLE**
3179///
3180/// This capability is not part of the spec yet, and may be removed or changed at any point.
3181///
3182/// Capabilities for the `session/stop` method.
3183///
3184/// By supplying `{}` it means that the agent supports stopping of sessions.
3185#[cfg(feature = "unstable_session_stop")]
3186#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
3187#[non_exhaustive]
3188pub struct SessionStopCapabilities {
3189 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
3190 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
3191 /// these keys.
3192 ///
3193 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
3194 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
3195 pub meta: Option<Meta>,
3196}
3197
3198#[cfg(feature = "unstable_session_stop")]
3199impl SessionStopCapabilities {
3200 #[must_use]
3201 pub fn new() -> Self {
3202 Self::default()
3203 }
3204
3205 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
3206 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
3207 /// these keys.
3208 ///
3209 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
3210 #[must_use]
3211 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
3212 self.meta = meta.into_option();
3213 self
3214 }
3215}
3216
3217/// Prompt capabilities supported by the agent in `session/prompt` requests.
3218///
3219/// Baseline agent functionality requires support for [`ContentBlock::Text`]
3220/// and [`ContentBlock::ResourceLink`] in prompt requests.
3221///
3222/// Other variants must be explicitly opted in to.
3223/// Capabilities for different types of content in prompt requests.
3224///
3225/// Indicates which content types beyond the baseline (text and resource links)
3226/// the agent can process.
3227///
3228/// See protocol docs: [Prompt Capabilities](https://agentclientprotocol.com/protocol/initialization#prompt-capabilities)
3229#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
3230#[serde(rename_all = "camelCase")]
3231#[non_exhaustive]
3232pub struct PromptCapabilities {
3233 /// Agent supports [`ContentBlock::Image`].
3234 #[serde(default)]
3235 pub image: bool,
3236 /// Agent supports [`ContentBlock::Audio`].
3237 #[serde(default)]
3238 pub audio: bool,
3239 /// Agent supports embedded context in `session/prompt` requests.
3240 ///
3241 /// When enabled, the Client is allowed to include [`ContentBlock::Resource`]
3242 /// in prompt requests for pieces of context that are referenced in the message.
3243 #[serde(default)]
3244 pub embedded_context: bool,
3245 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
3246 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
3247 /// these keys.
3248 ///
3249 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
3250 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
3251 pub meta: Option<Meta>,
3252}
3253
3254impl PromptCapabilities {
3255 #[must_use]
3256 pub fn new() -> Self {
3257 Self::default()
3258 }
3259
3260 /// Agent supports [`ContentBlock::Image`].
3261 #[must_use]
3262 pub fn image(mut self, image: bool) -> Self {
3263 self.image = image;
3264 self
3265 }
3266
3267 /// Agent supports [`ContentBlock::Audio`].
3268 #[must_use]
3269 pub fn audio(mut self, audio: bool) -> Self {
3270 self.audio = audio;
3271 self
3272 }
3273
3274 /// Agent supports embedded context in `session/prompt` requests.
3275 ///
3276 /// When enabled, the Client is allowed to include [`ContentBlock::Resource`]
3277 /// in prompt requests for pieces of context that are referenced in the message.
3278 #[must_use]
3279 pub fn embedded_context(mut self, embedded_context: bool) -> Self {
3280 self.embedded_context = embedded_context;
3281 self
3282 }
3283
3284 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
3285 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
3286 /// these keys.
3287 ///
3288 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
3289 #[must_use]
3290 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
3291 self.meta = meta.into_option();
3292 self
3293 }
3294}
3295
3296/// MCP capabilities supported by the agent
3297#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
3298#[serde(rename_all = "camelCase")]
3299#[non_exhaustive]
3300pub struct McpCapabilities {
3301 /// Agent supports [`McpServer::Http`].
3302 #[serde(default)]
3303 pub http: bool,
3304 /// Agent supports [`McpServer::Sse`].
3305 #[serde(default)]
3306 pub sse: bool,
3307 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
3308 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
3309 /// these keys.
3310 ///
3311 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
3312 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
3313 pub meta: Option<Meta>,
3314}
3315
3316impl McpCapabilities {
3317 #[must_use]
3318 pub fn new() -> Self {
3319 Self::default()
3320 }
3321
3322 /// Agent supports [`McpServer::Http`].
3323 #[must_use]
3324 pub fn http(mut self, http: bool) -> Self {
3325 self.http = http;
3326 self
3327 }
3328
3329 /// Agent supports [`McpServer::Sse`].
3330 #[must_use]
3331 pub fn sse(mut self, sse: bool) -> Self {
3332 self.sse = sse;
3333 self
3334 }
3335
3336 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
3337 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
3338 /// these keys.
3339 ///
3340 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
3341 #[must_use]
3342 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
3343 self.meta = meta.into_option();
3344 self
3345 }
3346}
3347
3348// Method schema
3349
3350/// Names of all methods that agents handle.
3351///
3352/// Provides a centralized definition of method names used in the protocol.
3353#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
3354#[non_exhaustive]
3355pub struct AgentMethodNames {
3356 /// Method for initializing the connection.
3357 pub initialize: &'static str,
3358 /// Method for authenticating with the agent.
3359 pub authenticate: &'static str,
3360 /// Method for creating a new session.
3361 pub session_new: &'static str,
3362 /// Method for loading an existing session.
3363 pub session_load: &'static str,
3364 /// Method for setting the mode for a session.
3365 pub session_set_mode: &'static str,
3366 /// Method for setting a configuration option for a session.
3367 pub session_set_config_option: &'static str,
3368 /// Method for sending a prompt to the agent.
3369 pub session_prompt: &'static str,
3370 /// Notification for cancelling operations.
3371 pub session_cancel: &'static str,
3372 /// Method for selecting a model for a given session.
3373 #[cfg(feature = "unstable_session_model")]
3374 pub session_set_model: &'static str,
3375 /// Method for listing existing sessions.
3376 #[cfg(feature = "unstable_session_list")]
3377 pub session_list: &'static str,
3378 /// Method for forking an existing session.
3379 #[cfg(feature = "unstable_session_fork")]
3380 pub session_fork: &'static str,
3381 /// Method for resuming an existing session.
3382 #[cfg(feature = "unstable_session_resume")]
3383 pub session_resume: &'static str,
3384 /// Method for stopping an active session.
3385 #[cfg(feature = "unstable_session_stop")]
3386 pub session_stop: &'static str,
3387}
3388
3389/// Constant containing all agent method names.
3390pub const AGENT_METHOD_NAMES: AgentMethodNames = AgentMethodNames {
3391 initialize: INITIALIZE_METHOD_NAME,
3392 authenticate: AUTHENTICATE_METHOD_NAME,
3393 session_new: SESSION_NEW_METHOD_NAME,
3394 session_load: SESSION_LOAD_METHOD_NAME,
3395 session_set_mode: SESSION_SET_MODE_METHOD_NAME,
3396 session_set_config_option: SESSION_SET_CONFIG_OPTION_METHOD_NAME,
3397 session_prompt: SESSION_PROMPT_METHOD_NAME,
3398 session_cancel: SESSION_CANCEL_METHOD_NAME,
3399 #[cfg(feature = "unstable_session_model")]
3400 session_set_model: SESSION_SET_MODEL_METHOD_NAME,
3401 #[cfg(feature = "unstable_session_list")]
3402 session_list: SESSION_LIST_METHOD_NAME,
3403 #[cfg(feature = "unstable_session_fork")]
3404 session_fork: SESSION_FORK_METHOD_NAME,
3405 #[cfg(feature = "unstable_session_resume")]
3406 session_resume: SESSION_RESUME_METHOD_NAME,
3407 #[cfg(feature = "unstable_session_stop")]
3408 session_stop: SESSION_STOP_METHOD_NAME,
3409};
3410
3411/// Method name for the initialize request.
3412pub(crate) const INITIALIZE_METHOD_NAME: &str = "initialize";
3413/// Method name for the authenticate request.
3414pub(crate) const AUTHENTICATE_METHOD_NAME: &str = "authenticate";
3415/// Method name for creating a new session.
3416pub(crate) const SESSION_NEW_METHOD_NAME: &str = "session/new";
3417/// Method name for loading an existing session.
3418pub(crate) const SESSION_LOAD_METHOD_NAME: &str = "session/load";
3419/// Method name for setting the mode for a session.
3420pub(crate) const SESSION_SET_MODE_METHOD_NAME: &str = "session/set_mode";
3421/// Method name for setting a configuration option for a session.
3422pub(crate) const SESSION_SET_CONFIG_OPTION_METHOD_NAME: &str = "session/set_config_option";
3423/// Method name for sending a prompt.
3424pub(crate) const SESSION_PROMPT_METHOD_NAME: &str = "session/prompt";
3425/// Method name for the cancel notification.
3426pub(crate) const SESSION_CANCEL_METHOD_NAME: &str = "session/cancel";
3427/// Method name for selecting a model for a given session.
3428#[cfg(feature = "unstable_session_model")]
3429pub(crate) const SESSION_SET_MODEL_METHOD_NAME: &str = "session/set_model";
3430/// Method name for listing existing sessions.
3431#[cfg(feature = "unstable_session_list")]
3432pub(crate) const SESSION_LIST_METHOD_NAME: &str = "session/list";
3433/// Method name for forking an existing session.
3434#[cfg(feature = "unstable_session_fork")]
3435pub(crate) const SESSION_FORK_METHOD_NAME: &str = "session/fork";
3436/// Method name for resuming an existing session.
3437#[cfg(feature = "unstable_session_resume")]
3438pub(crate) const SESSION_RESUME_METHOD_NAME: &str = "session/resume";
3439/// Method name for stopping an active session.
3440#[cfg(feature = "unstable_session_stop")]
3441pub(crate) const SESSION_STOP_METHOD_NAME: &str = "session/stop";
3442
3443/// All possible requests that a client can send to an agent.
3444///
3445/// This enum is used internally for routing RPC requests. You typically won't need
3446/// to use this directly - instead, use the methods on the [`Agent`] trait.
3447///
3448/// This enum encompasses all method calls from client to agent.
3449#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
3450#[serde(untagged)]
3451#[schemars(inline)]
3452#[non_exhaustive]
3453pub enum ClientRequest {
3454 /// Establishes the connection with a client and negotiates protocol capabilities.
3455 ///
3456 /// This method is called once at the beginning of the connection to:
3457 /// - Negotiate the protocol version to use
3458 /// - Exchange capability information between client and agent
3459 /// - Determine available authentication methods
3460 ///
3461 /// The agent should respond with its supported protocol version and capabilities.
3462 ///
3463 /// See protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)
3464 InitializeRequest(InitializeRequest),
3465 /// Authenticates the client using the specified authentication method.
3466 ///
3467 /// Called when the agent requires authentication before allowing session creation.
3468 /// The client provides the authentication method ID that was advertised during initialization.
3469 ///
3470 /// After successful authentication, the client can proceed to create sessions with
3471 /// `new_session` without receiving an `auth_required` error.
3472 ///
3473 /// See protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)
3474 AuthenticateRequest(AuthenticateRequest),
3475 /// Creates a new conversation session with the agent.
3476 ///
3477 /// Sessions represent independent conversation contexts with their own history and state.
3478 ///
3479 /// The agent should:
3480 /// - Create a new session context
3481 /// - Connect to any specified MCP servers
3482 /// - Return a unique session ID for future requests
3483 ///
3484 /// May return an `auth_required` error if the agent requires authentication.
3485 ///
3486 /// See protocol docs: [Session Setup](https://agentclientprotocol.com/protocol/session-setup)
3487 NewSessionRequest(NewSessionRequest),
3488 /// Loads an existing session to resume a previous conversation.
3489 ///
3490 /// This method is only available if the agent advertises the `loadSession` capability.
3491 ///
3492 /// The agent should:
3493 /// - Restore the session context and conversation history
3494 /// - Connect to the specified MCP servers
3495 /// - Stream the entire conversation history back to the client via notifications
3496 ///
3497 /// See protocol docs: [Loading Sessions](https://agentclientprotocol.com/protocol/session-setup#loading-sessions)
3498 LoadSessionRequest(LoadSessionRequest),
3499 #[cfg(feature = "unstable_session_list")]
3500 /// **UNSTABLE**
3501 ///
3502 /// This capability is not part of the spec yet, and may be removed or changed at any point.
3503 ///
3504 /// Lists existing sessions known to the agent.
3505 ///
3506 /// This method is only available if the agent advertises the `listSessions` capability.
3507 ///
3508 /// The agent should return metadata about sessions with optional filtering and pagination support.
3509 ListSessionsRequest(ListSessionsRequest),
3510 #[cfg(feature = "unstable_session_fork")]
3511 /// **UNSTABLE**
3512 ///
3513 /// This capability is not part of the spec yet, and may be removed or changed at any point.
3514 ///
3515 /// Forks an existing session to create a new independent session.
3516 ///
3517 /// This method is only available if the agent advertises the `session.fork` capability.
3518 ///
3519 /// The agent should create a new session with the same conversation context as the
3520 /// original, allowing operations like generating summaries without affecting the
3521 /// original session's history.
3522 ForkSessionRequest(ForkSessionRequest),
3523 #[cfg(feature = "unstable_session_resume")]
3524 /// **UNSTABLE**
3525 ///
3526 /// This capability is not part of the spec yet, and may be removed or changed at any point.
3527 ///
3528 /// Resumes an existing session without returning previous messages.
3529 ///
3530 /// This method is only available if the agent advertises the `session.resume` capability.
3531 ///
3532 /// The agent should resume the session context, allowing the conversation to continue
3533 /// without replaying the message history (unlike `session/load`).
3534 ResumeSessionRequest(ResumeSessionRequest),
3535 #[cfg(feature = "unstable_session_stop")]
3536 /// **UNSTABLE**
3537 ///
3538 /// This capability is not part of the spec yet, and may be removed or changed at any point.
3539 ///
3540 /// Stops an active session and frees up any resources associated with it.
3541 ///
3542 /// This method is only available if the agent advertises the `session.stop` capability.
3543 ///
3544 /// The agent must cancel any ongoing work (as if `session/cancel` was called)
3545 /// and then free up any resources associated with the session.
3546 StopSessionRequest(StopSessionRequest),
3547 /// Sets the current mode for a session.
3548 ///
3549 /// Allows switching between different agent modes (e.g., "ask", "architect", "code")
3550 /// that affect system prompts, tool availability, and permission behaviors.
3551 ///
3552 /// The mode must be one of the modes advertised in `availableModes` during session
3553 /// creation or loading. Agents may also change modes autonomously and notify the
3554 /// client via `current_mode_update` notifications.
3555 ///
3556 /// This method can be called at any time during a session, whether the Agent is
3557 /// idle or actively generating a response.
3558 ///
3559 /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
3560 SetSessionModeRequest(SetSessionModeRequest),
3561 /// Sets the current value for a session configuration option.
3562 SetSessionConfigOptionRequest(SetSessionConfigOptionRequest),
3563 /// Processes a user prompt within a session.
3564 ///
3565 /// This method handles the whole lifecycle of a prompt:
3566 /// - Receives user messages with optional context (files, images, etc.)
3567 /// - Processes the prompt using language models
3568 /// - Reports language model content and tool calls to the Clients
3569 /// - Requests permission to run tools
3570 /// - Executes any requested tool calls
3571 /// - Returns when the turn is complete with a stop reason
3572 ///
3573 /// See protocol docs: [Prompt Turn](https://agentclientprotocol.com/protocol/prompt-turn)
3574 PromptRequest(PromptRequest),
3575 #[cfg(feature = "unstable_session_model")]
3576 /// **UNSTABLE**
3577 ///
3578 /// This capability is not part of the spec yet, and may be removed or changed at any point.
3579 ///
3580 /// Select a model for a given session.
3581 SetSessionModelRequest(SetSessionModelRequest),
3582 /// Handles extension method requests from the client.
3583 ///
3584 /// Extension methods provide a way to add custom functionality while maintaining
3585 /// protocol compatibility.
3586 ///
3587 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
3588 ExtMethodRequest(ExtRequest),
3589}
3590
3591impl ClientRequest {
3592 /// Returns the corresponding method name of the request.
3593 #[must_use]
3594 pub fn method(&self) -> &str {
3595 match self {
3596 Self::InitializeRequest(_) => AGENT_METHOD_NAMES.initialize,
3597 Self::AuthenticateRequest(_) => AGENT_METHOD_NAMES.authenticate,
3598 Self::NewSessionRequest(_) => AGENT_METHOD_NAMES.session_new,
3599 Self::LoadSessionRequest(_) => AGENT_METHOD_NAMES.session_load,
3600 #[cfg(feature = "unstable_session_list")]
3601 Self::ListSessionsRequest(_) => AGENT_METHOD_NAMES.session_list,
3602 #[cfg(feature = "unstable_session_fork")]
3603 Self::ForkSessionRequest(_) => AGENT_METHOD_NAMES.session_fork,
3604 #[cfg(feature = "unstable_session_resume")]
3605 Self::ResumeSessionRequest(_) => AGENT_METHOD_NAMES.session_resume,
3606 #[cfg(feature = "unstable_session_stop")]
3607 Self::StopSessionRequest(_) => AGENT_METHOD_NAMES.session_stop,
3608 Self::SetSessionModeRequest(_) => AGENT_METHOD_NAMES.session_set_mode,
3609 Self::SetSessionConfigOptionRequest(_) => AGENT_METHOD_NAMES.session_set_config_option,
3610 Self::PromptRequest(_) => AGENT_METHOD_NAMES.session_prompt,
3611 #[cfg(feature = "unstable_session_model")]
3612 Self::SetSessionModelRequest(_) => AGENT_METHOD_NAMES.session_set_model,
3613 Self::ExtMethodRequest(ext_request) => &ext_request.method,
3614 }
3615 }
3616}
3617
3618/// All possible responses that an agent can send to a client.
3619///
3620/// This enum is used internally for routing RPC responses. You typically won't need
3621/// to use this directly - the responses are handled automatically by the connection.
3622///
3623/// These are responses to the corresponding `ClientRequest` variants.
3624#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
3625#[serde(untagged)]
3626#[schemars(inline)]
3627#[non_exhaustive]
3628#[allow(clippy::large_enum_variant)]
3629pub enum AgentResponse {
3630 InitializeResponse(InitializeResponse),
3631 AuthenticateResponse(#[serde(default)] AuthenticateResponse),
3632 NewSessionResponse(NewSessionResponse),
3633 LoadSessionResponse(#[serde(default)] LoadSessionResponse),
3634 #[cfg(feature = "unstable_session_list")]
3635 ListSessionsResponse(ListSessionsResponse),
3636 #[cfg(feature = "unstable_session_fork")]
3637 ForkSessionResponse(ForkSessionResponse),
3638 #[cfg(feature = "unstable_session_resume")]
3639 ResumeSessionResponse(#[serde(default)] ResumeSessionResponse),
3640 #[cfg(feature = "unstable_session_stop")]
3641 StopSessionResponse(#[serde(default)] StopSessionResponse),
3642 SetSessionModeResponse(#[serde(default)] SetSessionModeResponse),
3643 SetSessionConfigOptionResponse(SetSessionConfigOptionResponse),
3644 PromptResponse(PromptResponse),
3645 #[cfg(feature = "unstable_session_model")]
3646 SetSessionModelResponse(#[serde(default)] SetSessionModelResponse),
3647 ExtMethodResponse(ExtResponse),
3648}
3649
3650/// All possible notifications that a client can send to an agent.
3651///
3652/// This enum is used internally for routing RPC notifications. You typically won't need
3653/// to use this directly - use the notification methods on the [`Agent`] trait instead.
3654///
3655/// Notifications do not expect a response.
3656#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
3657#[serde(untagged)]
3658#[schemars(inline)]
3659#[non_exhaustive]
3660pub enum ClientNotification {
3661 /// Cancels ongoing operations for a session.
3662 ///
3663 /// This is a notification sent by the client to cancel an ongoing prompt turn.
3664 ///
3665 /// Upon receiving this notification, the Agent SHOULD:
3666 /// - Stop all language model requests as soon as possible
3667 /// - Abort all tool call invocations in progress
3668 /// - Send any pending `session/update` notifications
3669 /// - Respond to the original `session/prompt` request with `StopReason::Cancelled`
3670 ///
3671 /// See protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)
3672 CancelNotification(CancelNotification),
3673 /// Handles extension notifications from the client.
3674 ///
3675 /// Extension notifications provide a way to send one-way messages for custom functionality
3676 /// while maintaining protocol compatibility.
3677 ///
3678 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
3679 ExtNotification(ExtNotification),
3680}
3681
3682impl ClientNotification {
3683 /// Returns the corresponding method name of the notification.
3684 #[must_use]
3685 pub fn method(&self) -> &str {
3686 match self {
3687 Self::CancelNotification(_) => AGENT_METHOD_NAMES.session_cancel,
3688 Self::ExtNotification(ext_notification) => &ext_notification.method,
3689 }
3690 }
3691}
3692
3693/// Notification to cancel ongoing operations for a session.
3694///
3695/// See protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)
3696#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
3697#[schemars(extend("x-side" = "agent", "x-method" = SESSION_CANCEL_METHOD_NAME))]
3698#[serde(rename_all = "camelCase")]
3699#[non_exhaustive]
3700pub struct CancelNotification {
3701 /// The ID of the session to cancel operations for.
3702 pub session_id: SessionId,
3703 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
3704 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
3705 /// these keys.
3706 ///
3707 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
3708 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
3709 pub meta: Option<Meta>,
3710}
3711
3712impl CancelNotification {
3713 #[must_use]
3714 pub fn new(session_id: impl Into<SessionId>) -> Self {
3715 Self {
3716 session_id: session_id.into(),
3717 meta: None,
3718 }
3719 }
3720
3721 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
3722 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
3723 /// these keys.
3724 ///
3725 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
3726 #[must_use]
3727 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
3728 self.meta = meta.into_option();
3729 self
3730 }
3731}
3732
3733#[cfg(test)]
3734mod test_serialization {
3735 use super::*;
3736 use serde_json::json;
3737
3738 #[test]
3739 fn test_mcp_server_stdio_serialization() {
3740 let server = McpServer::Stdio(
3741 McpServerStdio::new("test-server", "/usr/bin/server")
3742 .args(vec!["--port".to_string(), "3000".to_string()])
3743 .env(vec![EnvVariable::new("API_KEY", "secret123")]),
3744 );
3745
3746 let json = serde_json::to_value(&server).unwrap();
3747 assert_eq!(
3748 json,
3749 json!({
3750 "name": "test-server",
3751 "command": "/usr/bin/server",
3752 "args": ["--port", "3000"],
3753 "env": [
3754 {
3755 "name": "API_KEY",
3756 "value": "secret123"
3757 }
3758 ]
3759 })
3760 );
3761
3762 let deserialized: McpServer = serde_json::from_value(json).unwrap();
3763 match deserialized {
3764 McpServer::Stdio(McpServerStdio {
3765 name,
3766 command,
3767 args,
3768 env,
3769 meta: _,
3770 }) => {
3771 assert_eq!(name, "test-server");
3772 assert_eq!(command, PathBuf::from("/usr/bin/server"));
3773 assert_eq!(args, vec!["--port", "3000"]);
3774 assert_eq!(env.len(), 1);
3775 assert_eq!(env[0].name, "API_KEY");
3776 assert_eq!(env[0].value, "secret123");
3777 }
3778 _ => panic!("Expected Stdio variant"),
3779 }
3780 }
3781
3782 #[test]
3783 fn test_mcp_server_http_serialization() {
3784 let server = McpServer::Http(
3785 McpServerHttp::new("http-server", "https://api.example.com").headers(vec![
3786 HttpHeader::new("Authorization", "Bearer token123"),
3787 HttpHeader::new("Content-Type", "application/json"),
3788 ]),
3789 );
3790
3791 let json = serde_json::to_value(&server).unwrap();
3792 assert_eq!(
3793 json,
3794 json!({
3795 "type": "http",
3796 "name": "http-server",
3797 "url": "https://api.example.com",
3798 "headers": [
3799 {
3800 "name": "Authorization",
3801 "value": "Bearer token123"
3802 },
3803 {
3804 "name": "Content-Type",
3805 "value": "application/json"
3806 }
3807 ]
3808 })
3809 );
3810
3811 let deserialized: McpServer = serde_json::from_value(json).unwrap();
3812 match deserialized {
3813 McpServer::Http(McpServerHttp {
3814 name,
3815 url,
3816 headers,
3817 meta: _,
3818 }) => {
3819 assert_eq!(name, "http-server");
3820 assert_eq!(url, "https://api.example.com");
3821 assert_eq!(headers.len(), 2);
3822 assert_eq!(headers[0].name, "Authorization");
3823 assert_eq!(headers[0].value, "Bearer token123");
3824 assert_eq!(headers[1].name, "Content-Type");
3825 assert_eq!(headers[1].value, "application/json");
3826 }
3827 _ => panic!("Expected Http variant"),
3828 }
3829 }
3830
3831 #[test]
3832 fn test_mcp_server_sse_serialization() {
3833 let server = McpServer::Sse(
3834 McpServerSse::new("sse-server", "https://sse.example.com/events")
3835 .headers(vec![HttpHeader::new("X-API-Key", "apikey456")]),
3836 );
3837
3838 let json = serde_json::to_value(&server).unwrap();
3839 assert_eq!(
3840 json,
3841 json!({
3842 "type": "sse",
3843 "name": "sse-server",
3844 "url": "https://sse.example.com/events",
3845 "headers": [
3846 {
3847 "name": "X-API-Key",
3848 "value": "apikey456"
3849 }
3850 ]
3851 })
3852 );
3853
3854 let deserialized: McpServer = serde_json::from_value(json).unwrap();
3855 match deserialized {
3856 McpServer::Sse(McpServerSse {
3857 name,
3858 url,
3859 headers,
3860 meta: _,
3861 }) => {
3862 assert_eq!(name, "sse-server");
3863 assert_eq!(url, "https://sse.example.com/events");
3864 assert_eq!(headers.len(), 1);
3865 assert_eq!(headers[0].name, "X-API-Key");
3866 assert_eq!(headers[0].value, "apikey456");
3867 }
3868 _ => panic!("Expected Sse variant"),
3869 }
3870 }
3871
3872 #[test]
3873 fn test_session_config_option_category_known_variants() {
3874 // Test serialization of known variants
3875 assert_eq!(
3876 serde_json::to_value(&SessionConfigOptionCategory::Mode).unwrap(),
3877 json!("mode")
3878 );
3879 assert_eq!(
3880 serde_json::to_value(&SessionConfigOptionCategory::Model).unwrap(),
3881 json!("model")
3882 );
3883 assert_eq!(
3884 serde_json::to_value(&SessionConfigOptionCategory::ThoughtLevel).unwrap(),
3885 json!("thought_level")
3886 );
3887
3888 // Test deserialization of known variants
3889 assert_eq!(
3890 serde_json::from_str::<SessionConfigOptionCategory>("\"mode\"").unwrap(),
3891 SessionConfigOptionCategory::Mode
3892 );
3893 assert_eq!(
3894 serde_json::from_str::<SessionConfigOptionCategory>("\"model\"").unwrap(),
3895 SessionConfigOptionCategory::Model
3896 );
3897 assert_eq!(
3898 serde_json::from_str::<SessionConfigOptionCategory>("\"thought_level\"").unwrap(),
3899 SessionConfigOptionCategory::ThoughtLevel
3900 );
3901 }
3902
3903 #[test]
3904 fn test_session_config_option_category_unknown_variants() {
3905 // Test that unknown strings are captured in Other variant
3906 let unknown: SessionConfigOptionCategory =
3907 serde_json::from_str("\"some_future_category\"").unwrap();
3908 assert_eq!(
3909 unknown,
3910 SessionConfigOptionCategory::Other("some_future_category".to_string())
3911 );
3912
3913 // Test round-trip of unknown category
3914 let json = serde_json::to_value(&unknown).unwrap();
3915 assert_eq!(json, json!("some_future_category"));
3916 }
3917
3918 #[test]
3919 fn test_session_config_option_category_custom_categories() {
3920 // Category names beginning with `_` are free for custom use
3921 let custom: SessionConfigOptionCategory =
3922 serde_json::from_str("\"_my_custom_category\"").unwrap();
3923 assert_eq!(
3924 custom,
3925 SessionConfigOptionCategory::Other("_my_custom_category".to_string())
3926 );
3927
3928 // Test round-trip preserves the custom category name
3929 let json = serde_json::to_value(&custom).unwrap();
3930 assert_eq!(json, json!("_my_custom_category"));
3931
3932 // Deserialize back and verify
3933 let deserialized: SessionConfigOptionCategory = serde_json::from_value(json).unwrap();
3934 assert_eq!(
3935 deserialized,
3936 SessionConfigOptionCategory::Other("_my_custom_category".to_string()),
3937 );
3938 }
3939
3940 #[test]
3941 fn test_auth_method_agent_serialization() {
3942 let method = AuthMethod::Agent(AuthMethodAgent::new("default-auth", "Default Auth"));
3943
3944 let json = serde_json::to_value(&method).unwrap();
3945 assert_eq!(
3946 json,
3947 json!({
3948 "id": "default-auth",
3949 "name": "Default Auth"
3950 })
3951 );
3952 // description should be omitted when None
3953 assert!(!json.as_object().unwrap().contains_key("description"));
3954 // Agent variant should not emit a `type` field (backward compat)
3955 assert!(!json.as_object().unwrap().contains_key("type"));
3956
3957 let deserialized: AuthMethod = serde_json::from_value(json).unwrap();
3958 match deserialized {
3959 AuthMethod::Agent(AuthMethodAgent { id, name, .. }) => {
3960 assert_eq!(id.0.as_ref(), "default-auth");
3961 assert_eq!(name, "Default Auth");
3962 }
3963 #[cfg(feature = "unstable_auth_methods")]
3964 _ => panic!("Expected Agent variant"),
3965 }
3966 }
3967
3968 #[test]
3969 fn test_auth_method_explicit_agent_deserialization() {
3970 // An explicit `"type": "agent"` should also deserialize to Agent
3971 let json = json!({
3972 "id": "agent-auth",
3973 "name": "Agent Auth",
3974 "type": "agent"
3975 });
3976
3977 let deserialized: AuthMethod = serde_json::from_value(json).unwrap();
3978 assert!(matches!(deserialized, AuthMethod::Agent(_)));
3979 }
3980
3981 #[cfg(feature = "unstable_auth_methods")]
3982 #[test]
3983 fn test_auth_method_env_var_serialization() {
3984 let method = AuthMethod::EnvVar(AuthMethodEnvVar::new(
3985 "api-key",
3986 "API Key",
3987 vec![AuthEnvVar::new("API_KEY")],
3988 ));
3989
3990 let json = serde_json::to_value(&method).unwrap();
3991 assert_eq!(
3992 json,
3993 json!({
3994 "id": "api-key",
3995 "name": "API Key",
3996 "type": "env_var",
3997 "vars": [{"name": "API_KEY"}]
3998 })
3999 );
4000 // secret defaults to true and should be omitted; optional defaults to false and should be omitted
4001 assert!(!json["vars"][0].as_object().unwrap().contains_key("secret"));
4002 assert!(
4003 !json["vars"][0]
4004 .as_object()
4005 .unwrap()
4006 .contains_key("optional")
4007 );
4008
4009 let deserialized: AuthMethod = serde_json::from_value(json).unwrap();
4010 match deserialized {
4011 AuthMethod::EnvVar(AuthMethodEnvVar {
4012 id,
4013 name: method_name,
4014 vars,
4015 link,
4016 ..
4017 }) => {
4018 assert_eq!(id.0.as_ref(), "api-key");
4019 assert_eq!(method_name, "API Key");
4020 assert_eq!(vars.len(), 1);
4021 assert_eq!(vars[0].name, "API_KEY");
4022 assert!(vars[0].secret);
4023 assert!(!vars[0].optional);
4024 assert!(link.is_none());
4025 }
4026 _ => panic!("Expected EnvVar variant"),
4027 }
4028 }
4029
4030 #[cfg(feature = "unstable_auth_methods")]
4031 #[test]
4032 fn test_auth_method_env_var_with_link_serialization() {
4033 let method = AuthMethod::EnvVar(
4034 AuthMethodEnvVar::new("api-key", "API Key", vec![AuthEnvVar::new("API_KEY")])
4035 .link("https://example.com/keys"),
4036 );
4037
4038 let json = serde_json::to_value(&method).unwrap();
4039 assert_eq!(
4040 json,
4041 json!({
4042 "id": "api-key",
4043 "name": "API Key",
4044 "type": "env_var",
4045 "vars": [{"name": "API_KEY"}],
4046 "link": "https://example.com/keys"
4047 })
4048 );
4049
4050 let deserialized: AuthMethod = serde_json::from_value(json).unwrap();
4051 match deserialized {
4052 AuthMethod::EnvVar(AuthMethodEnvVar { link, .. }) => {
4053 assert_eq!(link.as_deref(), Some("https://example.com/keys"));
4054 }
4055 _ => panic!("Expected EnvVar variant"),
4056 }
4057 }
4058
4059 #[cfg(feature = "unstable_auth_methods")]
4060 #[test]
4061 fn test_auth_method_env_var_multiple_vars() {
4062 let method = AuthMethod::EnvVar(AuthMethodEnvVar::new(
4063 "azure-openai",
4064 "Azure OpenAI",
4065 vec![
4066 AuthEnvVar::new("AZURE_OPENAI_API_KEY").label("API Key"),
4067 AuthEnvVar::new("AZURE_OPENAI_ENDPOINT")
4068 .label("Endpoint URL")
4069 .secret(false),
4070 AuthEnvVar::new("AZURE_OPENAI_API_VERSION")
4071 .label("API Version")
4072 .secret(false)
4073 .optional(true),
4074 ],
4075 ));
4076
4077 let json = serde_json::to_value(&method).unwrap();
4078 assert_eq!(
4079 json,
4080 json!({
4081 "id": "azure-openai",
4082 "name": "Azure OpenAI",
4083 "type": "env_var",
4084 "vars": [
4085 {"name": "AZURE_OPENAI_API_KEY", "label": "API Key"},
4086 {"name": "AZURE_OPENAI_ENDPOINT", "label": "Endpoint URL", "secret": false},
4087 {"name": "AZURE_OPENAI_API_VERSION", "label": "API Version", "secret": false, "optional": true}
4088 ]
4089 })
4090 );
4091
4092 let deserialized: AuthMethod = serde_json::from_value(json).unwrap();
4093 match deserialized {
4094 AuthMethod::EnvVar(AuthMethodEnvVar { vars, .. }) => {
4095 assert_eq!(vars.len(), 3);
4096 // First var: secret (default true), not optional (default false)
4097 assert_eq!(vars[0].name, "AZURE_OPENAI_API_KEY");
4098 assert_eq!(vars[0].label.as_deref(), Some("API Key"));
4099 assert!(vars[0].secret);
4100 assert!(!vars[0].optional);
4101 // Second var: not a secret, not optional
4102 assert_eq!(vars[1].name, "AZURE_OPENAI_ENDPOINT");
4103 assert!(!vars[1].secret);
4104 assert!(!vars[1].optional);
4105 // Third var: not a secret, optional
4106 assert_eq!(vars[2].name, "AZURE_OPENAI_API_VERSION");
4107 assert!(!vars[2].secret);
4108 assert!(vars[2].optional);
4109 }
4110 _ => panic!("Expected EnvVar variant"),
4111 }
4112 }
4113
4114 #[cfg(feature = "unstable_auth_methods")]
4115 #[test]
4116 fn test_auth_method_terminal_serialization() {
4117 let method = AuthMethod::Terminal(AuthMethodTerminal::new("tui-auth", "Terminal Auth"));
4118
4119 let json = serde_json::to_value(&method).unwrap();
4120 assert_eq!(
4121 json,
4122 json!({
4123 "id": "tui-auth",
4124 "name": "Terminal Auth",
4125 "type": "terminal"
4126 })
4127 );
4128 // args and env should be omitted when empty
4129 assert!(!json.as_object().unwrap().contains_key("args"));
4130 assert!(!json.as_object().unwrap().contains_key("env"));
4131
4132 let deserialized: AuthMethod = serde_json::from_value(json).unwrap();
4133 match deserialized {
4134 AuthMethod::Terminal(AuthMethodTerminal { args, env, .. }) => {
4135 assert!(args.is_empty());
4136 assert!(env.is_empty());
4137 }
4138 _ => panic!("Expected Terminal variant"),
4139 }
4140 }
4141
4142 #[cfg(feature = "unstable_auth_methods")]
4143 #[test]
4144 fn test_auth_method_terminal_with_args_and_env_serialization() {
4145 use std::collections::HashMap;
4146
4147 let mut env = HashMap::new();
4148 env.insert("TERM".to_string(), "xterm-256color".to_string());
4149
4150 let method = AuthMethod::Terminal(
4151 AuthMethodTerminal::new("tui-auth", "Terminal Auth")
4152 .args(vec!["--interactive".to_string(), "--color".to_string()])
4153 .env(env),
4154 );
4155
4156 let json = serde_json::to_value(&method).unwrap();
4157 assert_eq!(
4158 json,
4159 json!({
4160 "id": "tui-auth",
4161 "name": "Terminal Auth",
4162 "type": "terminal",
4163 "args": ["--interactive", "--color"],
4164 "env": {
4165 "TERM": "xterm-256color"
4166 }
4167 })
4168 );
4169
4170 let deserialized: AuthMethod = serde_json::from_value(json).unwrap();
4171 match deserialized {
4172 AuthMethod::Terminal(AuthMethodTerminal { args, env, .. }) => {
4173 assert_eq!(args, vec!["--interactive", "--color"]);
4174 assert_eq!(env.len(), 1);
4175 assert_eq!(env.get("TERM").unwrap(), "xterm-256color");
4176 }
4177 _ => panic!("Expected Terminal variant"),
4178 }
4179 }
4180}