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