agent_client_protocol_schema/
client.rs

1//! Methods and notifications the client handles/receives.
2//!
3//! This module defines the Client trait and all associated types for implementing
4//! a client that interacts with AI coding agents via the Agent Client Protocol (ACP).
5
6use std::{fmt, path::PathBuf, sync::Arc};
7
8use schemars::JsonSchema;
9use serde::{Deserialize, Serialize};
10use serde_json::value::RawValue;
11
12use crate::{
13    ContentBlock, ExtNotification, Plan, SessionId, SessionModeId, ToolCall, ToolCallUpdate,
14    ext::ExtRequest,
15};
16
17// Session updates
18
19/// Notification containing a session update from the agent.
20///
21/// Used to stream real-time progress and results during prompt processing.
22///
23/// See protocol docs: [Agent Reports Output](https://agentclientprotocol.com/protocol/prompt-turn#3-agent-reports-output)
24#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
25#[schemars(extend("x-side" = "client", "x-method" = SESSION_UPDATE_NOTIFICATION))]
26#[serde(rename_all = "camelCase")]
27pub struct SessionNotification {
28    /// The ID of the session this update pertains to.
29    pub session_id: SessionId,
30    /// The actual update content.
31    pub update: SessionUpdate,
32    /// Extension point for implementations
33    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
34    pub meta: Option<serde_json::Value>,
35}
36
37/// Different types of updates that can be sent during session processing.
38///
39/// These updates provide real-time feedback about the agent's progress.
40///
41/// See protocol docs: [Agent Reports Output](https://agentclientprotocol.com/protocol/prompt-turn#3-agent-reports-output)
42#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
43#[serde(rename_all = "snake_case", tag = "sessionUpdate")]
44pub enum SessionUpdate {
45    /// A chunk of the user's message being streamed.
46    UserMessageChunk { content: ContentBlock },
47    /// A chunk of the agent's response being streamed.
48    AgentMessageChunk { content: ContentBlock },
49    /// A chunk of the agent's internal reasoning being streamed.
50    AgentThoughtChunk { content: ContentBlock },
51    /// Notification that a new tool call has been initiated.
52    ToolCall(ToolCall),
53    /// Update on the status or results of a tool call.
54    ToolCallUpdate(ToolCallUpdate),
55    /// The agent's execution plan for complex tasks.
56    /// See protocol docs: [Agent Plan](https://agentclientprotocol.com/protocol/agent-plan)
57    Plan(Plan),
58    /// Available commands are ready or have changed
59    #[serde(rename_all = "camelCase")]
60    AvailableCommandsUpdate {
61        available_commands: Vec<AvailableCommand>,
62    },
63    /// The current mode of the session has changed
64    ///
65    /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
66    #[serde(rename_all = "camelCase")]
67    CurrentModeUpdate { current_mode_id: SessionModeId },
68}
69
70/// Information about a command.
71#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
72#[serde(rename_all = "camelCase")]
73pub struct AvailableCommand {
74    /// Command name (e.g., `create_plan`, `research_codebase`).
75    pub name: String,
76    /// Human-readable description of what the command does.
77    pub description: String,
78    /// Input for the command if required
79    pub input: Option<AvailableCommandInput>,
80    /// Extension point for implementations
81    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
82    pub meta: Option<serde_json::Value>,
83}
84
85/// The input specification for a command.
86#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
87#[serde(untagged, rename_all = "camelCase")]
88pub enum AvailableCommandInput {
89    /// All text that was typed after the command name is provided as input.
90    #[schemars(rename = "UnstructuredCommandInput")]
91    Unstructured {
92        /// A hint to display when the input hasn't been provided yet
93        hint: String,
94    },
95}
96
97// Permission
98
99/// Request for user permission to execute a tool call.
100///
101/// Sent when the agent needs authorization before performing a sensitive operation.
102///
103/// See protocol docs: [Requesting Permission](https://agentclientprotocol.com/protocol/tool-calls#requesting-permission)
104#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
105#[schemars(extend("x-side" = "client", "x-method" = SESSION_REQUEST_PERMISSION_METHOD_NAME))]
106#[serde(rename_all = "camelCase")]
107pub struct RequestPermissionRequest {
108    /// The session ID for this request.
109    pub session_id: SessionId,
110    /// Details about the tool call requiring permission.
111    pub tool_call: ToolCallUpdate,
112    /// Available permission options for the user to choose from.
113    pub options: Vec<PermissionOption>,
114    /// Extension point for implementations
115    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
116    pub meta: Option<serde_json::Value>,
117}
118
119/// An option presented to the user when requesting permission.
120#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
121pub struct PermissionOption {
122    /// Unique identifier for this permission option.
123    #[serde(rename = "optionId")]
124    pub id: PermissionOptionId,
125    /// Human-readable label to display to the user.
126    pub name: String,
127    /// Hint about the nature of this permission option.
128    pub kind: PermissionOptionKind,
129    /// Extension point for implementations
130    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
131    pub meta: Option<serde_json::Value>,
132}
133
134/// Unique identifier for a permission option.
135#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash)]
136#[serde(transparent)]
137pub struct PermissionOptionId(pub Arc<str>);
138
139impl fmt::Display for PermissionOptionId {
140    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
141        self.0.fmt(f)
142    }
143}
144
145/// The type of permission option being presented to the user.
146///
147/// Helps clients choose appropriate icons and UI treatment.
148#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
149#[serde(rename_all = "snake_case")]
150pub enum PermissionOptionKind {
151    /// Allow this operation only this time.
152    AllowOnce,
153    /// Allow this operation and remember the choice.
154    AllowAlways,
155    /// Reject this operation only this time.
156    RejectOnce,
157    /// Reject this operation and remember the choice.
158    RejectAlways,
159}
160
161/// Response to a permission request.
162#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
163#[schemars(extend("x-side" = "client", "x-method" = SESSION_REQUEST_PERMISSION_METHOD_NAME))]
164#[serde(rename_all = "camelCase")]
165pub struct RequestPermissionResponse {
166    /// The user's decision on the permission request.
167    // This extra-level is unfortunately needed because the output must be an object
168    pub outcome: RequestPermissionOutcome,
169    /// Extension point for implementations
170    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
171    pub meta: Option<serde_json::Value>,
172}
173
174/// The outcome of a permission request.
175#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
176#[serde(tag = "outcome", rename_all = "snake_case")]
177pub enum RequestPermissionOutcome {
178    /// The prompt turn was cancelled before the user responded.
179    ///
180    /// When a client sends a `session/cancel` notification to cancel an ongoing
181    /// prompt turn, it MUST respond to all pending `session/request_permission`
182    /// requests with this `Cancelled` outcome.
183    ///
184    /// See protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)
185    Cancelled,
186    /// The user selected one of the provided options.
187    #[serde(rename_all = "camelCase")]
188    Selected {
189        /// The ID of the option the user selected.
190        option_id: PermissionOptionId,
191    },
192}
193
194// Write text file
195
196/// Request to write content to a text file.
197///
198/// Only available if the client supports the `fs.writeTextFile` capability.
199#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
200#[schemars(extend("x-side" = "client", "x-method" = FS_WRITE_TEXT_FILE_METHOD_NAME))]
201#[serde(rename_all = "camelCase")]
202pub struct WriteTextFileRequest {
203    /// The session ID for this request.
204    pub session_id: SessionId,
205    /// Absolute path to the file to write.
206    pub path: PathBuf,
207    /// The text content to write to the file.
208    pub content: String,
209    /// Extension point for implementations
210    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
211    pub meta: Option<serde_json::Value>,
212}
213
214/// Response to `fs/write_text_file`
215#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema)]
216#[serde(rename_all = "camelCase")]
217#[schemars(extend("x-side" = "client", "x-method" = FS_WRITE_TEXT_FILE_METHOD_NAME))]
218#[serde(default)]
219pub struct WriteTextFileResponse {
220    /// Extension point for implementations
221    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
222    pub meta: Option<serde_json::Value>,
223}
224
225// Read text file
226
227/// Request to read content from a text file.
228///
229/// Only available if the client supports the `fs.readTextFile` capability.
230#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
231#[schemars(extend("x-side" = "client", "x-method" = FS_READ_TEXT_FILE_METHOD_NAME))]
232#[serde(rename_all = "camelCase")]
233pub struct ReadTextFileRequest {
234    /// The session ID for this request.
235    pub session_id: SessionId,
236    /// Absolute path to the file to read.
237    pub path: PathBuf,
238    /// Line number to start reading from (1-based).
239    #[serde(default, skip_serializing_if = "Option::is_none")]
240    pub line: Option<u32>,
241    /// Maximum number of lines to read.
242    #[serde(default, skip_serializing_if = "Option::is_none")]
243    pub limit: Option<u32>,
244    /// Extension point for implementations
245    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
246    pub meta: Option<serde_json::Value>,
247}
248
249/// Response containing the contents of a text file.
250#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
251#[schemars(extend("x-side" = "client", "x-method" = FS_READ_TEXT_FILE_METHOD_NAME))]
252#[serde(rename_all = "camelCase")]
253pub struct ReadTextFileResponse {
254    pub content: String,
255    /// Extension point for implementations
256    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
257    pub meta: Option<serde_json::Value>,
258}
259
260// Terminals
261
262#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash)]
263#[serde(transparent)]
264pub struct TerminalId(pub Arc<str>);
265
266impl std::fmt::Display for TerminalId {
267    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
268        write!(f, "{}", self.0)
269    }
270}
271
272/// Request to create a new terminal and execute a command.
273#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
274#[serde(rename_all = "camelCase")]
275#[schemars(extend("x-side" = "client", "x-method" = TERMINAL_CREATE_METHOD_NAME))]
276pub struct CreateTerminalRequest {
277    /// The session ID for this request.
278    pub session_id: SessionId,
279    /// The command to execute.
280    pub command: String,
281    /// Array of command arguments.
282    #[serde(default, skip_serializing_if = "Vec::is_empty")]
283    pub args: Vec<String>,
284    /// Environment variables for the command.
285    #[serde(default, skip_serializing_if = "Vec::is_empty")]
286    pub env: Vec<crate::EnvVariable>,
287    /// Working directory for the command (absolute path).
288    #[serde(default, skip_serializing_if = "Option::is_none")]
289    pub cwd: Option<PathBuf>,
290    /// Maximum number of output bytes to retain.
291    ///
292    /// When the limit is exceeded, the Client truncates from the beginning of the output
293    /// to stay within the limit.
294    ///
295    /// The Client MUST ensure truncation happens at a character boundary to maintain valid
296    /// string output, even if this means the retained output is slightly less than the
297    /// specified limit.
298    #[serde(default, skip_serializing_if = "Option::is_none")]
299    pub output_byte_limit: Option<u64>,
300    /// Extension point for implementations
301    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
302    pub meta: Option<serde_json::Value>,
303}
304
305/// Response containing the ID of the created terminal.
306#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
307#[serde(rename_all = "camelCase")]
308#[schemars(extend("x-side" = "client", "x-method" = TERMINAL_CREATE_METHOD_NAME))]
309pub struct CreateTerminalResponse {
310    /// The unique identifier for the created terminal.
311    pub terminal_id: TerminalId,
312    /// Extension point for implementations
313    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
314    pub meta: Option<serde_json::Value>,
315}
316
317/// Request to get the current output and status of a terminal.
318#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
319#[serde(rename_all = "camelCase")]
320#[schemars(extend("x-side" = "client", "x-method" = TERMINAL_OUTPUT_METHOD_NAME))]
321pub struct TerminalOutputRequest {
322    /// The session ID for this request.
323    pub session_id: SessionId,
324    /// The ID of the terminal to get output from.
325    pub terminal_id: TerminalId,
326    /// Extension point for implementations
327    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
328    pub meta: Option<serde_json::Value>,
329}
330
331/// Response containing the terminal output and exit status.
332#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
333#[serde(rename_all = "camelCase")]
334#[schemars(extend("x-side" = "client", "x-method" = TERMINAL_OUTPUT_METHOD_NAME))]
335pub struct TerminalOutputResponse {
336    /// The terminal output captured so far.
337    pub output: String,
338    /// Whether the output was truncated due to byte limits.
339    pub truncated: bool,
340    /// Exit status if the command has completed.
341    pub exit_status: Option<TerminalExitStatus>,
342    /// Extension point for implementations
343    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
344    pub meta: Option<serde_json::Value>,
345}
346
347/// Request to release a terminal and free its resources.
348#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
349#[serde(rename_all = "camelCase")]
350#[schemars(extend("x-side" = "client", "x-method" = TERMINAL_RELEASE_METHOD_NAME))]
351pub struct ReleaseTerminalRequest {
352    /// The session ID for this request.
353    pub session_id: SessionId,
354    /// The ID of the terminal to release.
355    pub terminal_id: TerminalId,
356    /// Extension point for implementations
357    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
358    pub meta: Option<serde_json::Value>,
359}
360
361/// Response to terminal/release method
362#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema)]
363#[serde(rename_all = "camelCase")]
364#[schemars(extend("x-side" = "client", "x-method" = TERMINAL_RELEASE_METHOD_NAME))]
365pub struct ReleaseTerminalResponse {
366    /// Extension point for implementations
367    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
368    pub meta: Option<serde_json::Value>,
369}
370
371/// Request to kill a terminal command without releasing the terminal.
372#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
373#[serde(rename_all = "camelCase")]
374#[schemars(extend("x-side" = "client", "x-method" = TERMINAL_KILL_METHOD_NAME))]
375pub struct KillTerminalCommandRequest {
376    /// The session ID for this request.
377    pub session_id: SessionId,
378    /// The ID of the terminal to kill.
379    pub terminal_id: TerminalId,
380    /// Extension point for implementations
381    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
382    pub meta: Option<serde_json::Value>,
383}
384
385/// Response to terminal/kill command method
386#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema)]
387#[serde(rename_all = "camelCase")]
388#[schemars(extend("x-side" = "client", "x-method" = TERMINAL_KILL_METHOD_NAME))]
389pub struct KillTerminalCommandResponse {
390    /// Extension point for implementations
391    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
392    pub meta: Option<serde_json::Value>,
393}
394
395/// Request to wait for a terminal command to exit.
396#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
397#[serde(rename_all = "camelCase")]
398#[schemars(extend("x-side" = "client", "x-method" = TERMINAL_WAIT_FOR_EXIT_METHOD_NAME))]
399pub struct WaitForTerminalExitRequest {
400    /// The session ID for this request.
401    pub session_id: SessionId,
402    /// The ID of the terminal to wait for.
403    pub terminal_id: TerminalId,
404    /// Extension point for implementations
405    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
406    pub meta: Option<serde_json::Value>,
407}
408
409/// Response containing the exit status of a terminal command.
410#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
411#[serde(rename_all = "camelCase")]
412#[schemars(extend("x-side" = "client", "x-method" = TERMINAL_WAIT_FOR_EXIT_METHOD_NAME))]
413pub struct WaitForTerminalExitResponse {
414    /// The exit status of the terminal command.
415    #[serde(flatten)]
416    pub exit_status: TerminalExitStatus,
417    /// Extension point for implementations
418    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
419    pub meta: Option<serde_json::Value>,
420}
421
422/// Exit status of a terminal command.
423#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
424#[serde(rename_all = "camelCase")]
425pub struct TerminalExitStatus {
426    /// The process exit code (may be null if terminated by signal).
427    pub exit_code: Option<u32>,
428    /// The signal that terminated the process (may be null if exited normally).
429    pub signal: Option<String>,
430    /// Extension point for implementations
431    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
432    pub meta: Option<serde_json::Value>,
433}
434
435// Capabilities
436
437/// Capabilities supported by the client.
438///
439/// Advertised during initialization to inform the agent about
440/// available features and methods.
441///
442/// See protocol docs: [Client Capabilities](https://agentclientprotocol.com/protocol/initialization#client-capabilities)
443#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema)]
444#[serde(rename_all = "camelCase")]
445pub struct ClientCapabilities {
446    /// File system capabilities supported by the client.
447    /// Determines which file operations the agent can request.
448    #[serde(default)]
449    pub fs: FileSystemCapability,
450    /// Whether the Client support all `terminal/*` methods.
451    #[serde(default)]
452    pub terminal: bool,
453    /// Extension point for implementations
454    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
455    pub meta: Option<serde_json::Value>,
456}
457
458/// File system capabilities that a client may support.
459///
460/// See protocol docs: [FileSystem](https://agentclientprotocol.com/protocol/initialization#filesystem)
461#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema)]
462#[serde(rename_all = "camelCase")]
463pub struct FileSystemCapability {
464    /// Whether the Client supports `fs/read_text_file` requests.
465    #[serde(default)]
466    pub read_text_file: bool,
467    /// Whether the Client supports `fs/write_text_file` requests.
468    #[serde(default)]
469    pub write_text_file: bool,
470    /// Extension point for implementations
471    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
472    pub meta: Option<serde_json::Value>,
473}
474
475// Method schema
476
477/// Names of all methods that clients handle.
478///
479/// Provides a centralized definition of method names used in the protocol.
480#[derive(Debug, Clone, Serialize, Deserialize)]
481pub struct ClientMethodNames {
482    /// Method for requesting permission from the user.
483    pub session_request_permission: &'static str,
484    /// Notification for session updates.
485    pub session_update: &'static str,
486    /// Method for writing text files.
487    pub fs_write_text_file: &'static str,
488    /// Method for reading text files.
489    pub fs_read_text_file: &'static str,
490    /// Method for creating new terminals.
491    pub terminal_create: &'static str,
492    /// Method for getting terminals output.
493    pub terminal_output: &'static str,
494    /// Method for releasing a terminal.
495    pub terminal_release: &'static str,
496    /// Method for waiting for a terminal to finish.
497    pub terminal_wait_for_exit: &'static str,
498    /// Method for killing a terminal.
499    pub terminal_kill: &'static str,
500}
501
502/// Constant containing all client method names.
503pub const CLIENT_METHOD_NAMES: ClientMethodNames = ClientMethodNames {
504    session_update: SESSION_UPDATE_NOTIFICATION,
505    session_request_permission: SESSION_REQUEST_PERMISSION_METHOD_NAME,
506    fs_write_text_file: FS_WRITE_TEXT_FILE_METHOD_NAME,
507    fs_read_text_file: FS_READ_TEXT_FILE_METHOD_NAME,
508    terminal_create: TERMINAL_CREATE_METHOD_NAME,
509    terminal_output: TERMINAL_OUTPUT_METHOD_NAME,
510    terminal_release: TERMINAL_RELEASE_METHOD_NAME,
511    terminal_wait_for_exit: TERMINAL_WAIT_FOR_EXIT_METHOD_NAME,
512    terminal_kill: TERMINAL_KILL_METHOD_NAME,
513};
514
515/// Notification name for session updates.
516pub(crate) const SESSION_UPDATE_NOTIFICATION: &str = "session/update";
517/// Method name for requesting user permission.
518pub(crate) const SESSION_REQUEST_PERMISSION_METHOD_NAME: &str = "session/request_permission";
519/// Method name for writing text files.
520pub(crate) const FS_WRITE_TEXT_FILE_METHOD_NAME: &str = "fs/write_text_file";
521/// Method name for reading text files.
522pub(crate) const FS_READ_TEXT_FILE_METHOD_NAME: &str = "fs/read_text_file";
523/// Method name for creating a new terminal.
524pub(crate) const TERMINAL_CREATE_METHOD_NAME: &str = "terminal/create";
525/// Method for getting terminals output.
526pub(crate) const TERMINAL_OUTPUT_METHOD_NAME: &str = "terminal/output";
527/// Method for releasing a terminal.
528pub(crate) const TERMINAL_RELEASE_METHOD_NAME: &str = "terminal/release";
529/// Method for waiting for a terminal to finish.
530pub(crate) const TERMINAL_WAIT_FOR_EXIT_METHOD_NAME: &str = "terminal/wait_for_exit";
531/// Method for killing a terminal.
532pub(crate) const TERMINAL_KILL_METHOD_NAME: &str = "terminal/kill";
533
534/// All possible requests that an agent can send to a client.
535///
536/// This enum is used internally for routing RPC requests. You typically won't need
537/// to use this directly - instead, use the methods on the [`Client`] trait.
538///
539/// This enum encompasses all method calls from agent to client.
540#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
541#[serde(untagged)]
542#[schemars(extend("x-docs-ignore" = true))]
543pub enum AgentRequest {
544    /// Writes content to a text file in the client's file system.
545    ///
546    /// Only available if the client advertises the `fs.writeTextFile` capability.
547    /// Allows the agent to create or modify files within the client's environment.
548    ///
549    /// See protocol docs: [Client](https://agentclientprotocol.com/protocol/overview#client)
550    WriteTextFileRequest(WriteTextFileRequest),
551    /// Reads content from a text file in the client's file system.
552    ///
553    /// Only available if the client advertises the `fs.readTextFile` capability.
554    /// Allows the agent to access file contents within the client's environment.
555    ///
556    /// See protocol docs: [Client](https://agentclientprotocol.com/protocol/overview#client)
557    ReadTextFileRequest(ReadTextFileRequest),
558    /// Requests permission from the user for a tool call operation.
559    ///
560    /// Called by the agent when it needs user authorization before executing
561    /// a potentially sensitive operation. The client should present the options
562    /// to the user and return their decision.
563    ///
564    /// If the client cancels the prompt turn via `session/cancel`, it MUST
565    /// respond to this request with `RequestPermissionOutcome::Cancelled`.
566    ///
567    /// See protocol docs: [Requesting Permission](https://agentclientprotocol.com/protocol/tool-calls#requesting-permission)
568    RequestPermissionRequest(RequestPermissionRequest),
569    /// Executes a command in a new terminal
570    ///
571    /// Only available if the `terminal` Client capability is set to `true`.
572    ///
573    /// Returns a `TerminalId` that can be used with other terminal methods
574    /// to get the current output, wait for exit, and kill the command.
575    ///
576    /// The `TerminalId` can also be used to embed the terminal in a tool call
577    /// by using the `ToolCallContent::Terminal` variant.
578    ///
579    /// The Agent is responsible for releasing the terminal by using the `terminal/release`
580    /// method.
581    ///
582    /// See protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)
583    CreateTerminalRequest(CreateTerminalRequest),
584    /// Gets the terminal output and exit status
585    ///
586    /// Returns the current content in the terminal without waiting for the command to exit.
587    /// If the command has already exited, the exit status is included.
588    ///
589    /// See protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)
590    TerminalOutputRequest(TerminalOutputRequest),
591    /// Releases a terminal
592    ///
593    /// The command is killed if it hasn't exited yet. Use `terminal/wait_for_exit`
594    /// to wait for the command to exit before releasing the terminal.
595    ///
596    /// After release, the `TerminalId` can no longer be used with other `terminal/*` methods,
597    /// but tool calls that already contain it, continue to display its output.
598    ///
599    /// The `terminal/kill` method can be used to terminate the command without releasing
600    /// the terminal, allowing the Agent to call `terminal/output` and other methods.
601    ///
602    /// See protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)
603    ReleaseTerminalRequest(ReleaseTerminalRequest),
604    /// Waits for the terminal command to exit and return its exit status
605    ///
606    /// See protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)
607    WaitForTerminalExitRequest(WaitForTerminalExitRequest),
608    /// Kills the terminal command without releasing the terminal
609    ///
610    /// While `terminal/release` will also kill the command, this method will keep
611    /// the `TerminalId` valid so it can be used with other methods.
612    ///
613    /// This method can be helpful when implementing command timeouts which terminate
614    /// the command as soon as elapsed, and then get the final output so it can be sent
615    /// to the model.
616    ///
617    /// Note: `terminal/release` when `TerminalId` is no longer needed.
618    ///
619    /// See protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)
620    KillTerminalCommandRequest(KillTerminalCommandRequest),
621    /// Handles extension method requests from the agent.
622    ///
623    /// Allows the Agent to send an arbitrary request that is not part of the ACP spec.
624    /// Extension methods provide a way to add custom functionality while maintaining
625    /// protocol compatibility.
626    ///
627    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
628    ExtMethodRequest(ExtRequest),
629}
630
631/// All possible responses that a client can send to an agent.
632///
633/// This enum is used internally for routing RPC responses. You typically won't need
634/// to use this directly - the responses are handled automatically by the connection.
635///
636/// These are responses to the corresponding `AgentRequest` variants.
637#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
638#[serde(untagged)]
639#[schemars(extend("x-docs-ignore" = true))]
640pub enum ClientResponse {
641    WriteTextFileResponse(#[serde(default)] WriteTextFileResponse),
642    ReadTextFileResponse(ReadTextFileResponse),
643    RequestPermissionResponse(RequestPermissionResponse),
644    CreateTerminalResponse(CreateTerminalResponse),
645    TerminalOutputResponse(TerminalOutputResponse),
646    ReleaseTerminalResponse(#[serde(default)] ReleaseTerminalResponse),
647    WaitForTerminalExitResponse(WaitForTerminalExitResponse),
648    KillTerminalResponse(#[serde(default)] KillTerminalCommandResponse),
649    ExtMethodResponse(#[schemars(with = "serde_json::Value")] Arc<RawValue>),
650}
651
652/// All possible notifications that an agent can send to a client.
653///
654/// This enum is used internally for routing RPC notifications. You typically won't need
655/// to use this directly - use the notification methods on the [`Client`] trait instead.
656///
657/// Notifications do not expect a response.
658#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
659#[serde(untagged)]
660#[allow(clippy::large_enum_variant)]
661#[schemars(extend("x-docs-ignore" = true))]
662pub enum AgentNotification {
663    /// Handles session update notifications from the agent.
664    ///
665    /// This is a notification endpoint (no response expected) that receives
666    /// real-time updates about session progress, including message chunks,
667    /// tool calls, and execution plans.
668    ///
669    /// Note: Clients SHOULD continue accepting tool call updates even after
670    /// sending a `session/cancel` notification, as the agent may send final
671    /// updates before responding with the cancelled stop reason.
672    ///
673    /// See protocol docs: [Agent Reports Output](https://agentclientprotocol.com/protocol/prompt-turn#3-agent-reports-output)
674    SessionNotification(SessionNotification),
675    /// Handles extension notifications from the agent.
676    ///
677    /// Allows the Agent to send an arbitrary notification that is not part of the ACP spec.
678    /// Extension notifications provide a way to send one-way messages for custom functionality
679    /// while maintaining protocol compatibility.
680    ///
681    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
682    ExtNotification(ExtNotification),
683}